summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-02-01 22:15:18 +0000
committerJeremy Allison <jra@samba.org>2002-02-01 22:15:18 +0000
commit8d63a817bb04da3c7cc43e342a9034f5f23c5041 (patch)
treede549371c7728978ab045eab1a658b29007cc9ad
parentf98c14e8d6d8f1def0edcd02e1dfe66bab8a2ab6 (diff)
downloadsamba-8d63a817bb04da3c7cc43e342a9034f5f23c5041.tar.gz
Move over to RELEASE branch.
Jeremy.
-rw-r--r--source/Makefile.in127
-rw-r--r--source/acconfig.h9
-rw-r--r--source/auth/pampass.c93
-rw-r--r--source/auth/pass_check.c8
-rw-r--r--source/bin/.cvsignore4
-rw-r--r--source/client/client.c329
-rw-r--r--source/client/clitar.c21
-rw-r--r--source/client/smbmount.c97
-rwxr-xr-xsource/config.guess161
-rwxr-xr-xsource/config.sub150
-rwxr-xr-xsource/configure1987
-rw-r--r--source/configure.in209
-rw-r--r--source/groupdb/aliasdb.c2
-rw-r--r--source/groupdb/aliasfile.c1
-rw-r--r--source/groupdb/groupdb.c2
-rw-r--r--source/groupdb/groupfile.c1
-rw-r--r--source/include/.cvsignore1
-rw-r--r--source/include/byteorder.h42
-rw-r--r--source/include/charset.h10
-rw-r--r--source/include/client.h11
-rw-r--r--source/include/clitar.h25
-rw-r--r--source/include/config.h.in42
-rw-r--r--source/include/doserr.h50
-rw-r--r--source/include/includes.h20
-rw-r--r--source/include/interfaces.h2
-rw-r--r--source/include/libsmbclient.h171
-rw-r--r--source/include/local.h12
-rw-r--r--source/include/messages.h4
-rw-r--r--source/include/nameserv.h1
-rw-r--r--source/include/ntdomain.h18
-rw-r--r--source/include/nterr.h1037
-rw-r--r--source/include/profile.h8
-rw-r--r--source/include/proto.h2228
-rw-r--r--source/include/rpc_brs.h2
-rw-r--r--source/include/rpc_client.h2
-rw-r--r--source/include/rpc_dce.h2
-rw-r--r--source/include/rpc_dfs.h20
-rw-r--r--source/include/rpc_lsa.h207
-rw-r--r--source/include/rpc_misc.h19
-rw-r--r--source/include/rpc_netlogon.h314
-rw-r--r--source/include/rpc_reg.h209
-rw-r--r--source/include/rpc_samr.h202
-rw-r--r--source/include/rpc_secdes.h2
-rwxr-xr-xsource/include/rpc_spoolss.h255
-rw-r--r--source/include/rpc_srvsvc.h30
-rw-r--r--source/include/rpc_wkssvc.h2
-rw-r--r--source/include/smb.h147
-rw-r--r--source/include/smb_acls.h41
-rw-r--r--source/include/smb_macros.h44
-rw-r--r--source/include/talloc.h5
-rw-r--r--source/include/trans2.h136
-rw-r--r--source/include/util_getent.h29
-rw-r--r--source/include/version.h2
-rw-r--r--source/include/vfs.h58
-rw-r--r--source/lib/access.c25
-rw-r--r--source/lib/bitmap.c10
-rw-r--r--source/lib/charcnv.c28
-rw-r--r--source/lib/charset.c8
-rw-r--r--source/lib/crc32.c1
-rw-r--r--source/lib/debug.c6
-rw-r--r--source/lib/domain_namemap.c29
-rw-r--r--source/lib/error.c56
-rw-r--r--source/lib/fault.c5
-rw-r--r--source/lib/genrand.c6
-rw-r--r--source/lib/hash.c2
-rw-r--r--source/lib/interface.c11
-rw-r--r--source/lib/messages.c71
-rw-r--r--source/lib/netatalk.c2
-rw-r--r--source/lib/pidfile.c2
-rw-r--r--source/lib/readline.c67
-rw-r--r--source/lib/replace.c4
-rw-r--r--source/lib/select.c73
-rw-r--r--source/lib/smbrun.c2
-rw-r--r--source/lib/snprintf.c32
-rw-r--r--source/lib/substitute.c81
-rw-r--r--source/lib/sysacls.c1025
-rw-r--r--source/lib/system.c462
-rw-r--r--source/lib/talloc.c17
-rw-r--r--source/lib/time.c168
-rw-r--r--source/lib/username.c570
-rw-r--r--source/lib/util.c171
-rw-r--r--source/lib/util_file.c21
-rw-r--r--source/lib/util_getent.c112
-rw-r--r--source/lib/util_seaccess.c33
-rw-r--r--source/lib/util_sec.c27
-rw-r--r--source/lib/util_sid.c18
-rw-r--r--source/lib/util_sock.c77
-rw-r--r--source/lib/util_str.c49
-rw-r--r--source/lib/util_unistr.c119
-rw-r--r--source/lib/wins_srv.c7
-rw-r--r--source/libsmb/cli_lsarpc.c548
-rw-r--r--source/libsmb/cli_netlogon.c442
-rw-r--r--source/libsmb/cli_samr.c261
-rw-r--r--source/libsmb/cli_spoolss.c297
-rw-r--r--source/libsmb/cli_srvsvc.c58
-rw-r--r--source/libsmb/cliconnect.c596
-rw-r--r--source/libsmb/clidgram.c10
-rw-r--r--source/libsmb/clientgen.c165
-rw-r--r--source/libsmb/clierror.c306
-rw-r--r--source/libsmb/clifile.c450
-rw-r--r--source/libsmb/clilist.c241
-rw-r--r--source/libsmb/climessage.c29
-rw-r--r--source/libsmb/cliprint.c8
-rw-r--r--source/libsmb/clirap.c137
-rw-r--r--source/libsmb/clireadwrite.c41
-rw-r--r--source/libsmb/clisecdesc.c25
-rw-r--r--source/libsmb/clistr.c85
-rw-r--r--source/libsmb/clitrans.c77
-rw-r--r--source/libsmb/credentials.c4
-rw-r--r--source/libsmb/libsmbclient.c2857
-rw-r--r--source/libsmb/namequery.c170
-rw-r--r--source/libsmb/nmblib.c55
-rw-r--r--source/libsmb/nterr.c70
-rw-r--r--source/libsmb/pwd_cache.c97
-rw-r--r--source/libsmb/smbdes.c35
-rw-r--r--source/libsmb/smbencrypt.c2
-rw-r--r--source/libsmb/smberr.c162
-rw-r--r--source/libsmb/unexpected.c6
-rw-r--r--source/locking/brlock.c111
-rw-r--r--source/locking/locking.c225
-rw-r--r--source/locking/posix.c39
-rw-r--r--source/msdfs/msdfs.c5
-rw-r--r--source/nmbd/asyncdns.c2
-rw-r--r--source/nmbd/nmbd.c82
-rw-r--r--source/nmbd/nmbd_become_dmb.c2
-rw-r--r--source/nmbd/nmbd_become_lmb.c1
-rw-r--r--source/nmbd/nmbd_browserdb.c4
-rw-r--r--source/nmbd/nmbd_browsesync.c3
-rw-r--r--source/nmbd/nmbd_elections.c6
-rw-r--r--source/nmbd/nmbd_incomingdgrams.c2
-rw-r--r--source/nmbd/nmbd_incomingrequests.c7
-rw-r--r--source/nmbd/nmbd_lmhosts.c2
-rw-r--r--source/nmbd/nmbd_logonnames.c2
-rw-r--r--source/nmbd/nmbd_mynames.c63
-rw-r--r--source/nmbd/nmbd_namelistdb.c18
-rw-r--r--source/nmbd/nmbd_namequery.c1
-rw-r--r--source/nmbd/nmbd_nameregister.c6
-rw-r--r--source/nmbd/nmbd_namerelease.c2
-rw-r--r--source/nmbd/nmbd_nodestatus.c2
-rw-r--r--source/nmbd/nmbd_packets.c13
-rw-r--r--source/nmbd/nmbd_processlogon.c2
-rw-r--r--source/nmbd/nmbd_responserecordsdb.c10
-rw-r--r--source/nmbd/nmbd_sendannounce.c23
-rw-r--r--source/nmbd/nmbd_serverlistdb.c63
-rw-r--r--source/nmbd/nmbd_subnetdb.c4
-rw-r--r--source/nmbd/nmbd_synclists.c4
-rw-r--r--source/nmbd/nmbd_winsproxy.c8
-rw-r--r--source/nmbd/nmbd_winsserver.c9
-rw-r--r--source/nmbd/nmbd_workgroupdb.c2
-rw-r--r--source/nsswitch/nss.h47
-rw-r--r--source/nsswitch/pam_winbind.c32
-rw-r--r--source/nsswitch/pam_winbind.h12
-rw-r--r--source/nsswitch/wb_client.c101
-rw-r--r--source/nsswitch/wb_common.c112
-rw-r--r--source/nsswitch/wbinfo.c130
-rw-r--r--source/nsswitch/winbind_nss.c532
-rw-r--r--source/nsswitch/winbind_nss_config.h4
-rw-r--r--source/nsswitch/winbind_nss_solaris.c11
-rw-r--r--source/nsswitch/winbindd.c550
-rw-r--r--source/nsswitch/winbindd.h42
-rw-r--r--source/nsswitch/winbindd_cache.c476
-rw-r--r--source/nsswitch/winbindd_group.c393
-rw-r--r--source/nsswitch/winbindd_idmap.c15
-rw-r--r--source/nsswitch/winbindd_misc.c97
-rw-r--r--source/nsswitch/winbindd_nss.h23
-rw-r--r--source/nsswitch/winbindd_pam.c142
-rw-r--r--source/nsswitch/winbindd_proto.h127
-rw-r--r--source/nsswitch/winbindd_sid.c3
-rw-r--r--source/nsswitch/winbindd_user.c350
-rw-r--r--source/nsswitch/winbindd_util.c1288
-rw-r--r--source/nsswitch/wins.c196
-rw-r--r--source/pam_smbpass/pam_smb_auth.c21
-rw-r--r--source/pam_smbpass/pam_smb_passwd.c10
-rw-r--r--source/pam_smbpass/support.c25
-rw-r--r--source/pam_smbpass/support.h2
-rw-r--r--source/param/loadparm.c166
-rw-r--r--source/param/params.c14
-rw-r--r--source/passdb/pampass.c93
-rw-r--r--source/passdb/pass_check.c6
-rw-r--r--source/passdb/passdb.c162
-rw-r--r--source/passdb/passgrp.c2
-rw-r--r--source/passdb/pdb_ldap.c422
-rw-r--r--source/passdb/pdb_nisplus.c81
-rw-r--r--source/passdb/pdb_smbpasswd.c55
-rw-r--r--source/passdb/pdb_tdb.c302
-rw-r--r--source/passdb/secrets.c15
-rw-r--r--source/passdb/smbpassfile.c1
-rw-r--r--source/printing/load.c4
-rw-r--r--source/printing/lpq_parse.c1
-rw-r--r--source/printing/nt_printing.c879
-rw-r--r--source/printing/pcap.c24
-rw-r--r--source/printing/print_cups.c7
-rw-r--r--source/printing/print_generic.c2
-rw-r--r--source/printing/print_svid.c2
-rw-r--r--source/printing/printfsp.c16
-rw-r--r--source/printing/printing.c184
-rw-r--r--source/profile/profile.c2
-rw-r--r--source/rpc_client/cli_login.c60
-rw-r--r--source/rpc_client/cli_netlogon.c69
-rw-r--r--source/rpc_client/cli_pipe.c50
-rw-r--r--source/rpc_client/cli_spoolss_notify.c11
-rw-r--r--source/rpc_client/cli_trust.c29
-rw-r--r--source/rpc_parse/.cvsignore2
-rw-r--r--source/rpc_parse/parse_dfs.c42
-rw-r--r--source/rpc_parse/parse_lsa.c550
-rw-r--r--source/rpc_parse/parse_misc.c89
-rw-r--r--source/rpc_parse/parse_net.c1092
-rw-r--r--source/rpc_parse/parse_prs.c124
-rw-r--r--source/rpc_parse/parse_reg.c258
-rw-r--r--source/rpc_parse/parse_rpc.c6
-rw-r--r--source/rpc_parse/parse_samr.c912
-rw-r--r--source/rpc_parse/parse_sec.c29
-rw-r--r--source/rpc_parse/parse_spoolss.c881
-rw-r--r--source/rpc_parse/parse_srv.c39
-rw-r--r--source/rpc_parse/parse_wks.c10
-rw-r--r--source/rpc_server/srv_dfs.c1
-rw-r--r--source/rpc_server/srv_dfs_nt.c67
-rw-r--r--source/rpc_server/srv_lsa.c200
-rw-r--r--source/rpc_server/srv_lsa_hnd.c24
-rw-r--r--source/rpc_server/srv_lsa_nt.c185
-rw-r--r--source/rpc_server/srv_netlog.c37
-rw-r--r--source/rpc_server/srv_netlog_nt.c125
-rw-r--r--source/rpc_server/srv_pipe.c39
-rw-r--r--source/rpc_server/srv_pipe_hnd.c49
-rw-r--r--source/rpc_server/srv_reg.c59
-rw-r--r--source/rpc_server/srv_reg_nt.c22
-rw-r--r--source/rpc_server/srv_samr.c4
-rw-r--r--source/rpc_server/srv_samr_nt.c1347
-rwxr-xr-xsource/rpc_server/srv_spoolss.c169
-rw-r--r--source/rpc_server/srv_spoolss_nt.c2328
-rw-r--r--source/rpc_server/srv_srvsvc.c2
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c203
-rw-r--r--source/rpc_server/srv_util.c28
-rw-r--r--source/rpc_server/srv_wkssvc.c2
-rw-r--r--source/rpc_server/srv_wkssvc_nt.c3
-rw-r--r--source/rpcclient/cmd_lsarpc.c257
-rw-r--r--source/rpcclient/cmd_netlogon.c313
-rw-r--r--source/rpcclient/cmd_samr.c847
-rw-r--r--source/rpcclient/cmd_spoolss.c691
-rw-r--r--source/rpcclient/cmd_srvsvc.c39
-rw-r--r--source/rpcclient/rpcclient.c272
-rw-r--r--source/script/mkproto.awk2
-rw-r--r--source/smbd/.cvsignore2
-rw-r--r--source/smbd/blocking.c490
-rw-r--r--source/smbd/chgpasswd.c8
-rw-r--r--source/smbd/close.c47
-rw-r--r--source/smbd/conn.c6
-rw-r--r--source/smbd/connection.c11
-rw-r--r--source/smbd/dfree.c3
-rw-r--r--source/smbd/dir.c59
-rw-r--r--source/smbd/dosmode.c2
-rw-r--r--source/smbd/error.c111
-rw-r--r--source/smbd/fileio.c161
-rw-r--r--source/smbd/filename.c28
-rw-r--r--source/smbd/files.c81
-rw-r--r--source/smbd/groupname.c17
-rw-r--r--source/smbd/ipc.c35
-rw-r--r--source/smbd/lanman.c146
-rw-r--r--source/smbd/mangle.c9
-rw-r--r--source/smbd/message.c10
-rw-r--r--source/smbd/negprot.c5
-rw-r--r--source/smbd/noquotas.c2
-rw-r--r--source/smbd/notify.c55
-rw-r--r--source/smbd/notify_hash.c78
-rw-r--r--source/smbd/notify_kernel.c3
-rw-r--r--source/smbd/nttrans.c361
-rw-r--r--source/smbd/open.c109
-rw-r--r--source/smbd/oplock.c1623
-rw-r--r--source/smbd/oplock_irix.c180
-rw-r--r--source/smbd/oplock_linux.c97
-rw-r--r--source/smbd/password.c440
-rw-r--r--source/smbd/pipes.c20
-rw-r--r--source/smbd/posix_acls.c102
-rw-r--r--source/smbd/process.c68
-rw-r--r--source/smbd/quotas.c49
-rw-r--r--source/smbd/reply.c1155
-rw-r--r--source/smbd/sec_ctx.c23
-rw-r--r--source/smbd/server.c114
-rw-r--r--source/smbd/service.c98
-rw-r--r--source/smbd/session.c9
-rw-r--r--source/smbd/trans2.c4250
-rw-r--r--source/smbd/uid.c251
-rw-r--r--source/smbd/utmp.c79
-rw-r--r--source/smbd/vfs-wrap.c123
-rw-r--r--source/smbd/vfs.c111
-rw-r--r--source/smbwrapper/shared.c2
-rw-r--r--source/smbwrapper/smbsh.c10
-rw-r--r--source/smbwrapper/smbw.c52
-rw-r--r--source/smbwrapper/smbw_dir.c9
-rw-r--r--source/smbwrapper/smbw_stat.c2
-rw-r--r--source/smbwrapper/wrapped.c7
-rw-r--r--source/tdb/.cvsignore2
-rw-r--r--source/tdb/Makefile3
-rw-r--r--source/tdb/README3
-rw-r--r--source/tdb/spinlock.c6
-rw-r--r--source/tdb/tdb.c296
-rw-r--r--source/tdb/tdb.h17
-rw-r--r--source/tdb/tdbtest.c65
-rw-r--r--source/tdb/tdbtool.c158
-rw-r--r--source/tdb/tdbtorture.c85
-rw-r--r--source/tdb/tdbutil.c244
-rw-r--r--source/utils/locktest.c2
-rw-r--r--source/utils/locktest2.c2
-rw-r--r--source/utils/make_printerdef.c2
-rw-r--r--source/utils/make_smbcodepage.c6
-rw-r--r--source/utils/make_unicodemap.c8
-rw-r--r--source/utils/masktest.c1
-rw-r--r--source/utils/nmblookup.c21
-rw-r--r--source/utils/pdbedit.c149
-rw-r--r--source/utils/rpccheck.c2
-rw-r--r--source/utils/rpctorture.c8
-rw-r--r--source/utils/smbcacls.c40
-rw-r--r--source/utils/smbcontrol.c19
-rw-r--r--source/utils/smbfilter.c6
-rw-r--r--source/utils/smbpasswd.c183
-rw-r--r--source/utils/smbw_sample.c31
-rw-r--r--source/utils/status.c5
-rw-r--r--source/utils/testparm.c4
-rw-r--r--source/utils/testprns.c1
-rw-r--r--source/utils/torture.c11
-rw-r--r--source/web/cgi.c2
-rw-r--r--source/web/diagnose.c2
-rw-r--r--source/web/statuspage.c2
-rw-r--r--source/web/swat.c1
324 files changed, 31692 insertions, 19122 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 356539493d4..067b223008f 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -1,4 +1,4 @@
-###########################################################################
+##########################################################################
# Makefile.in for Samba - rewritten for autoconf support
# Copyright Andrew Tridgell 1992-1998
###########################################################################
@@ -111,10 +111,10 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \
lib/interfaces.o lib/pidfile.o lib/replace.o \
lib/signal.o lib/system.o lib/time.o \
- lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
+ lib/ufc.o lib/genrand.o lib/username.o lib/util_getent.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \
- lib/util_array.o lib/util_str.o lib/util_sid.o \
- lib/util_unistr.o lib/util_file.o lib/sysacls.o \
+ lib/util_str.o lib/util_sid.o \
+ lib/util_unistr.o lib/util_file.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.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 \
@@ -128,17 +128,19 @@ UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
PARAM_OBJ = param/loadparm.o param/params.o
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
- libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
- libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
- libsmb/clitrans.o libsmb/clisecdesc.o \
- libsmb/namequery.o libsmb/nmblib.o libsmb/clistr.o \
- libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
- libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
- libsmb/passchange.o libsmb/unexpected.o $(RPC_PARSE_OBJ1)
+ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
+ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
+ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
+ libsmb/namequery.o libsmb/nmblib.o libsmb/clistr.o \
+ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
+ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
+ libsmb/clioplock.o libsmb/errormap.o \
+ libsmb/passchange.o libsmb/unexpected.o $(RPC_PARSE_OBJ1)
LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \
- libsmb/cli_netlogon.o libsmb/cli_srvsvc.o \
- rpc_client/cli_pipe.o nsswitch/winbindd_glue.o
+ libsmb/cli_netlogon.o libsmb/cli_srvsvc.o libsmb/cli_dfs.o \
+ libsmb/cli_reg.o \
+ rpc_client/cli_pipe.o libsmb/cli_pipe_util.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 \
@@ -146,8 +148,7 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o \
rpc_server/srv_samr.o rpc_server/srv_samr_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 \
- lib/util_getent.o
+ 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
@@ -158,14 +159,12 @@ 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_creds.o
+ rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o
RPC_CLIENT_OBJ = rpc_client/cli_netlogon.o rpc_client/cli_pipe.o \
- rpc_client/cli_lsarpc.o rpc_client/cli_connect.o \
- rpc_client/cli_use.o rpc_client/cli_login.o \
- rpc_client/cli_spoolss_notify.o rpc_client/ncacn_np_use.o \
- lib/util_list.o rpc_client/cli_trust.o
+ rpc_client/cli_login.o \
+ rpc_client/cli_spoolss_notify.o \
+ rpc_client/cli_trust.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
@@ -190,7 +189,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.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 \
+ smbd/posix_acls.o lib/sysacls.o \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o
@@ -254,23 +253,25 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ)
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(PASSDB_OBJ) \
- $(UBIQX_OBJ) $(RPC_PARSE_OBJ) $(RPC_CLIENT_OBJ) \
- libsmb/cli_lsarpc.o libsmb/cli_samr.o $(LIB_OBJ)
+ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
+ $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ) \
+ libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_pipe_util.o
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ)
-RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_spoolss.o \
- rpcclient/cmd_samr.o rpcclient/cmd_lsarpc.o \
- rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o
-
+RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
+ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
+ rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
+ rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
+ rpc_client/cli_login.o rpc_client/cli_netlogon.o
+
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
- $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
- $(READLINE_OBJ)
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+ $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
+ $(READLINE_OBJ)
-PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po
+PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
SMBW_OBJ = smbwrapper/smbw.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
@@ -312,6 +313,9 @@ MSGTEST_OBJ = utils/msgtest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
LOCKTEST_OBJ = utils/locktest.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ)
+NSSTEST_OBJ = utils/nsstest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ)
+
SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
$(LIBMSRPC_OBJ)
@@ -343,7 +347,7 @@ PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
$(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ) $(RPCCLIENT_OBJ1) \
$(RPC_CLIENT_OBJ) $(LIBMSRPC_OBJ)
-NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
+NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ)
NSS_OBJ = $(NSS_OBJ_0:.o=.po)
PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
@@ -355,9 +359,9 @@ PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
lib/wins_srv.o lib/substitute.o lib/select.o lib/util.o \
nsswitch/wb_client.o nsswitch/wb_common.o lib/system.o \
lib/charset.o lib/util_file.o lib/kanji.o lib/genrand.o \
- lib/username.o lib/charcnv.o lib/time.o lib/md4.o \
+ lib/username.o lib/util_getent.o lib/charcnv.o lib/time.o lib/md4.o \
lib/util_unistr.o lib/signal.o lib/talloc.o lib/ms_fnmatch.o \
- lib/util_sock.o lib/smbrun.o lib/util_sec.o \
+ lib/util_sock.o lib/smbrun.o lib/util_sec.o lib/snprintf.o \
ubiqx/ubi_sLinkList.o libsmb/smbencrypt.o libsmb/smbdes.o \
$(PARAM_OBJ) $(TDB_OBJ) $(PASSDB_OBJ)
@@ -373,7 +377,9 @@ WINBINDD_OBJ1 = \
nsswitch/winbindd_cache.o \
nsswitch/winbindd_pam.o \
nsswitch/winbindd_sid.o \
- nsswitch/winbindd_misc.o
+ nsswitch/winbindd_misc.o \
+ nsswitch/winbindd_wins.o \
+ nsswitch/winbindd_cm.o
NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \
smbd/password.o smbd/utmp.o smbd/session.o smbd/uid.o smbd/sec_ctx.o \
@@ -387,15 +393,13 @@ WINBINDD_OBJ = \
$(GROUPDB_OBJ) $(PROFILE_OBJ) \
$(NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ)
-WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o
+WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o \
+ passdb/secrets.o
-WINBIND_NSS_OBJ = nsswitch/winbind_nss.o nsswitch/wb_common.o
+WINBIND_NSS_OBJ = nsswitch/winbind_nss.o nsswitch/wb_common.o nsswitch/winbind_nss_solaris.o
WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po)
-NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
-NSS_OBJ = $(NSS_OBJ_0:.o=.po)
-
######################################################################
# now the rules...
######################################################################
@@ -581,6 +585,10 @@ bin/locktest2: $(LOCKTEST2_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS)
+bin/nsstest: $(NSSTEST_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS)
+
bin/rpctorture: $(RPCTORTURE_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(LIBS)
@@ -600,16 +608,17 @@ bin/smbw_sample: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
bin/smbwrapper.@SHLIBEXT@: $(PICOBJS)
@echo Linking shared library $@
- @$(LD) @LDSHFLAGS@ -o $@ $(PICOBJS) $(LIBS)
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(PICOBJS) $(LIBS)
bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32)
@echo Linking shared library $@
- @$(LD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LIBS)
+ @$(SHLD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LIBS)
libsmbclient: $(LIBSMBCLIENT_PICOBJS)
@echo Linking libsmbclient shared library bin/$@.@SHLIBEXT@
@$(SHLD) @LDSHFLAGS@ -o bin/$@.@SHLIBEXT@ \
- $(LIBSMBCLIENT_PICOBJS) $(LIBS)
+ $(LIBSMBCLIENT_PICOBJS) $(LIBS) \
+ @SONAMEFLAG@libsmbclient.so.$(LIBSMBCLIENT_MAJOR)
@echo Linking libsmbclient non-shared library bin/$@.a
@-$(AR) -rc bin/$@.a $(LIBSMBCLIENT_PICOBJS)
@@ -619,11 +628,11 @@ bin/smbsh: $(SMBSH_OBJ) bin/.dummy
bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_OBJ)
@echo Linking shared library $@
- $(LD) @LDSHFLAGS@ -symbolic -o $@ $(PAM_SMBPASS_OBJ) -lpam $(LIBS) -lc
+ $(SHLD) @LDSHFLAGS@ -symbolic -o $@ $(PAM_SMBPASS_OBJ) -lpam $(LIBS) -lc
nsswitch/libnss_wins.so: $(NSS_OBJ)
@echo "Linking $@"
- @$(LD) @LDSHFLAGS@ -o $@ $(NSS_OBJ) -lc
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(NSS_OBJ) -lc
bin/winbindd: $(WINBINDD_OBJ) bin/.dummy
@echo Linking $@
@@ -631,11 +640,11 @@ bin/winbindd: $(WINBINDD_OBJ) bin/.dummy
nsswitch/libnss_winbind.so: $(WINBIND_NSS_PICOBJS)
@echo "Linking $@"
- @$(LINK) @LDSHFLAGS@ -o $@ $(WINBIND_NSS_PICOBJS)
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(WINBIND_NSS_PICOBJS)
nsswitch/pam_winbind.so: $(PAM_WINBIND_OBJ) bin/.dummy
@echo Linking $@
- @$(LINK) @LDSHFLAGS@ -o $@ $(PAM_WINBIND_OBJ)
+ @$(SHLD) @LDSHFLAGS@ -o $@ $(PAM_WINBIND_OBJ)
bin/wbinfo: $(WBINFO_OBJ) $(PARAM_OBJ) $(LIB_OBJ) $(NOPROTO_OBJ) $(UBIQX_OBJ) bin/.dummy
@echo Linking $@
@@ -671,8 +680,8 @@ installclientlib:
# revert to the previously installed version
revert:
- @$(SHELL) $(srcdir)/script/revert.sh $(SBINDIR) $(SPROGS)
- @$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(PROGS) $(SCRIPTS)
+ @$(SHELL) $(srcdir)/script/revert.sh $(SBINDIR) $(SPROGS) ${WINBIND_SPROGS}
+ @$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(PROGS) $(SCRIPTS) ${WINBIND_PROGS}
installman:
@$(SHELL) $(srcdir)/script/installman.sh $(MANDIR) $(srcdir) "@ROFF@"
@@ -695,6 +704,11 @@ uninstallcp:
clean:
-rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@* */*.a
+winbindd_proto:
+ @cd $(srcdir) && $(SHELL) script/mkproto.sh $(AWK) \
+ -h _WINBINDD_PROTO_H_ nsswitch/winbindd_proto.h \
+ $(WINBINDD_OBJ1)
+
proto:
@echo rebuilding include/proto.h
@cd $(srcdir) && $(AWK) -f script/mkproto.awk `echo $(PROTO_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/proto.h
@@ -706,7 +720,8 @@ ctags:
ctags `find $(srcdir) -name "*.[ch]" | grep -v /CVS/`
realclean: clean
- -rm -f config.log $(PROGS) $(SPROGS) bin/.dummy
+ -rm -f config.log $(PROGS) $(SPROGS) $(WINBIND_PROGS) $(WINBIND_SPROGS) $(LPROGS) bin/.dummy
+ -rm -f bin/debug2html bin/smbfilter bin/smbtorture
-rmdir bin
distclean: realclean
@@ -714,14 +729,6 @@ distclean: realclean
-rm -f config.status config.cache so_locations
-rm -rf .deps
-#
-# This target is for documenation updators. It regenerates
-# the man pages and HTML docs from the YODL source files.
-# In order for this target to work YODL must be installed
-# and working on your system. JRA.
-yodldocs:
- @$(SHELL) $(srcdir)/script/makeyodldocs.sh $(srcdir)
-
# this target is really just for my use. It only works on a limited
# range of machines and is used to produce a list of potentially
# dead (ie. unused) functions in the code. (tridge)
diff --git a/source/acconfig.h b/source/acconfig.h
index 3bb46ad9ad2..78b652d950c 100644
--- a/source/acconfig.h
+++ b/source/acconfig.h
@@ -79,6 +79,7 @@
#undef WITH_MSDFS
#undef WITH_VFS
#undef HAVE_INO64_T
+#undef HAVE_DEV64_T
#undef HAVE_STRUCT_FLOCK64
#undef SIZEOF_INO_T
#undef SIZEOF_OFF_T
@@ -146,6 +147,7 @@
#undef HAVE_ACL_GET_PERM_NP
#undef HAVE_UNIXWARE_ACLS
#undef HAVE_SOLARIS_ACLS
+#undef HAVE_HPUX_ACLS
#undef HAVE_IRIX_ACLS
#undef HAVE_AIX_ACLS
#undef HAVE_TRU64_ACLS
@@ -164,3 +166,10 @@
#undef WITH_TDB_SAM
#undef LINUX_QUOTAS_1
#undef LINUX_QUOTAS_2
+#undef BROKEN_REDHAT_7_SYSTEM_HEADERS
+#undef HAVE_IMMEDIATE_STRUCTURES
+#undef HAVE_STAT_ST_BLOCKS
+#undef STAT_ST_BLOCKSIZE
+#undef HAVE_DEVICE_MAJOR_FN
+#undef HAVE_DEVICE_MINOR_FN
+#undef HAVE_MAKEDEV_FN
diff --git a/source/auth/pampass.c b/source/auth/pampass.c
index dd9d38f66c3..018eae3a07e 100644
--- a/source/auth/pampass.c
+++ b/source/auth/pampass.c
@@ -30,8 +30,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#ifdef WITH_PAM
/*******************************************************************
@@ -49,9 +47,9 @@ extern int DEBUGLEVEL;
*/
struct smb_pam_userdata {
- char *PAM_username;
- char *PAM_password;
- char *PAM_newpassword;
+ const char *PAM_username;
+ const char *PAM_password;
+ const char *PAM_newpassword;
};
typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr);
@@ -83,12 +81,13 @@ static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg,
*********************************************************************/
static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
- char *msg, int dbglvl, uint32 *nt_status)
+ char *msg, int dbglvl,
+ NTSTATUS *nt_status)
{
if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
return True;
- if (*nt_status == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(*nt_status)) {
/* Complain LOUDLY */
DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
@@ -158,7 +157,7 @@ static int smb_pam_conv(int num_msg,
default:
/* Must be an error of some sort... */
- free(reply);
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
}
@@ -181,7 +180,7 @@ static void special_char_sub(char *buf)
all_string_sub(buf, "\\t", "\t", 0);
}
-static void pwd_sub(char *buf, char *username, char *oldpass, char *newpass)
+static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass)
{
pstring_sub(buf, "%u", username);
all_string_sub(buf, "%o", oldpass, sizeof(fstring));
@@ -249,7 +248,7 @@ static void free_pw_chat(struct chat_struct *list)
while (list) {
struct chat_struct *old_head = list;
DLIST_REMOVE(list, list);
- free(old_head);
+ SAFE_FREE(old_head);
}
}
@@ -324,8 +323,7 @@ static int smb_pam_passchange_conv(int num_msg,
if (!found) {
DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
break;
@@ -357,8 +355,7 @@ static int smb_pam_passchange_conv(int num_msg,
if (!found) {
DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
break;
@@ -375,8 +372,7 @@ static int smb_pam_passchange_conv(int num_msg,
default:
/* Must be an error of some sort... */
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
}
@@ -394,24 +390,24 @@ static int smb_pam_passchange_conv(int num_msg,
static void smb_free_pam_conv(struct pam_conv *pconv)
{
if (pconv)
- safe_free(pconv->appdata_ptr);
+ SAFE_FREE(pconv->appdata_ptr);
- safe_free(pconv);
+ SAFE_FREE(pconv);
}
/***************************************************************************
Allocate a pam_conv struct.
****************************************************************************/
-static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, char *user,
- char *passwd, char *newpass)
+static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, const char *user,
+ const char *passwd, const char *newpass)
{
struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv));
struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata));
if (pconv == NULL || udp == NULL) {
- safe_free(pconv);
- safe_free(udp);
+ SAFE_FREE(pconv);
+ SAFE_FREE(udp);
return NULL;
}
@@ -449,9 +445,10 @@ static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr)
* Start PAM authentication for specified account
*/
-static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct pam_conv *pconv)
+static BOOL smb_pam_start(pam_handle_t **pamh, const char *user, const char *rhost, struct pam_conv *pconv)
{
int pam_error;
+ const char *our_rhost;
*pamh = (pam_handle_t *)NULL;
@@ -464,14 +461,16 @@ static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct p
}
if (rhost == NULL) {
- rhost = client_name();
+ our_rhost = client_name();
if (strequal(rhost,"UNKNOWN"))
- rhost = client_addr();
+ our_rhost = client_addr();
+ } else {
+ our_rhost = rhost;
}
#ifdef PAM_RHOST
- DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost));
- pam_error = pam_set_item(*pamh, PAM_RHOST, rhost);
+ DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", our_rhost));
+ pam_error = pam_set_item(*pamh, PAM_RHOST, our_rhost);
if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) {
smb_pam_end(*pamh, pconv);
*pamh = (pam_handle_t *)NULL;
@@ -494,10 +493,10 @@ static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct p
/*
* PAM Authentication Handler
*/
-static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
+static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
/*
* To enable debugging set in /etc/pam.d/samba:
@@ -548,10 +547,10 @@ static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
/*
* PAM Account Handler
*/
-static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
+static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user));
pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */
@@ -594,10 +593,10 @@ static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
* PAM Credential Setting
*/
-static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user)
+static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_NO_TOKEN;
+ NTSTATUS nt_status = NT_STATUS_NO_TOKEN;
/*
* This will allow samba to aquire a kerberos token. And, when
@@ -668,7 +667,7 @@ static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty,
* Internal PAM Password Changer.
*/
-static BOOL smb_pam_chauthtok(pam_handle_t *pamh, char * user)
+static BOOL smb_pam_chauthtok(pam_handle_t *pamh, const char * user)
{
int pam_error;
@@ -778,9 +777,9 @@ BOOL smb_pam_close_session(char *user, char *tty, char *rhost)
* PAM Externally accessible Account handler
*/
-uint32 smb_pam_accountcheck(char * user)
+NTSTATUS smb_pam_accountcheck(const char * user)
{
- uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
pam_handle_t *pamh = NULL;
struct pam_conv *pconv = NULL;
@@ -790,12 +789,12 @@ uint32 smb_pam_accountcheck(char * user)
return NT_STATUS_OK;
if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
- return False;
+ return NT_STATUS_NO_MEMORY;
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_ACCOUNT_DISABLED;
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK)
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user)))
DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
smb_pam_end(pamh, pconv);
@@ -806,10 +805,10 @@ uint32 smb_pam_accountcheck(char * user)
* PAM Password Validation Suite
*/
-uint32 smb_pam_passcheck(char * user, char * password)
+NTSTATUS smb_pam_passcheck(char * user, char * password)
{
pam_handle_t *pamh = NULL;
- uint32 nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
struct pam_conv *pconv = NULL;
/*
@@ -824,19 +823,19 @@ uint32 smb_pam_passcheck(char * user, char * password)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_LOGON_FAILURE;
- if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_auth(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_setcred(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
@@ -850,7 +849,7 @@ uint32 smb_pam_passcheck(char * user, char * password)
* PAM Password Change Suite
*/
-BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
+BOOL smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword)
{
/* Appropriate quantities of root should be obtained BEFORE calling this function */
struct pam_conv *pconv = NULL;
@@ -874,19 +873,19 @@ BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
#else
/* If PAM not used, no PAM restrictions on accounts. */
- uint32 smb_pam_accountcheck(char * user)
+NTSTATUS smb_pam_accountcheck(const char * user)
{
return NT_STATUS_OK;
}
/* If PAM not used, also no PAM restrictions on sessions. */
- BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
{
return True;
}
/* If PAM not used, also no PAM restrictions on sessions. */
- BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
+BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
{
return True;
}
diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c
index b3e762741fc..68f0566aee7 100644
--- a/source/auth/pass_check.c
+++ b/source/auth/pass_check.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* these are kept here to keep the string_combinations function simple */
static fstring this_user;
static fstring this_salt;
@@ -233,7 +231,7 @@ static BOOL dfs_auth(char *user, char *password)
}
/*
- * NB. I'd like to change these to call something like become_user()
+ * NB. I'd like to change these to call something like change_to_user()
* instead but currently we don't have a connection
* context to become the correct user. This is already
* fairly platform specific code however, so I think
@@ -599,7 +597,7 @@ static BOOL password_check(char *password)
{
#ifdef WITH_PAM
- return (smb_pam_passcheck(this_user, password) == NT_STATUS_OK);
+ return (NT_STATUS_IS_OK(smb_pam_passcheck(this_user, password)));
#endif /* WITH_PAM */
#ifdef WITH_AFS
@@ -832,7 +830,7 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
}
/* make a copy of it */
- StrnCpy(pass2, password, sizeof(pstring) - 1);
+ StrnCpy(pass2, password, sizeof(pass2) - 1);
/* try all lowercase if it's currently all uppercase */
if (strhasupper(password)) {
diff --git a/source/bin/.cvsignore b/source/bin/.cvsignore
index eb5b1b7dec3..17457b33b82 100644
--- a/source/bin/.cvsignore
+++ b/source/bin/.cvsignore
@@ -1,10 +1,12 @@
.dummy
.libs
+debug2html
make_printerdef
make_smbcodepage
make_unicodemap
nmbd
nmblookup
+nsstest
pdbedit
rpcclient
smbcacls
@@ -12,12 +14,14 @@ smbcacls
smbclient
smbcontrol
smbd
+smbfilter
smbmnt
smbmount
smbpasswd
smbsh
smbspool
smbstatus
+smbtorture
smbumount
swat
testparm
diff --git a/source/client/client.c b/source/client/client.c
index d839155bcfc..fe339094c8e 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -29,6 +29,7 @@
struct cli_state *cli;
extern BOOL in_client;
+extern BOOL AllowDebugChange;
static int port = SMB_PORT;
pstring cur_dir = "\\";
pstring cd_path = "";
@@ -60,9 +61,6 @@ static void cmd_help(void);
time_t newer_than = 0;
int archive_level = 0;
-extern pstring debugf;
-extern int DEBUGLEVEL;
-
BOOL translation = False;
static BOOL have_ip;
@@ -372,10 +370,7 @@ functions for do_list_queue
*/
static void reset_do_list_queue(void)
{
- if (do_list_queue)
- {
- free(do_list_queue);
- }
+ SAFE_FREE(do_list_queue);
do_list_queue = 0;
do_list_queue_size = 0;
do_list_queue_start = 0;
@@ -713,7 +708,7 @@ static void do_get(char *rname,char *lname)
rname, (long)nread));
}
- free(data);
+ SAFE_FREE(data);
if (!cli_close(cli, fnum)) {
DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
@@ -930,6 +925,21 @@ static BOOL do_mkdir(char *name)
return(True);
}
+/****************************************************************************
+ Show 8.3 name of a file.
+****************************************************************************/
+
+static BOOL do_altname(char *name)
+{
+ fstring altname;
+ if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) {
+ DEBUG(0,("%s getting alt name for %s\n", cli_errstr(cli),name));
+ return(False);
+ }
+ DEBUG(0,("%s\n", altname));
+
+ return(True);
+}
/****************************************************************************
Exit client.
@@ -980,6 +990,26 @@ static void cmd_mkdir(void)
}
}
+/****************************************************************************
+ show alt name
+ ****************************************************************************/
+
+static void cmd_altname(void)
+{
+ pstring name;
+ fstring buf;
+ char *p=buf;
+
+ pstrcpy(name,cur_dir);
+
+ if (!next_token(NULL,p,NULL,sizeof(buf))) {
+ DEBUG(0,("altname <file>\n"));
+ return;
+ }
+ pstrcat(name,p);
+
+ do_altname(name);
+}
/****************************************************************************
put a single file
@@ -1050,13 +1080,13 @@ static void do_put(char *rname,char *lname)
if (!cli_close(cli, fnum)) {
DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),rname));
fclose(f);
- if (buf) free(buf);
+ SAFE_FREE(buf);
return;
}
fclose(f);
- if (buf) free(buf);
+ SAFE_FREE(buf);
{
struct timeval tp_end;
@@ -1144,8 +1174,8 @@ static void free_file_list (struct file_list * list)
{
tmp = list;
DLIST_REMOVE(list, list);
- if (tmp->file_path) free(tmp->file_path);
- free(tmp);
+ SAFE_FREE(tmp->file_path);
+ SAFE_FREE(tmp);
}
}
@@ -1215,7 +1245,7 @@ static int file_find(struct file_list **list, const char *directory,
}
if (ret == -1) {
- free(path);
+ SAFE_FREE(path);
closedir(dir);
return -1;
}
@@ -1230,7 +1260,7 @@ static int file_find(struct file_list **list, const char *directory,
entry->isdir = isdir;
DLIST_ADD(*list, entry);
} else {
- free(path);
+ SAFE_FREE(path);
}
}
@@ -1266,7 +1296,7 @@ static void cmd_mput(void)
for (temp_list = file_list; temp_list;
temp_list = temp_list->next) {
- if (lname) free(lname);
+ SAFE_FREE(lname);
if (asprintf(&lname, "%s/", temp_list->file_path) <= 0)
continue;
trim_string(lname, "./", "/");
@@ -1275,16 +1305,16 @@ static void cmd_mput(void)
if (temp_list->isdir) {
/* if (!recurse) continue; */
- if (quest) free(quest);
- asprintf(&quest, "Put directory %s? ", lname);
+ SAFE_FREE(quest);
+ if (asprintf(&quest, "Put directory %s? ", lname) < 0) break;
if (prompt && !yesno(quest)) { /* No */
/* Skip the directory */
lname[strlen(lname)-1] = '/';
if (!seek_list(temp_list, lname))
break;
} else { /* Yes */
- if (rname) free(rname);
- asprintf(&rname, "%s%s", cur_dir, lname);
+ SAFE_FREE(rname);
+ if (asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
dos_format(rname);
if (!cli_chkpath(cli, rname) &&
!do_mkdir(rname)) {
@@ -1297,14 +1327,14 @@ static void cmd_mput(void)
}
continue;
} else {
- if (quest) free(quest);
- asprintf(&quest,"Put file %s? ", lname);
+ SAFE_FREE(quest);
+ if (asprintf(&quest,"Put file %s? ", lname) < 0) break;
if (prompt && !yesno(quest)) /* No */
continue;
/* Yes */
- if (rname) free(rname);
- asprintf(&rname, "%s%s", cur_dir, lname);
+ SAFE_FREE(rname);
+ if (asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
}
dos_format(rname);
@@ -1312,9 +1342,9 @@ static void cmd_mput(void)
do_put(rname, lname);
}
free_file_list(file_list);
- if (quest) free(quest);
- if (lname) free(lname);
- if (rname) free(rname);
+ SAFE_FREE(quest);
+ SAFE_FREE(lname);
+ SAFE_FREE(rname);
}
}
@@ -1478,6 +1508,141 @@ static void cmd_rmdir(void)
}
/****************************************************************************
+ UNIX hardlink.
+****************************************************************************/
+
+static void cmd_link(void)
+{
+ pstring src,dest;
+ fstring buf,buf2;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
+ }
+
+ pstrcpy(src,cur_dir);
+ pstrcpy(dest,cur_dir);
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("link <src> <dest>\n"));
+ return;
+ }
+
+ pstrcat(src,buf);
+ pstrcat(dest,buf2);
+
+ if (!cli_unix_hardlink(cli, src, dest)) {
+ DEBUG(0,("%s linking files (%s -> %s)\n",
+ cli_errstr(cli), src, dest));
+ return;
+ }
+}
+
+/****************************************************************************
+ UNIX symlink.
+****************************************************************************/
+
+static void cmd_symlink(void)
+{
+ pstring src,dest;
+ fstring buf,buf2;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
+ }
+
+ pstrcpy(src,cur_dir);
+ pstrcpy(dest,cur_dir);
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("symlink <src> <dest>\n"));
+ return;
+ }
+
+ pstrcat(src,buf);
+ pstrcat(dest,buf2);
+
+ if (!cli_unix_symlink(cli, src, dest)) {
+ DEBUG(0,("%s symlinking files (%s -> %s)\n",
+ cli_errstr(cli), src, dest));
+ return;
+ }
+}
+
+/****************************************************************************
+ UNIX chmod.
+****************************************************************************/
+
+static void cmd_chmod(void)
+{
+ pstring src;
+ mode_t mode;
+ fstring buf, buf2;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
+ }
+
+ pstrcpy(src,cur_dir);
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2))) {
+ DEBUG(0,("chmod mode file\n"));
+ return;
+ }
+
+ mode = (mode_t)strtol(buf, NULL, 8);
+ pstrcat(src,buf2);
+
+ if (!cli_unix_chmod(cli, src, mode)) {
+ DEBUG(0,("%s chmod file %s 0%o\n",
+ cli_errstr(cli), src, (unsigned int)mode));
+ return;
+ }
+}
+
+/****************************************************************************
+ UNIX chown.
+****************************************************************************/
+
+static void cmd_chown(void)
+{
+ pstring src;
+ uid_t uid;
+ gid_t gid;
+ fstring buf, buf2, buf3;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ DEBUG(0,("Server doesn't support UNIX CIFS calls.\n"));
+ return;
+ }
+
+ pstrcpy(src,cur_dir);
+
+ if (!next_token(NULL,buf,NULL,sizeof(buf)) ||
+ !next_token(NULL,buf2,NULL, sizeof(buf2)) ||
+ !next_token(NULL,buf3,NULL, sizeof(buf3))) {
+ DEBUG(0,("chown uid gid file\n"));
+ return;
+ }
+
+ uid = (uid_t)atoi(buf);
+ gid = (gid_t)atoi(buf2);
+ pstrcat(src,buf3);
+
+ if (!cli_unix_chown(cli, src, uid, gid)) {
+ DEBUG(0,("%s chown file %s uid=%d, gid=%d\n",
+ cli_errstr(cli), src, (int)uid, (int)gid));
+ return;
+ }
+}
+
+/****************************************************************************
rename some files
****************************************************************************/
static void cmd_rename(void)
@@ -1706,7 +1871,11 @@ static BOOL list_servers(char *wk_grp)
#define COMPL_REMOTE 1 /* Complete remote filename */
#define COMPL_LOCAL 2 /* Complete local filename */
-/* This defines the commands supported by this client */
+/* This defines the commands supported by this client.
+ * NOTE: The "!" must be the last one in the list because it's fn pointer
+ * field is NULL, and NULL in that field is used in process_tok()
+ * (below) to indicate the end of the list. crh
+ */
struct
{
char *name;
@@ -1715,47 +1884,53 @@ struct
char compl_args[2]; /* Completion argument info */
} commands[] =
{
- {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
+ {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
+ {"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}},
+ {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
+ {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
+ {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
+ {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
+ {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
{"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
- {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
- {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
- {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
+ {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
+ {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
+ {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
+ {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
+ {"link",cmd_link,"<src> <dest> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},
+ {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
+ {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
+ {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
{"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}},
- {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
- {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
- {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
{"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}},
- {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
- {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
+ {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
+ {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
{"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
- {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
- {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
- {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
- {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
- {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
- {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},
- {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},
- {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
- {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},
{"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}},
{"printmode",cmd_printmode,"<graphics or text> set the print mode",{COMPL_NONE,COMPL_NONE}},
+ {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},
+ {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
+ {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
+ {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
- {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
{"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
- {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
- {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
- {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
- {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
- {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
- {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
- {"tarmode",cmd_tarmode,
- "<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
+ {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
+ {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},
+ {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
+ {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
{"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
- {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
- {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
- {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
+ {"symlink",cmd_symlink,"<src> <dest> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
+ {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
+ {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
+
+ /* Yes, this must be here, see crh's comment above. */
{"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
{"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
@@ -1854,7 +2029,7 @@ static void process_command_string(char *cmd)
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
+static char **completion_fn(const char *text, int start, int end)
{
#define MAX_COMPLETIONS 100
char **matches;
@@ -1878,7 +2053,7 @@ static char **completion_fn(char *text, int start, int end)
}
if (count == 2) {
- free(matches[0]);
+ SAFE_FREE(matches[0]);
matches[0] = strdup(matches[1]);
}
matches[count] = NULL;
@@ -1908,7 +2083,7 @@ static void readline_callback(void)
timeout.tv_sec = 0;
timeout.tv_usec = 0;
- sys_select_intr(cli->fd+1,&fds,&timeout);
+ sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
/* We deliberately use receive_smb instead of
client_receive_smb as we want to receive
@@ -2012,7 +2187,6 @@ struct cli_state *do_connect(char *server, char *share)
DEBUG(0,("session request to %s failed (%s)\n",
called.name, cli_errstr(c)));
cli_shutdown(c);
- free(c);
if ((p=strchr(called.name, '.'))) {
*p = 0;
goto again;
@@ -2029,7 +2203,6 @@ struct cli_state *do_connect(char *server, char *share)
if (!cli_negprot(c)) {
DEBUG(0,("protocol negotiation failed\n"));
cli_shutdown(c);
- free(c);
return NULL;
}
@@ -2049,7 +2222,6 @@ struct cli_state *do_connect(char *server, char *share)
!cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
- free(c);
return NULL;
}
DEBUG(0,("Anonymous login successful\n"));
@@ -2073,7 +2245,6 @@ struct cli_state *do_connect(char *server, char *share)
password, strlen(password)+1)) {
DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
- free(c);
return NULL;
}
@@ -2285,13 +2456,13 @@ static int do_message_op(void)
extern FILE *dbf;
extern char *optarg;
extern int optind;
- int old_debug;
pstring query_host;
BOOL message = False;
extern char tar_type;
static pstring servicesf = CONFIGFILE;
pstring term_code;
pstring new_name_resolve_order;
+ pstring logfile;
char *p;
#ifdef KANJI
@@ -2306,6 +2477,7 @@ static int do_message_op(void)
*new_name_resolve_order = 0;
DEBUGLEVEL = 2;
+ AllowDebugChange = False;
setup_logging(pname,True);
@@ -2331,6 +2503,25 @@ static int do_message_op(void)
exit(1);
}
}
+ else if(strncmp(argv[opt], "-d", 2) == 0) {
+ if(argv[opt][2] != '\0') {
+ if (argv[opt][2] == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(&argv[opt][2]);
+ } else if(argv[opt+1] != NULL) {
+ /*
+ * At least one more arg left.
+ */
+ if (argv[opt+1][0] == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(argv[opt+1]);
+ } else {
+ usage(pname);
+ exit(1);
+ }
+ }
}
TimeInit();
@@ -2338,11 +2529,9 @@ static int do_message_op(void)
in_client = True; /* Make sure that we tell lp_load we are */
- old_debug = DEBUGLEVEL;
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
- DEBUGLEVEL = old_debug;
codepage_initialise(lp_client_code_page());
@@ -2462,7 +2651,8 @@ static int do_message_op(void)
port = atoi(optarg);
break;
case 'l':
- slprintf(debugf,sizeof(debugf)-1, "%s.client",optarg);
+ slprintf(logfile,sizeof(logfile)-1, "%s.client",optarg);
+ lp_set_logfile(logfile);
break;
case 'h':
usage(pname);
@@ -2540,7 +2730,8 @@ static int do_message_op(void)
}
else if (strwicmp("username", param) == 0)
pstrcpy(username, val);
-
+ else if (strwicmp("domain", param) == 0)
+ pstrcpy(workgroup,val);
memset(buf, 0, sizeof(buf));
}
fclose(auth);
diff --git a/source/client/clitar.c b/source/client/clitar.c
index 335c92eecf1..2beb669de90 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -69,7 +69,6 @@ typedef struct
stack dir_stack = {NULL, 0}; /* Want an empty stack */
#define SEPARATORS " \t\n\r"
-extern int DEBUGLEVEL;
extern struct cli_state *cli;
extern FILE *dbf;
@@ -195,7 +194,7 @@ static void writetarheader(int f, char *aname, int size, time_t mtime,
i = strlen(b)+1;
DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
- free(b);
+ SAFE_FREE(b);
}
/* use l + 1 to do the null too */
@@ -1229,7 +1228,7 @@ static void do_tarput(void)
if (longfilename != NULL) {
- free(finfo.name); /* Free the space already allocated */
+ SAFE_FREE(finfo.name); /* Free the space already allocated */
finfo.name = longfilename;
longfilename = NULL;
@@ -1455,7 +1454,7 @@ void cmd_tar(void)
process_tar();
- free(argl);
+ SAFE_FREE(argl);
}
/****************************************************************************
@@ -1472,7 +1471,7 @@ int process_tar(void)
#else
do_tarput();
#endif
- free(tarbuf);
+ SAFE_FREE(tarbuf);
close(tarhandle);
break;
case 'r':
@@ -1522,7 +1521,7 @@ int process_tar(void)
if (ntarf) dotareof(tarhandle);
close(tarhandle);
- free(tarbuf);
+ SAFE_FREE(tarbuf);
DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
@@ -1532,9 +1531,9 @@ int process_tar(void)
if (must_free_cliplist) {
int i;
for (i = 0; i < clipn; ++i) {
- free(cliplist[i]);
+ SAFE_FREE(cliplist[i]);
}
- free(cliplist);
+ SAFE_FREE(cliplist);
cliplist = NULL;
clipn = 0;
must_free_cliplist = False;
@@ -1654,16 +1653,16 @@ static int read_inclusion_file(char *filename)
}
if (inclusion_buffer) {
- free(inclusion_buffer);
+ SAFE_FREE(inclusion_buffer);
}
if (error) {
if (cliplist) {
char **pp;
/* We know cliplist is always null-terminated */
for (pp = cliplist; *pp; ++pp) {
- free(*pp);
+ SAFE_FREE(*pp);
}
- free(cliplist);
+ SAFE_FREE(cliplist);
cliplist = NULL;
must_free_cliplist = False;
}
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 273a5fa85fd..2c941836e39 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -28,7 +28,6 @@
#include <linux/smb_fs.h>
extern struct in_addr ipzero;
-extern int DEBUGLEVEL;
extern BOOL in_client;
extern pstring user_socket_options;
@@ -114,7 +113,8 @@ static void usr1_handler(int x)
/*****************************************************
return a connection to a server
*******************************************************/
-static struct cli_state *do_connection(char *service)
+
+static struct cli_state *do_connection(char *svc_name)
{
struct cli_state *c;
struct nmb_name called, calling;
@@ -124,12 +124,12 @@ static struct cli_state *do_connection(char *service)
pstring server;
char *share;
- if (service[0] != '\\' || service[1] != '\\') {
+ if (svc_name[0] != '\\' || svc_name[1] != '\\') {
usage();
exit(1);
}
- pstrcpy(server, service+2);
+ pstrcpy(server, svc_name+2);
share = strchr(server,'\\');
if (!share) {
usage();
@@ -153,7 +153,6 @@ static struct cli_state *do_connection(char *service)
DEBUG(0,("%d: Connection to %s failed\n", getpid(), server_n));
if (c) {
cli_shutdown(c);
- free(c);
}
return NULL;
}
@@ -163,7 +162,6 @@ static struct cli_state *do_connection(char *service)
DEBUG(0,("%d: session request to %s failed (%s)\n",
getpid(), called.name, cli_errstr(c)));
cli_shutdown(c);
- free(c);
if ((p=strchr(called.name, '.'))) {
*p = 0;
goto again;
@@ -180,7 +178,6 @@ static struct cli_state *do_connection(char *service)
if (!cli_negprot(c)) {
DEBUG(0,("%d: protocol negotiation failed\n", getpid()));
cli_shutdown(c);
- free(c);
return NULL;
}
@@ -191,6 +188,11 @@ static struct cli_state *do_connection(char *service)
}
}
+ /* This should be right for current smbfs. Future versions will support
+ large files as well as unicode and oplocks. */
+ c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
+ CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
+ c->force_dos_errors = True;
if (!cli_session_setup(c, username,
password, strlen(password),
password, strlen(password),
@@ -202,7 +204,6 @@ static struct cli_state *do_connection(char *service)
DEBUG(0,("%d: session setup failed: %s\n",
getpid(), cli_errstr(c)));
cli_shutdown(c);
- free(c);
return NULL;
}
DEBUG(0,("Anonymous login successful\n"));
@@ -215,7 +216,6 @@ static struct cli_state *do_connection(char *service)
DEBUG(0,("%d: tree connect failed: %s\n",
getpid(), cli_errstr(c)));
cli_shutdown(c);
- free(c);
return NULL;
}
@@ -310,7 +310,7 @@ static void smb_umount(char *mount_point)
* not exit after open_sockets() or send_login() errors,
* as the smbfs mount would then have no way to recover.
*/
-static void send_fs_socket(char *service, char *mount_point, struct cli_state *c)
+static void send_fs_socket(char *svc_name, char *mount_point, struct cli_state *c)
{
int fd, closed = 0, res = 1;
pid_t parentpid = getppid();
@@ -364,7 +364,6 @@ static void send_fs_socket(char *service, char *mount_point, struct cli_state *c
If we don't do this we will "leak" sockets and memory on
each reconnection we have to make. */
cli_shutdown(c);
- free(c);
c = NULL;
if (!closed) {
@@ -384,7 +383,7 @@ static void send_fs_socket(char *service, char *mount_point, struct cli_state *c
setup_logging("mount.smbfs", False);
append_log = True;
reopen_logs();
- DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", service, getpid()));
+ DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", svc_name, getpid()));
closed = 1;
}
@@ -395,7 +394,7 @@ static void send_fs_socket(char *service, char *mount_point, struct cli_state *c
CatchSignal(SIGUSR1, &usr1_handler);
pause();
DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", getpid()));
- c = do_connection(service);
+ c = do_connection(svc_name);
}
}
@@ -404,19 +403,6 @@ static void send_fs_socket(char *service, char *mount_point, struct cli_state *c
exit(1);
}
-/*********************************************************
-a strdup with exit
-**********************************************************/
-static char *xstrdup(char *s)
-{
- s = strdup(s);
- if (!s) {
- fprintf(stderr,"out of memory\n");
- exit(1);
- }
- return s;
-}
-
/****************************************************************************
mount smbfs
@@ -648,31 +634,31 @@ static void usage(void)
printf("Version %s\n\n",VERSION);
printf(
-"Options:
- username=<arg> SMB username
- password=<arg> SMB password
- credentials=<filename> file with username/password
- netbiosname=<arg> source NetBIOS name
- uid=<arg> mount uid or username
- gid=<arg> mount gid or groupname
- port=<arg> remote SMB port number
- fmask=<arg> file umask
- dmask=<arg> directory umask
- debug=<arg> debug level
- ip=<arg> destination host or IP address
- workgroup=<arg> workgroup on destination
- sockopt=<arg> TCP socket options
- scope=<arg> NetBIOS scope
- iocharset=<arg> Linux charset (iso8859-1, utf8)
- codepage=<arg> server codepage (cp850)
- ttl=<arg> dircache time to live
- guest don't prompt for a password
- ro mount read-only
- rw mount read-write
-
-This command is designed to be run from within /bin/mount by giving
-the option '-t smbfs'. For example:
- mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test
+"Options:\n\
+ username=<arg> SMB username\n\
+ password=<arg> SMB password\n\
+ credentials=<filename> file with username/password\n\
+ netbiosname=<arg> source NetBIOS name\n\
+ uid=<arg> mount uid or username\n\
+ gid=<arg> mount gid or groupname\n\
+ port=<arg> remote SMB port number\n\
+ fmask=<arg> file umask\n\
+ dmask=<arg> directory umask\n\
+ debug=<arg> debug level\n\
+ ip=<arg> destination host or IP address\n\
+ workgroup=<arg> workgroup on destination\n\
+ sockopt=<arg> TCP socket options\n\
+ scope=<arg> NetBIOS scope\n\
+ iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
+ codepage=<arg> server codepage (cp850)\n\
+ ttl=<arg> dircache time to live\n\
+ guest don't prompt for a password\n\
+ ro mount read-only\n\
+ rw mount read-write\n\
+\n\
+This command is designed to be run from within /bin/mount by giving\n\
+the option '-t smbfs'. For example:\n\
+ mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
");
}
@@ -824,15 +810,6 @@ static void parse_mount_smb(int argc, char **argv)
/* here we are interactive, even if run from autofs */
setup_logging("mount.smbfs",True);
- /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
- is to not announce any unicode capabilities as current smbfs does
- not support it. */
- p = getenv("CLI_FORCE_ASCII");
- if (p && !strcmp(p, "false"))
- unsetenv("CLI_FORCE_ASCII");
- else
- setenv("CLI_FORCE_ASCII", "true", 1);
-
TimeInit();
charset_initialise();
diff --git a/source/config.guess b/source/config.guess
index c339a949429..bcdc0742b73 100755
--- a/source/config.guess
+++ b/source/config.guess
@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
-timestamp='2001-06-29'
+timestamp='2001-11-26'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@ timestamp='2001-06-29'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+# Originally written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -127,7 +128,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
- # Netbsd (nbsd) targets should (where applicable) match one or
+ # NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
@@ -144,6 +145,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
macppc) machine=powerpc-apple ;;
hp3[0-9][05]) machine=m68k-hp ;;
ibmrt|romp-ibm) machine=romp-ibm ;;
+ sparc*) machine=`uname -p`-unknown ;;
*) machine=${UNAME_MACHINE}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -172,6 +174,45 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -227,6 +268,9 @@ EOF
2-307)
UNAME_MACHINE="alphaev67"
;;
+ 2-1307)
+ UNAME_MACHINE="alphaev68"
+ ;;
esac
fi
rm -f $dummy.s $dummy
@@ -244,30 +288,9 @@ EOF
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
- arc64:OpenBSD:*:*)
- echo mips64el-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hkmips:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
@@ -330,9 +353,6 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
- atari*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -359,18 +379,6 @@ EOF
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
- sun3*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
@@ -387,6 +395,7 @@ EOF
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
@@ -408,7 +417,6 @@ EOF
exit (-1);
}
EOF
- eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm -f $dummy.c $dummy && exit 0
@@ -478,6 +486,7 @@ EOF
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
@@ -489,7 +498,6 @@ EOF
exit(0);
}
EOF
- eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
@@ -540,10 +548,8 @@ EOF
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- case "${HPUX_REV}" in
- 11.[0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -552,12 +558,13 @@ EOF
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
- fi ;;
- esac
- if [ "${HP_ARCH}" = "" ]; then
- sed 's/^ //' << EOF >$dummy.c
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -590,11 +597,10 @@ EOF
exit (0);
}
EOF
- eval $set_cc_for_build
- (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
- if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
- rm -f $dummy.c $dummy
- fi ;;
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy
+ fi ;;
esac
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
@@ -603,6 +609,7 @@ EOF
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
+ eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
@@ -628,7 +635,6 @@ EOF
exit (0);
}
EOF
- eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
@@ -639,7 +645,7 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
- *9??*:MPE/iX:*:*)
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
@@ -658,9 +664,6 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
- hppa*:OpenBSD:*:*)
- echo hppa-unknown-openbsd
- exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -683,12 +686,13 @@ EOF
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE}
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
@@ -711,9 +715,6 @@ EOF
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
@@ -726,9 +727,6 @@ EOF
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
@@ -777,6 +775,9 @@ EOF
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -785,7 +786,7 @@ EOF
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
@@ -841,6 +842,7 @@ EOF
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
cat >$dummy.c <<EOF
#include <features.h>
#ifdef __cplusplus
@@ -865,7 +867,6 @@ EOF
return 0;
}
EOF
- eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
@@ -946,7 +947,7 @@ EOF
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -992,8 +993,8 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
- PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
@@ -1005,6 +1006,10 @@ EOF
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
@@ -1051,7 +1056,7 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
- NSR-[KW]:NONSTOP_KERNEL:*:*)
+ NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1097,11 +1102,18 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
@@ -1216,7 +1228,6 @@ main ()
}
EOF
-eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
diff --git a/source/config.sub b/source/config.sub
index 578b302738e..2476310dff3 100755
--- a/source/config.sub
+++ b/source/config.sub
@@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
-timestamp='2001-06-08'
+timestamp='2001-12-03'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -29,7 +29,8 @@ timestamp='2001-06-08'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Please send patches to <config-patches@gnu.org>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -223,26 +224,35 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
- tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
- | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
- | pyramid | mn10200 | mn10300 | tron | a29k \
- | 580 | i960 | h8300 \
- | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
- | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
- | hppa64 \
- | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
- | alphaev6[78] \
- | we32k | ns16k | clipper | i370 | sh | sh[34] \
- | powerpc | powerpcle \
- | 1750a | dsp16xx | pdp10 | pdp11 \
- | mips16 | mips64 | mipsel | mips64el \
- | mips64orion | mips64orionel | mipstx39 | mipstx39el \
- | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
- | mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
- | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
- | v850 | c4x \
- | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
- | pj | pjl | h8500 | z8k)
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | c4x | clipper \
+ | d10v | d30v | dsp16xx \
+ | fr30 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+ | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+ | mipsisa32 \
+ | mn10200 | mn10300 \
+ | ns16k | ns32k \
+ | openrisc \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[34] | sh[34]eb | shbe | shle \
+ | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xstormy16 | xtensa \
+ | z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -265,31 +275,44 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
- # FIXME: clean up the formatting here.
- vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
- | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
- | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
- | xmp-* | ymp-* \
- | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
- | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
- | hppa2.0n-* | hppa64-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
- | alphaev6[78]-* \
- | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
- | clipper-* | orion-* \
- | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
- | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
- | mips16-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
- | mipstx39-* | mipstx39el-* | mcore-* \
- | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
- | [cjt]90-* \
- | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
- | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
- | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alphapca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c54x-* \
+ | clipper-* | cray2-* | cydra-* \
+ | d10v-* | d30v-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | m32r-* \
+ | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
+ | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
+ | ymp-* \
+ | z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -702,7 +725,7 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
- pentium | p5 | k5 | k6 | nexgen)
+ pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
@@ -711,7 +734,7 @@ case $basic_machine in
pentiumii | pentium2)
basic_machine=i686-pc
;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
@@ -735,6 +758,16 @@ case $basic_machine in
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
ps2)
basic_machine=i386-ibm
;;
@@ -752,6 +785,12 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
sa29200)
basic_machine=a29k-amd
os=-udi
@@ -763,7 +802,7 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
- sparclite-wrs)
+ sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -946,7 +985,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4)
+ sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
sparc | sparcv9 | sparcv9b)
@@ -1035,7 +1074,8 @@ case $os in
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1087,6 +1127,9 @@ case $os in
-acis*)
os=-aos
;;
+ -atheos*)
+ os=-atheos
+ ;;
-386bsd)
os=-bsd
;;
@@ -1359,6 +1402,9 @@ case $basic_machine in
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
+ -vos*)
+ vendor=stratus
+ ;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
diff --git a/source/configure b/source/configure
index 2b147225a4e..aea495dfeb4 100755
--- a/source/configure
+++ b/source/configure
@@ -25,6 +25,8 @@ ac_help="$ac_help
ac_help="$ac_help
--with-codepagedir=DIR Where to put codepage files (\$libdir/codepages)"
ac_help="$ac_help
+ --with-logfilebase=DIR Where to put log files (\$(VARDIR))"
+ac_help="$ac_help
--enable-debug Turn on compiler debugging information (default=no)"
ac_help="$ac_help
--with-readline[=DIR] Look for readline include/libs in DIR (default=auto)"
@@ -710,6 +712,25 @@ if test "${with_codepagedir+set}" = set; then
fi
+#################################################
+# set log directory location
+# Check whether --with-logfilebase or --without-logfilebase was given.
+if test "${with_logfilebase+set}" = set; then
+ withval="$with_logfilebase"
+ case "$withval" in
+ yes|no)
+ #
+ # Just in case anybody does it
+ #
+ echo "configure: warning: --with-logfilebase called without argument - will use default" 1>&2
+ ;;
+ * )
+ logfilebase="$withval"
+ ;;
+ esac
+fi
+
+
@@ -754,7 +775,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:758: checking for $ac_word" >&5
+echo "configure:779: 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
@@ -784,7 +805,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:788: checking for $ac_word" >&5
+echo "configure:809: 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
@@ -835,7 +856,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:839: checking for $ac_word" >&5
+echo "configure:860: 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
@@ -867,7 +888,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:871: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:892: 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.
@@ -878,12 +899,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 882 "configure"
+#line 903 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:908: \"$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
@@ -909,12 +930,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:913: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:934: 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:918: checking whether we are using GNU C" >&5
+echo "configure:939: 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
@@ -923,7 +944,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:927: \"$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:948: \"$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
@@ -942,7 +963,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:946: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:967: 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
@@ -1004,7 +1025,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:1008: checking for a BSD compatible install" >&5
+echo "configure:1029: 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
@@ -1056,12 +1077,12 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
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:1065: checking for $ac_word" >&5
+echo "configure:1086: 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
@@ -1093,10 +1114,10 @@ done
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:1097: checking whether $CC and cc understand -c and -o together" >&5
+echo "configure:1118: 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:1100: checking whether cc understands -c and -o together" >&5
+echo "configure:1121: 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]/_/'`"
@@ -1108,16 +1129,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:1112: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:1113: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+if { (eval echo configure:1133: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+ test -f conftest.o && { (eval echo configure:1134: \"$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:1118: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1139: \"$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:1120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:1121: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+ if { (eval echo configure:1141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+ test -f conftest.o && { (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
then
# cc works too.
:
@@ -1151,20 +1172,20 @@ fi
echo $ac_n "checking that the C compiler understands volatile""... $ac_c" 1>&6
-echo "configure:1155: checking that the C compiler understands volatile" >&5
+echo "configure:1176: 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 <<EOF
-#line 1161 "configure"
+#line 1182 "configure"
#include "confdefs.h"
#include <sys/types.h>
int main() {
volatile int i = 0
; return 0; }
EOF
-if { (eval echo configure:1168: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1189: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_volatile=yes
else
@@ -1214,7 +1235,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:1218: checking host system type" >&5
+echo "configure:1239: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -1235,7 +1256,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:1239: checking target system type" >&5
+echo "configure:1260: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -1253,7 +1274,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:1257: checking build system type" >&5
+echo "configure:1278: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -1287,7 +1308,7 @@ esac
echo $ac_n "checking config.cache system type""... $ac_c" 1>&6
-echo "configure:1291: checking config.cache system type" >&5
+echo "configure:1312: 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" &&
@@ -1312,7 +1333,7 @@ case "$host_os" in
# Try to work out if this is the native HPUX compiler that uses the -Ae flag.
*hpux*)
echo $ac_n "checking whether ${CC-cc} accepts -Ae""... $ac_c" 1>&6
-echo "configure:1316: checking whether ${CC-cc} accepts -Ae" >&5
+echo "configure:1337: 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
@@ -1342,14 +1363,14 @@ EOF
#
case `uname -r` in
*9*|*10*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
+ CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4"
cat >> confdefs.h <<\EOF
#define USE_BOTH_CRYPT_CALLS 1
EOF
;;
*11*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
+ CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4"
cat >> confdefs.h <<\EOF
#define USE_BOTH_CRYPT_CALLS 1
EOF
@@ -1357,6 +1378,15 @@ EOF
;;
esac
;;
+
+
+#
+# CRAY Unicos has broken const handling
+ *unicos*)
+ echo "$ac_t""disabling const" 1>&6
+ CPPFLAGS="$CPPFLAGS -Dconst="
+ ;;
+
#
# AIX4.x doesn't even admit to having large
# files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
@@ -1404,14 +1434,14 @@ EOF
*sysv4*)
if test $host = mips-sni-sysv4 ; then
echo $ac_n "checking for LFS support""... $ac_c" 1>&6
-echo "configure:1408: checking for LFS support" >&5
+echo "configure:1438: 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 <<EOF
-#line 1415 "configure"
+#line 1445 "configure"
#include "confdefs.h"
#include <unistd.h>
@@ -1423,7 +1453,7 @@ exit(1);
#endif
}
EOF
-if { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1457: \"$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
@@ -1450,14 +1480,14 @@ fi
#
*linux*)
echo $ac_n "checking for LFS support""... $ac_c" 1>&6
-echo "configure:1454: checking for LFS support" >&5
+echo "configure:1484: 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 <<EOF
-#line 1461 "configure"
+#line 1491 "configure"
#include "confdefs.h"
#include <unistd.h>
@@ -1495,7 +1525,7 @@ main() {
}
EOF
-if { (eval echo configure:1499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1529: \"$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
@@ -1516,14 +1546,14 @@ fi
*hurd*)
echo $ac_n "checking for LFS support""... $ac_c" 1>&6
-echo "configure:1520: checking for LFS support" >&5
+echo "configure:1550: 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 <<EOF
-#line 1527 "configure"
+#line 1557 "configure"
#include "confdefs.h"
#include <unistd.h>
@@ -1535,7 +1565,7 @@ exit(1);
#endif
}
EOF
-if { (eval echo configure:1539: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1569: \"$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
@@ -1557,21 +1587,21 @@ fi
esac
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1561: checking for inline" >&5
+echo "configure:1591: 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 <<EOF
-#line 1568 "configure"
+#line 1598 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:1575: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1605: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -1597,7 +1627,7 @@ EOF
esac
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1601: checking how to run the C preprocessor" >&5
+echo "configure:1631: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1612,13 +1642,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1616 "configure"
+#line 1646 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1622: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1652: \"$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
:
@@ -1629,13 +1659,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1633 "configure"
+#line 1663 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1639: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1669: \"$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
:
@@ -1646,13 +1676,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1650 "configure"
+#line 1680 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1686: \"$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
:
@@ -1677,12 +1707,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1681: checking for ANSI C header files" >&5
+echo "configure:1711: 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 <<EOF
-#line 1686 "configure"
+#line 1716 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1690,7 +1720,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1694: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1724: \"$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*
@@ -1707,7 +1737,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
-#line 1711 "configure"
+#line 1741 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1725,7 +1755,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
-#line 1729 "configure"
+#line 1759 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1746,7 +1776,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1750 "configure"
+#line 1780 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1757,7 +1787,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1761: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1791: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1785,12 +1815,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:1789: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1819: 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 <<EOF
-#line 1794 "configure"
+#line 1824 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -1798,7 +1828,7 @@ int main() {
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:1802: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1832: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -1823,7 +1853,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:1827: checking for opendir in -ldir" >&5
+echo "configure:1857: 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
@@ -1831,7 +1861,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1835 "configure"
+#line 1865 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1842,7 +1872,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1846: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1876: \"$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
@@ -1864,7 +1894,7 @@ fi
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1868: checking for opendir in -lx" >&5
+echo "configure:1898: 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
@@ -1872,7 +1902,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1876 "configure"
+#line 1906 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1883,7 +1913,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1917: \"$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
@@ -1906,12 +1936,12 @@ fi
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1910: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1940: 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 <<EOF
-#line 1915 "configure"
+#line 1945 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1920,7 +1950,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1924: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1941,12 +1971,12 @@ EOF
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1945: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1975: 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 <<EOF
-#line 1950 "configure"
+#line 1980 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1962,7 +1992,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1966: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1996: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -1986,17 +2016,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:1990: checking for $ac_hdr" >&5
+echo "configure:2020: 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
-#line 1995 "configure"
+#line 2025 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2000: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2030: \"$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*
@@ -2026,17 +2056,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:2030: checking for $ac_hdr" >&5
+echo "configure:2060: 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
-#line 2035 "configure"
+#line 2065 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2040: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2070: \"$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*
@@ -2066,17 +2096,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:2070: checking for $ac_hdr" >&5
+echo "configure:2100: 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
-#line 2075 "configure"
+#line 2105 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2080: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2110: \"$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*
@@ -2106,17 +2136,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:2110: checking for $ac_hdr" >&5
+echo "configure:2140: 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
-#line 2115 "configure"
+#line 2145 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2150: \"$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*
@@ -2146,17 +2176,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:2150: checking for $ac_hdr" >&5
+echo "configure:2180: 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
-#line 2155 "configure"
+#line 2185 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2160: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2190: \"$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*
@@ -2186,17 +2216,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:2190: checking for $ac_hdr" >&5
+echo "configure:2220: 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
-#line 2195 "configure"
+#line 2225 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2230: \"$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*
@@ -2226,17 +2256,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:2230: checking for $ac_hdr" >&5
+echo "configure:2260: 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
-#line 2235 "configure"
+#line 2265 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2270: \"$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*
@@ -2262,21 +2292,21 @@ else
fi
done
-for ac_hdr in security/pam_modules.h security/_pam_macros.h
+for ac_hdr in security/pam_modules.h security/_pam_macros.h synch.h pthread.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2270: checking for $ac_hdr" >&5
+echo "configure:2300: 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
-#line 2275 "configure"
+#line 2305 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2280: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2310: \"$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*
@@ -2310,14 +2340,14 @@ done
case "$host_os" in
*hpux*)
cat > conftest.$ac_ext <<EOF
-#line 2314 "configure"
+#line 2344 "configure"
#include "confdefs.h"
#include <shadow.h>
int main() {
struct spwd testme
; return 0; }
EOF
-if { (eval echo configure:2321: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2351: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_shadow_h=yes
else
@@ -2339,17 +2369,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:2343: checking for $ac_hdr" >&5
+echo "configure:2373: 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
-#line 2348 "configure"
+#line 2378 "configure"
#include "confdefs.h"
#include <$ac_hdr>
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:2383: \"$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*
@@ -2375,21 +2405,21 @@ else
fi
done
-for ac_hdr in nss.h nss_common.h sys/security.h security/pam_appl.h security/pam_modules.h
+for ac_hdr in nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h
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:2413: 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
-#line 2388 "configure"
+#line 2418 "configure"
#include "confdefs.h"
#include <$ac_hdr>
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:2423: \"$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 +2449,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:2423: checking for $ac_hdr" >&5
+echo "configure:2453: 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
-#line 2428 "configure"
+#line 2458 "configure"
#include "confdefs.h"
#include <$ac_hdr>
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:2463: \"$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 +2489,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:2463: checking for $ac_hdr" >&5
+echo "configure:2493: 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
-#line 2468 "configure"
+#line 2498 "configure"
#include "confdefs.h"
#include <$ac_hdr>
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:2503: \"$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*
@@ -2499,17 +2529,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:2503: checking for $ac_hdr" >&5
+echo "configure:2533: 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
-#line 2508 "configure"
+#line 2538 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2513: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2543: \"$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*
@@ -2541,17 +2571,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:2545: checking for $ac_hdr" >&5
+echo "configure:2575: 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
-#line 2550 "configure"
+#line 2580 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2555: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2585: \"$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*
@@ -2583,17 +2613,59 @@ 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:2587: checking for $ac_hdr" >&5
+echo "configure:2617: 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
+#line 2622 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2627: \"$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 <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# For quotas on Linux XFS filesystems
+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:2659: 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
-#line 2592 "configure"
+#line 2664 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2597: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2669: \"$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*
@@ -2621,7 +2693,7 @@ done
echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:2625: checking size of int" >&5
+echo "configure:2697: 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
@@ -2629,18 +2701,18 @@ else
ac_cv_sizeof_int=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2633 "configure"
+#line 2705 "configure"
#include "confdefs.h"
#include <stdio.h>
-main()
+int main()
{
FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
+ if (!f) return(1);
fprintf(f, "%d\n", sizeof(int));
- exit(0);
+ return(0);
}
EOF
-if { (eval echo configure:2644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2716: \"$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
@@ -2660,7 +2732,7 @@ EOF
echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:2664: checking size of long" >&5
+echo "configure:2736: 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
@@ -2668,18 +2740,18 @@ else
ac_cv_sizeof_long=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2672 "configure"
+#line 2744 "configure"
#include "confdefs.h"
#include <stdio.h>
-main()
+int main()
{
FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
+ if (!f) return(1);
fprintf(f, "%d\n", sizeof(long));
- exit(0);
+ return(0);
}
EOF
-if { (eval echo configure:2683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2755: \"$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
@@ -2699,7 +2771,7 @@ EOF
echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:2703: checking size of short" >&5
+echo "configure:2775: 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
@@ -2707,18 +2779,18 @@ else
ac_cv_sizeof_short=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2711 "configure"
+#line 2783 "configure"
#include "confdefs.h"
#include <stdio.h>
-main()
+int main()
{
FILE *f=fopen("conftestval", "w");
- if (!f) exit(1);
+ if (!f) return(1);
fprintf(f, "%d\n", sizeof(short));
- exit(0);
+ return(0);
}
EOF
-if { (eval echo configure:2722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2794: \"$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
@@ -2739,12 +2811,12 @@ EOF
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2743: checking for working const" >&5
+echo "configure:2815: 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 <<EOF
-#line 2748 "configure"
+#line 2820 "configure"
#include "confdefs.h"
int main() {
@@ -2793,7 +2865,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:2797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2869: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -2814,21 +2886,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:2818: checking for inline" >&5
+echo "configure:2890: 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 <<EOF
-#line 2825 "configure"
+#line 2897 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:2832: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2904: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -2854,14 +2926,14 @@ EOF
esac
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:2858: checking whether byte ordering is bigendian" >&5
+echo "configure:2930: 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 <<EOF
-#line 2865 "configure"
+#line 2937 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -2872,11 +2944,11 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:2876: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2948: \"$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 <<EOF
-#line 2880 "configure"
+#line 2952 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -2887,7 +2959,7 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:2891: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
@@ -2907,7 +2979,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 <<EOF
-#line 2911 "configure"
+#line 2983 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
@@ -2920,7 +2992,7 @@ main () {
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-if { (eval echo configure:2924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2996: \"$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
@@ -2944,14 +3016,14 @@ EOF
fi
echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-echo "configure:2948: checking whether char is unsigned" >&5
+echo "configure:3020: 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 <<EOF
-#line 2955 "configure"
+#line 3027 "configure"
#include "confdefs.h"
#ifdef __CHAR_UNSIGNED__
yes
@@ -2973,7 +3045,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 <<EOF
-#line 2977 "configure"
+#line 3049 "configure"
#include "confdefs.h"
/* volatile prevents gcc2 from optimizing the test away on sparcs. */
#if !defined(__STDC__) || __STDC__ != 1
@@ -2983,7 +3055,7 @@ main() {
volatile char c = 255; exit(c < 0);
}
EOF
-if { (eval echo configure:2987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3059: \"$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
@@ -3008,12 +3080,12 @@ fi
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:3012: checking return type of signal handlers" >&5
+echo "configure:3084: 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 <<EOF
-#line 3017 "configure"
+#line 3089 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -3030,7 +3102,7 @@ int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:3034: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
@@ -3049,12 +3121,12 @@ EOF
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:3053: checking for uid_t in sys/types.h" >&5
+echo "configure:3125: 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
-#line 3058 "configure"
+#line 3130 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -3083,12 +3155,12 @@ EOF
fi
echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:3087: checking for mode_t" >&5
+echo "configure:3159: 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 <<EOF
-#line 3092 "configure"
+#line 3164 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3116,12 +3188,12 @@ EOF
fi
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:3120: checking for off_t" >&5
+echo "configure:3192: 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 <<EOF
-#line 3125 "configure"
+#line 3197 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3149,12 +3221,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:3153: checking for size_t" >&5
+echo "configure:3225: 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 <<EOF
-#line 3158 "configure"
+#line 3230 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3182,12 +3254,12 @@ EOF
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:3186: checking for pid_t" >&5
+echo "configure:3258: 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 <<EOF
-#line 3191 "configure"
+#line 3263 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3215,12 +3287,12 @@ EOF
fi
echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:3219: checking for st_rdev in struct stat" >&5
+echo "configure:3291: 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 <<EOF
-#line 3224 "configure"
+#line 3296 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -3228,7 +3300,7 @@ int main() {
struct stat s; s.st_rdev;
; return 0; }
EOF
-if { (eval echo configure:3232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_rdev=yes
else
@@ -3249,12 +3321,12 @@ EOF
fi
echo $ac_n "checking for d_off in dirent""... $ac_c" 1>&6
-echo "configure:3253: checking for d_off in dirent" >&5
+echo "configure:3325: 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 <<EOF
-#line 3258 "configure"
+#line 3330 "configure"
#include "confdefs.h"
#include <unistd.h>
@@ -3264,7 +3336,7 @@ int main() {
struct dirent d; d.d_off;
; return 0; }
EOF
-if { (eval echo configure:3268: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_dirent_d_off=yes
else
@@ -3285,12 +3357,12 @@ EOF
fi
echo $ac_n "checking for ino_t""... $ac_c" 1>&6
-echo "configure:3289: checking for ino_t" >&5
+echo "configure:3361: 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 <<EOF
-#line 3294 "configure"
+#line 3366 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3318,12 +3390,12 @@ EOF
fi
echo $ac_n "checking for loff_t""... $ac_c" 1>&6
-echo "configure:3322: checking for loff_t" >&5
+echo "configure:3394: 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 <<EOF
-#line 3327 "configure"
+#line 3399 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3351,12 +3423,12 @@ EOF
fi
echo $ac_n "checking for offset_t""... $ac_c" 1>&6
-echo "configure:3355: checking for offset_t" >&5
+echo "configure:3427: 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 <<EOF
-#line 3360 "configure"
+#line 3432 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3384,12 +3456,12 @@ EOF
fi
echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:3388: checking for ssize_t" >&5
+echo "configure:3460: 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 <<EOF
-#line 3393 "configure"
+#line 3465 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3417,12 +3489,12 @@ EOF
fi
echo $ac_n "checking for wchar_t""... $ac_c" 1>&6
-echo "configure:3421: checking for wchar_t" >&5
+echo "configure:3493: 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 <<EOF
-#line 3426 "configure"
+#line 3498 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3454,7 +3526,7 @@ fi
# for cups support we need libcups, and a handful of header files
echo $ac_n "checking for httpConnect in -lcups""... $ac_c" 1>&6
-echo "configure:3458: checking for httpConnect in -lcups" >&5
+echo "configure:3530: checking for httpConnect in -lcups" >&5
ac_lib_var=`echo cups'_'httpConnect | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3462,7 +3534,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcups $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3466 "configure"
+#line 3538 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3473,7 +3545,7 @@ int main() {
httpConnect()
; return 0; }
EOF
-if { (eval echo configure:3477: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3549: \"$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
@@ -3508,17 +3580,17 @@ if test x"$ac_cv_lib_cups_httpConnect" = x"yes"; then
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3512: checking for $ac_hdr" >&5
+echo "configure:3584: 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
-#line 3517 "configure"
+#line 3589 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3594: \"$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*
@@ -3557,7 +3629,7 @@ fi
############################################
# we need libdl for PAM and the new VFS code
echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:3561: checking for dlopen in -ldl" >&5
+echo "configure:3633: 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
@@ -3565,7 +3637,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3569 "configure"
+#line 3641 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3576,7 +3648,7 @@ int main() {
dlopen()
; return 0; }
EOF
-if { (eval echo configure:3580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3652: \"$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
@@ -3602,15 +3674,56 @@ fi
############################################
+# check if the compiler can do immediate structures
+echo $ac_n "checking for immediate structures""... $ac_c" 1>&6
+echo "configure:3680: 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 <<EOF
+#line 3686 "configure"
+#include "confdefs.h"
+
+#include <stdio.h>
+int main() {
+
+ #define X_FOOBAR(x) ((FOOBAR) { x })
+ typedef struct {unsigned x;} FOOBAR;
+ FOOBAR f = X_FOOBAR(1);
+
+; return 0; }
+EOF
+if { (eval echo configure:3698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ samba_cv_immediate_structures=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_immediate_structures=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_immediate_structures" 1>&6
+if test x"$samba_cv_immediate_structures" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_IMMEDIATE_STRUCTURES 1
+EOF
+
+fi
+
+############################################
# check for unix domain sockets
echo $ac_n "checking for unix domain sockets""... $ac_c" 1>&6
-echo "configure:3608: checking for unix domain sockets" >&5
+echo "configure:3721: 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 <<EOF
-#line 3614 "configure"
+#line 3727 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -3625,7 +3738,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:3629: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3742: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_unixsocket=yes
else
@@ -3646,13 +3759,13 @@ EOF
fi
echo $ac_n "checking for socklen_t type""... $ac_c" 1>&6
-echo "configure:3650: checking for socklen_t type" >&5
+echo "configure:3763: 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 <<EOF
-#line 3656 "configure"
+#line 3769 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -3665,7 +3778,7 @@ int main() {
socklen_t i = 0
; return 0; }
EOF
-if { (eval echo configure:3669: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_socklen_t=yes
else
@@ -3686,13 +3799,13 @@ EOF
fi
echo $ac_n "checking for sig_atomic_t type""... $ac_c" 1>&6
-echo "configure:3690: checking for sig_atomic_t type" >&5
+echo "configure:3803: 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 <<EOF
-#line 3696 "configure"
+#line 3809 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -3705,7 +3818,7 @@ int main() {
sig_atomic_t i = 0
; return 0; }
EOF
-if { (eval echo configure:3709: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_sig_atomic_t=yes
else
@@ -3728,20 +3841,20 @@ fi
# stupid headers have the functions but no declaration. grrrr.
echo $ac_n "checking for errno declaration""... $ac_c" 1>&6
-echo "configure:3732: checking for errno declaration" >&5
+echo "configure:3845: 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 <<EOF
-#line 3738 "configure"
+#line 3851 "configure"
#include "confdefs.h"
#include <errno.h>
int main() {
int i = (int)errno
; return 0; }
EOF
-if { (eval echo configure:3745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3858: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_errno_decl=yes
else
@@ -3763,20 +3876,20 @@ EOF
echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6
-echo "configure:3767: checking for setresuid declaration" >&5
+echo "configure:3880: 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 <<EOF
-#line 3773 "configure"
+#line 3886 "configure"
#include "confdefs.h"
#include <unistd.h>
int main() {
int i = (int)setresuid
; return 0; }
EOF
-if { (eval echo configure:3780: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_setresuid_decl=yes
else
@@ -3798,20 +3911,20 @@ EOF
echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6
-echo "configure:3802: checking for setresgid declaration" >&5
+echo "configure:3915: 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 <<EOF
-#line 3808 "configure"
+#line 3921 "configure"
#include "confdefs.h"
#include <unistd.h>
int main() {
int i = (int)setresgid
; return 0; }
EOF
-if { (eval echo configure:3815: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_setresgid_decl=yes
else
@@ -3833,20 +3946,20 @@ EOF
echo $ac_n "checking for asprintf declaration""... $ac_c" 1>&6
-echo "configure:3837: checking for asprintf declaration" >&5
+echo "configure:3950: 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 <<EOF
-#line 3843 "configure"
+#line 3956 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
int i = (int)asprintf
; return 0; }
EOF
-if { (eval echo configure:3850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_asprintf_decl=yes
else
@@ -3868,20 +3981,20 @@ EOF
echo $ac_n "checking for vasprintf declaration""... $ac_c" 1>&6
-echo "configure:3872: checking for vasprintf declaration" >&5
+echo "configure:3985: 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 <<EOF
-#line 3878 "configure"
+#line 3991 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
int i = (int)vasprintf
; return 0; }
EOF
-if { (eval echo configure:3885: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3998: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_vasprintf_decl=yes
else
@@ -3903,20 +4016,20 @@ EOF
echo $ac_n "checking for vsnprintf declaration""... $ac_c" 1>&6
-echo "configure:3907: checking for vsnprintf declaration" >&5
+echo "configure:4020: 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 <<EOF
-#line 3913 "configure"
+#line 4026 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
int i = (int)vsnprintf
; return 0; }
EOF
-if { (eval echo configure:3920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4033: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_vsnprintf_decl=yes
else
@@ -3938,20 +4051,20 @@ EOF
echo $ac_n "checking for snprintf declaration""... $ac_c" 1>&6
-echo "configure:3942: checking for snprintf declaration" >&5
+echo "configure:4055: 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 <<EOF
-#line 3948 "configure"
+#line 4061 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
int i = (int)snprintf
; return 0; }
EOF
-if { (eval echo configure:3955: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4068: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_have_snprintf_decl=yes
else
@@ -3975,7 +4088,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:3979: checking for real setresuid" >&5
+echo "configure:4092: 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
@@ -3984,12 +4097,12 @@ else
samba_cv_have_setresuid=cross
else
cat > conftest.$ac_ext <<EOF
-#line 3988 "configure"
+#line 4101 "configure"
#include "confdefs.h"
#include <errno.h>
main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);}
EOF
-if { (eval echo configure:3993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4106: \"$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
@@ -4014,7 +4127,7 @@ fi
# Do the same check for setresguid...
#
echo $ac_n "checking for real setresgid""... $ac_c" 1>&6
-echo "configure:4018: checking for real setresgid" >&5
+echo "configure:4131: 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
@@ -4023,13 +4136,13 @@ else
samba_cv_have_setresgid=cross
else
cat > conftest.$ac_ext <<EOF
-#line 4027 "configure"
+#line 4140 "configure"
#include "confdefs.h"
#include <unistd.h>
#include <errno.h>
main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}
EOF
-if { (eval echo configure:4033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4146: \"$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
@@ -4052,7 +4165,7 @@ EOF
fi
echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:4056: checking for 8-bit clean memcmp" >&5
+echo "configure:4169: 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
@@ -4060,7 +4173,7 @@ else
ac_cv_func_memcmp_clean=no
else
cat > conftest.$ac_ext <<EOF
-#line 4064 "configure"
+#line 4177 "configure"
#include "confdefs.h"
main()
@@ -4070,7 +4183,7 @@ main()
}
EOF
-if { (eval echo configure:4074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4187: \"$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
@@ -4094,7 +4207,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:4098: checking whether to use readline" >&5
+echo "configure:4211: 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"
@@ -4106,17 +4219,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:4110: checking for $ac_hdr" >&5
+echo "configure:4223: 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
-#line 4115 "configure"
+#line 4228 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4233: \"$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*
@@ -4146,17 +4259,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4150: checking for $ac_hdr" >&5
+echo "configure:4263: 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
-#line 4155 "configure"
+#line 4268 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4160: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4273: \"$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*
@@ -4187,17 +4300,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4191: checking for $ac_hdr" >&5
+echo "configure:4304: 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
-#line 4196 "configure"
+#line 4309 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4201: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4314: \"$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*
@@ -4220,7 +4333,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:4224: checking for tgetent in -l${termlib}" >&5
+echo "configure:4337: 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
@@ -4228,7 +4341,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-l${termlib} $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4232 "configure"
+#line 4345 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4239,7 +4352,7 @@ int main() {
tgetent()
; return 0; }
EOF
-if { (eval echo configure:4243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4356: \"$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
@@ -4261,7 +4374,7 @@ fi
done
echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6
-echo "configure:4265: checking for rl_callback_handler_install in -lreadline" >&5
+echo "configure:4378: 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
@@ -4269,7 +4382,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lreadline $TERMLIBS $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4273 "configure"
+#line 4386 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4280,7 +4393,7 @@ int main() {
rl_callback_handler_install()
; return 0; }
EOF
-if { (eval echo configure:4284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4397: \"$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
@@ -4331,17 +4444,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4335: checking for $ac_hdr" >&5
+echo "configure:4448: 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
-#line 4340 "configure"
+#line 4453 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4458: \"$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*
@@ -4371,17 +4484,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4375: checking for $ac_hdr" >&5
+echo "configure:4488: 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
-#line 4380 "configure"
+#line 4493 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4498: \"$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*
@@ -4412,17 +4525,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4416: checking for $ac_hdr" >&5
+echo "configure:4529: 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
-#line 4421 "configure"
+#line 4534 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4426: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4539: \"$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*
@@ -4445,7 +4558,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:4449: checking for tgetent in -l${termlib}" >&5
+echo "configure:4562: 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
@@ -4453,7 +4566,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-l${termlib} $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4457 "configure"
+#line 4570 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4464,7 +4577,7 @@ int main() {
tgetent()
; return 0; }
EOF
-if { (eval echo configure:4468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4581: \"$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
@@ -4486,7 +4599,7 @@ fi
done
echo $ac_n "checking for rl_callback_handler_install in -lreadline""... $ac_c" 1>&6
-echo "configure:4490: checking for rl_callback_handler_install in -lreadline" >&5
+echo "configure:4603: 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
@@ -4494,7 +4607,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lreadline $TERMLIBS $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4498 "configure"
+#line 4611 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4505,7 +4618,7 @@ int main() {
rl_callback_handler_install()
; return 0; }
EOF
-if { (eval echo configure:4509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4622: \"$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
@@ -4560,12 +4673,12 @@ fi
for ac_func in connect
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4564: checking for $ac_func" >&5
+echo "configure:4677: 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 <<EOF
-#line 4569 "configure"
+#line 4682 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4588,7 +4701,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4705: \"$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
@@ -4616,7 +4729,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:4620: checking for printf in -lnsl_s" >&5
+echo "configure:4733: 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
@@ -4624,7 +4737,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl_s $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4628 "configure"
+#line 4741 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4635,7 +4748,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:4639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4752: \"$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
@@ -4666,7 +4779,7 @@ fi
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6
-echo "configure:4670: checking for printf in -lnsl" >&5
+echo "configure:4783: 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
@@ -4674,7 +4787,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4678 "configure"
+#line 4791 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4685,7 +4798,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:4689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4802: \"$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
@@ -4716,7 +4829,7 @@ fi
case "$LIBS" in
*-lsocket*) ;;
*) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:4720: checking for connect in -lsocket" >&5
+echo "configure:4833: 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
@@ -4724,7 +4837,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4728 "configure"
+#line 4841 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4735,7 +4848,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:4739: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4852: \"$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
@@ -4766,7 +4879,7 @@ fi
case "$LIBS" in
*-linet*) ;;
*) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6
-echo "configure:4770: checking for connect in -linet" >&5
+echo "configure:4883: 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
@@ -4774,7 +4887,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4778 "configure"
+#line 4891 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4785,7 +4898,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:4789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4902: \"$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
@@ -4829,12 +4942,12 @@ fi
for ac_func in yp_get_default_domain
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4833: checking for $ac_func" >&5
+echo "configure:4946: 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 <<EOF
-#line 4838 "configure"
+#line 4951 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4857,7 +4970,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4974: \"$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
@@ -4883,7 +4996,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:4887: checking for yp_get_default_domain in -lnsl" >&5
+echo "configure:5000: 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
@@ -4891,7 +5004,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4895 "configure"
+#line 5008 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4902,7 +5015,7 @@ int main() {
yp_get_default_domain()
; return 0; }
EOF
-if { (eval echo configure:4906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5019: \"$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
@@ -4932,12 +5045,12 @@ fi
for ac_func in execl
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4936: checking for $ac_func" >&5
+echo "configure:5049: 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 <<EOF
-#line 4941 "configure"
+#line 5054 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4960,7 +5073,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5077: \"$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
@@ -4990,15 +5103,15 @@ else
RUNPROG=""
fi
-for ac_func in waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot
+for ac_func in waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot link
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4997: checking for $ac_func" >&5
+echo "configure:5110: 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 <<EOF
-#line 5002 "configure"
+#line 5115 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5021,7 +5134,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5138: \"$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
@@ -5045,15 +5158,15 @@ else
fi
done
-for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset
+for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset setpgid mknod mknod64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5052: checking for $ac_func" >&5
+echo "configure:5165: 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 <<EOF
-#line 5057 "configure"
+#line 5170 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5076,7 +5189,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5193: \"$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
@@ -5103,12 +5216,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:5107: checking for $ac_func" >&5
+echo "configure:5220: 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 <<EOF
-#line 5112 "configure"
+#line 5225 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5131,7 +5244,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5248: \"$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
@@ -5158,12 +5271,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:5162: checking for $ac_func" >&5
+echo "configure:5275: 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 <<EOF
-#line 5167 "configure"
+#line 5280 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5186,7 +5299,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5303: \"$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
@@ -5210,15 +5323,15 @@ else
fi
done
-for ac_func in initgroups select poll rdchk getgrnam getgrent pathconf
+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:5217: checking for $ac_func" >&5
+echo "configure:5330: 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 <<EOF
-#line 5222 "configure"
+#line 5335 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5241,7 +5354,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5358: \"$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
@@ -5268,12 +5381,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:5272: checking for $ac_func" >&5
+echo "configure:5385: 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 <<EOF
-#line 5277 "configure"
+#line 5390 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5296,7 +5409,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5413: \"$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
@@ -5323,12 +5436,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:5327: checking for $ac_func" >&5
+echo "configure:5440: 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 <<EOF
-#line 5332 "configure"
+#line 5445 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5351,7 +5464,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5468: \"$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
@@ -5378,12 +5491,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:5382: 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 <<EOF
-#line 5387 "configure"
+#line 5500 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5406,7 +5519,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5410: \"$ac_link\") 1>&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
@@ -5433,12 +5546,67 @@ 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:5437: 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 <<EOF
+#line 5555 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+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
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in syslog vsyslog
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+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 <<EOF
-#line 5442 "configure"
+#line 5610 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5461,7 +5629,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5465: \"$ac_link\") 1>&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
@@ -5490,12 +5658,12 @@ done
for ac_func in syscall
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5494: checking for $ac_func" >&5
+echo "configure:5662: 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 <<EOF
-#line 5499 "configure"
+#line 5667 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5518,7 +5686,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5522: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5690: \"$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
@@ -5546,12 +5714,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:5550: checking for $ac_func" >&5
+echo "configure:5718: 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 <<EOF
-#line 5555 "configure"
+#line 5723 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5574,7 +5742,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5746: \"$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
@@ -5601,12 +5769,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:5605: checking for $ac_func" >&5
+echo "configure:5773: 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 <<EOF
-#line 5610 "configure"
+#line 5778 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5629,7 +5797,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5801: \"$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
@@ -5656,12 +5824,12 @@ done
for ac_func in __getcwd _getcwd
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5660: checking for $ac_func" >&5
+echo "configure:5828: 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 <<EOF
-#line 5665 "configure"
+#line 5833 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5684,7 +5852,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5856: \"$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
@@ -5711,12 +5879,12 @@ done
for ac_func in __xstat __fxstat __lxstat
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5715: checking for $ac_func" >&5
+echo "configure:5883: 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 <<EOF
-#line 5720 "configure"
+#line 5888 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5739,7 +5907,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5911: \"$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
@@ -5766,12 +5934,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:5770: checking for $ac_func" >&5
+echo "configure:5938: 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 <<EOF
-#line 5775 "configure"
+#line 5943 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5794,7 +5962,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:5966: \"$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
@@ -5821,12 +5989,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:5825: checking for $ac_func" >&5
+echo "configure:5993: 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 <<EOF
-#line 5830 "configure"
+#line 5998 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5849,7 +6017,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5853: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6021: \"$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
@@ -5876,12 +6044,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:5880: checking for $ac_func" >&5
+echo "configure:6048: 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 <<EOF
-#line 5885 "configure"
+#line 6053 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5904,7 +6072,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6076: \"$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
@@ -5931,12 +6099,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:5935: 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 <<EOF
-#line 5940 "configure"
+#line 6108 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5959,7 +6127,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5963: \"$ac_link\") 1>&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
@@ -5986,12 +6154,12 @@ done
for ac_func in _write __write _fork __fork
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5990: checking for $ac_func" >&5
+echo "configure:6158: 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 <<EOF
-#line 5995 "configure"
+#line 6163 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6014,7 +6182,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6186: \"$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
@@ -6041,12 +6209,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:6045: checking for $ac_func" >&5
+echo "configure:6213: 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 <<EOF
-#line 6050 "configure"
+#line 6218 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6069,7 +6237,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6241: \"$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
@@ -6096,12 +6264,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:6100: checking for $ac_func" >&5
+echo "configure:6268: 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 <<EOF
-#line 6105 "configure"
+#line 6273 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6124,7 +6292,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6296: \"$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
@@ -6151,12 +6319,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:6155: checking for $ac_func" >&5
+echo "configure:6323: 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 <<EOF
-#line 6160 "configure"
+#line 6328 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6179,7 +6347,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6351: \"$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
@@ -6206,12 +6374,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:6210: checking for $ac_func" >&5
+echo "configure:6378: 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 <<EOF
-#line 6215 "configure"
+#line 6383 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6234,7 +6402,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6238: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6406: \"$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
@@ -6261,12 +6429,12 @@ done
for ac_func in open64 _open64 __open64 creat64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6265: checking for $ac_func" >&5
+echo "configure:6433: 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 <<EOF
-#line 6270 "configure"
+#line 6438 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6289,7 +6457,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6293: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6461: \"$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
@@ -6320,9 +6488,9 @@ done
if test x$ac_cv_func_stat64 = xno ; then
echo $ac_n "checking for stat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:6324: checking for stat64 in <sys/stat.h>" >&5
+echo "configure:6492: checking for stat64 in <sys/stat.h>" >&5
cat > conftest.$ac_ext <<EOF
-#line 6326 "configure"
+#line 6494 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -6334,7 +6502,7 @@ int main() {
struct stat64 st64; exit(stat64(".",&st64));
; return 0; }
EOF
-if { (eval echo configure:6338: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_func_stat64=yes
else
@@ -6353,9 +6521,9 @@ fi
if test x$ac_cv_func_lstat64 = xno ; then
echo $ac_n "checking for lstat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:6357: checking for lstat64 in <sys/stat.h>" >&5
+echo "configure:6525: checking for lstat64 in <sys/stat.h>" >&5
cat > conftest.$ac_ext <<EOF
-#line 6359 "configure"
+#line 6527 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -6367,7 +6535,7 @@ int main() {
struct stat64 st64; exit(lstat64(".",&st64));
; return 0; }
EOF
-if { (eval echo configure:6371: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6539: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_func_lstat64=yes
else
@@ -6386,9 +6554,9 @@ fi
if test x$ac_cv_func_fstat64 = xno ; then
echo $ac_n "checking for fstat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:6390: checking for fstat64 in <sys/stat.h>" >&5
+echo "configure:6558: checking for fstat64 in <sys/stat.h>" >&5
cat > conftest.$ac_ext <<EOF
-#line 6392 "configure"
+#line 6560 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -6400,7 +6568,7 @@ int main() {
struct stat64 st64; exit(fstat64(0,&st64));
; return 0; }
EOF
-if { (eval echo configure:6404: \"$ac_link\") 1>&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*
ac_cv_func_fstat64=yes
else
@@ -6425,7 +6593,7 @@ fi
if test x$ac_cv_func_strcasecmp = xno ; then
echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6
-echo "configure:6429: checking for strcasecmp in -lresolv" >&5
+echo "configure:6597: checking for strcasecmp in -lresolv" >&5
ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6433,7 +6601,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6437 "configure"
+#line 6605 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6444,7 +6612,7 @@ int main() {
strcasecmp()
; return 0; }
EOF
-if { (eval echo configure:6448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6616: \"$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
@@ -6480,12 +6648,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6484: checking for $ac_func" >&5
+echo "configure:6652: 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 <<EOF
-#line 6489 "configure"
+#line 6657 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6508,7 +6676,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6512: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6680: \"$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
@@ -6533,7 +6701,7 @@ fi
done
;;
*) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:6537: checking for putprpwnam in -lsecurity" >&5
+echo "configure:6705: 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
@@ -6541,7 +6709,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6545 "configure"
+#line 6713 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6552,7 +6720,7 @@ int main() {
putprpwnam()
; return 0; }
EOF
-if { (eval echo configure:6556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6724: \"$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
@@ -6582,12 +6750,12 @@ fi
for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6586: checking for $ac_func" >&5
+echo "configure:6754: 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 <<EOF
-#line 6591 "configure"
+#line 6759 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6610,7 +6778,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6782: \"$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
@@ -6641,12 +6809,12 @@ case "$LIBS" in
*-lsec*) for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6645: checking for $ac_func" >&5
+echo "configure:6813: 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 <<EOF
-#line 6650 "configure"
+#line 6818 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6669,7 +6837,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6673: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6841: \"$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
@@ -6694,7 +6862,7 @@ fi
done
;;
*) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:6698: checking for putprpwnam in -lsec" >&5
+echo "configure:6866: 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
@@ -6702,7 +6870,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6706 "configure"
+#line 6874 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6713,7 +6881,7 @@ int main() {
putprpwnam()
; return 0; }
EOF
-if { (eval echo configure:6717: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6885: \"$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
@@ -6743,12 +6911,12 @@ fi
for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6747: checking for $ac_func" >&5
+echo "configure:6915: 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 <<EOF
-#line 6752 "configure"
+#line 6920 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6771,7 +6939,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6943: \"$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
@@ -6803,12 +6971,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:6807: checking for $ac_func" >&5
+echo "configure:6975: 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 <<EOF
-#line 6812 "configure"
+#line 6980 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6831,7 +6999,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7003: \"$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
@@ -6856,7 +7024,7 @@ fi
done
;;
*) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6
-echo "configure:6860: checking for set_auth_parameters in -lsecurity" >&5
+echo "configure:7028: 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
@@ -6864,7 +7032,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6868 "configure"
+#line 7036 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6875,7 +7043,7 @@ int main() {
set_auth_parameters()
; return 0; }
EOF
-if { (eval echo configure:6879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7047: \"$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
@@ -6905,12 +7073,12 @@ fi
for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6909: checking for $ac_func" >&5
+echo "configure:7077: 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 <<EOF
-#line 6914 "configure"
+#line 7082 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6933,7 +7101,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7105: \"$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
@@ -6964,12 +7132,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:6968: checking for $ac_func" >&5
+echo "configure:7136: 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 <<EOF
-#line 6973 "configure"
+#line 7141 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6992,7 +7160,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7164: \"$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
@@ -7017,7 +7185,7 @@ fi
done
;;
*) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6
-echo "configure:7021: checking for set_auth_parameters in -lsec" >&5
+echo "configure:7189: 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
@@ -7025,7 +7193,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7029 "configure"
+#line 7197 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7036,7 +7204,7 @@ int main() {
set_auth_parameters()
; return 0; }
EOF
-if { (eval echo configure:7040: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7208: \"$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
@@ -7066,12 +7234,12 @@ fi
for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7070: checking for $ac_func" >&5
+echo "configure:7238: 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 <<EOF
-#line 7075 "configure"
+#line 7243 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7094,7 +7262,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7098: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7266: \"$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
@@ -7127,12 +7295,12 @@ case "$LIBS" in
*-lgen*) for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7131: checking for $ac_func" >&5
+echo "configure:7299: 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 <<EOF
-#line 7136 "configure"
+#line 7304 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7155,7 +7323,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7159: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7327: \"$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
@@ -7180,7 +7348,7 @@ fi
done
;;
*) echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6
-echo "configure:7184: checking for getspnam in -lgen" >&5
+echo "configure:7352: 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
@@ -7188,7 +7356,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7192 "configure"
+#line 7360 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7199,7 +7367,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:7203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7371: \"$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
@@ -7229,12 +7397,12 @@ fi
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7233: checking for $ac_func" >&5
+echo "configure:7401: 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 <<EOF
-#line 7238 "configure"
+#line 7406 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7257,7 +7425,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7261: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7429: \"$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
@@ -7289,12 +7457,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7293: checking for $ac_func" >&5
+echo "configure:7461: 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 <<EOF
-#line 7298 "configure"
+#line 7466 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7317,7 +7485,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7489: \"$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
@@ -7342,7 +7510,7 @@ fi
done
;;
*) echo $ac_n "checking for getspnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:7346: checking for getspnam in -lsecurity" >&5
+echo "configure:7514: 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
@@ -7350,7 +7518,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7354 "configure"
+#line 7522 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7361,7 +7529,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:7365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7533: \"$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
@@ -7391,12 +7559,12 @@ fi
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7395: checking for $ac_func" >&5
+echo "configure:7563: 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 <<EOF
-#line 7400 "configure"
+#line 7568 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7419,7 +7587,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7423: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7591: \"$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
@@ -7450,12 +7618,12 @@ case "$LIBS" in
*-lsec*) for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7454: checking for $ac_func" >&5
+echo "configure:7622: 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 <<EOF
-#line 7459 "configure"
+#line 7627 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7478,7 +7646,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7650: \"$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
@@ -7503,7 +7671,7 @@ fi
done
;;
*) echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6
-echo "configure:7507: checking for getspnam in -lsec" >&5
+echo "configure:7675: 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
@@ -7511,7 +7679,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7515 "configure"
+#line 7683 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7522,7 +7690,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:7526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7694: \"$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
@@ -7552,12 +7720,12 @@ fi
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7556: checking for $ac_func" >&5
+echo "configure:7724: 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 <<EOF
-#line 7561 "configure"
+#line 7729 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7580,7 +7748,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7752: \"$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
@@ -7612,12 +7780,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7616: checking for $ac_func" >&5
+echo "configure:7784: 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 <<EOF
-#line 7621 "configure"
+#line 7789 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7640,7 +7808,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7812: \"$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
@@ -7665,7 +7833,7 @@ fi
done
;;
*) echo $ac_n "checking for bigcrypt in -lsecurity""... $ac_c" 1>&6
-echo "configure:7669: checking for bigcrypt in -lsecurity" >&5
+echo "configure:7837: 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
@@ -7673,7 +7841,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7677 "configure"
+#line 7845 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7684,7 +7852,7 @@ int main() {
bigcrypt()
; return 0; }
EOF
-if { (eval echo configure:7688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7856: \"$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
@@ -7714,12 +7882,12 @@ fi
for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7718: checking for $ac_func" >&5
+echo "configure:7886: 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 <<EOF
-#line 7723 "configure"
+#line 7891 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7742,7 +7910,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7914: \"$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
@@ -7773,12 +7941,12 @@ case "$LIBS" in
*-lsec*) for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7777: checking for $ac_func" >&5
+echo "configure:7945: 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 <<EOF
-#line 7782 "configure"
+#line 7950 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7801,7 +7969,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7805: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7973: \"$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
@@ -7826,7 +7994,7 @@ fi
done
;;
*) echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6
-echo "configure:7830: checking for bigcrypt in -lsec" >&5
+echo "configure:7998: 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
@@ -7834,7 +8002,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7838 "configure"
+#line 8006 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7845,7 +8013,7 @@ int main() {
bigcrypt()
; return 0; }
EOF
-if { (eval echo configure:7849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8017: \"$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
@@ -7875,12 +8043,12 @@ fi
for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7879: checking for $ac_func" >&5
+echo "configure:8047: 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 <<EOF
-#line 7884 "configure"
+#line 8052 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7903,7 +8071,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8075: \"$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
@@ -7935,12 +8103,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7939: checking for $ac_func" >&5
+echo "configure:8107: 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 <<EOF
-#line 7944 "configure"
+#line 8112 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7963,7 +8131,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8135: \"$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
@@ -7988,7 +8156,7 @@ fi
done
;;
*) echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:7992: checking for getprpwnam in -lsecurity" >&5
+echo "configure:8160: 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
@@ -7996,7 +8164,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8000 "configure"
+#line 8168 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -8007,7 +8175,7 @@ int main() {
getprpwnam()
; return 0; }
EOF
-if { (eval echo configure:8011: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8179: \"$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
@@ -8037,12 +8205,12 @@ fi
for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8041: checking for $ac_func" >&5
+echo "configure:8209: 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 <<EOF
-#line 8046 "configure"
+#line 8214 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -8065,7 +8233,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:8069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8237: \"$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
@@ -8096,12 +8264,12 @@ case "$LIBS" in
*-lsec*) for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8100: checking for $ac_func" >&5
+echo "configure:8268: 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 <<EOF
-#line 8105 "configure"
+#line 8273 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -8124,7 +8292,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:8128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8296: \"$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
@@ -8149,7 +8317,7 @@ fi
done
;;
*) echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:8153: checking for getprpwnam in -lsec" >&5
+echo "configure:8321: 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
@@ -8157,7 +8325,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 8161 "configure"
+#line 8329 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -8168,7 +8336,7 @@ int main() {
getprpwnam()
; return 0; }
EOF
-if { (eval echo configure:8172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8340: \"$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
@@ -8198,12 +8366,12 @@ fi
for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8202: checking for $ac_func" >&5
+echo "configure:8370: 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 <<EOF
-#line 8207 "configure"
+#line 8375 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -8226,7 +8394,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:8230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8398: \"$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
@@ -8261,12 +8429,15 @@ done
# these are the defaults, good for lots of systems
HOST_OS="$host_os"
LDSHFLAGS="-shared"
+SONAMEFLAG="#"
SHLD="\${CC}"
PICFLAG=""
PICSUFFIX="po.o"
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:8441: checking ability to build shared libraries" >&5
# and these are for particular systems
case "$host_os" in
@@ -8277,18 +8448,45 @@ EOF
BLDSHARED="true"
LDSHFLAGS="-shared"
PICFLAG="-fPIC"
- ;;
+ SONAMEFLAG="-Wl,-soname="
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE 512
+EOF
+
+ ;;
*solaris*) cat >> confdefs.h <<\EOF
#define SUNOS5 1
EOF
- ;;
+ BLDSHARED="true"
+ LDSHFLAGS="-h \$@ -G"
+ if test "${ac_cv_prog_CC}" = "gcc"; then
+ PICFLAG="-fPIC"
+ else
+ PICFLAG="-KPIC"
+ POBAD_CC=""
+ PICSUFFIX="po.o"
+ fi
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE 512
+EOF
+
+ ;;
*sunos*) cat >> confdefs.h <<\EOF
#define SUNOS4 1
EOF
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-h,\$@ -G"
+ PICFLAG="-KPIC" # Is this correct for SunOS
;;
- *bsd*) LDSHFLAGS="-shared -Bshareable"
+ *bsd*) BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-fPIC"
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE 512
+EOF
+
;;
*irix*) cat >> confdefs.h <<\EOF
#define IRIX 1
@@ -8302,12 +8500,29 @@ EOF
;;
esac
ATTEMPT_WRAP32_BUILD=yes
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ if test "${ac_cv_prog_CC}" = "gcc"; then
+ PICFLAG="-fPIC"
+ else
+ PICFLAG="-KPIC"
+ fi
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE 512
+EOF
+
;;
*aix*) cat >> confdefs.h <<\EOF
#define AIX 1
EOF
- # AIX is too ugly for now
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry"
+ PICFLAG="-O2 -qmaxmem=6000"
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE DEV_BSIZE
+EOF
+
;;
*hpux*) cat >> confdefs.h <<\EOF
#define HPUX 1
@@ -8316,10 +8531,16 @@ EOF
SHLIBEXT="sl"
# Use special PIC flags for the native HP-UX compiler.
if test $ac_cv_prog_cc_Ae = yes; then
- LDSHFLAGS="-b"
+ BLDSHARED="true"
+ SHLD="/usr/bin/ld"
+ LDSHFLAGS="-B symbolic -b -z +h \$@"
PICFLAG="+z"
fi
- ;;
+ cat >> confdefs.h <<\EOF
+#define STAT_ST_BLOCKSIZE 8192
+EOF
+
+ ;;
*qnx*) cat >> confdefs.h <<\EOF
#define QNX 1
EOF
@@ -8327,11 +8548,23 @@ EOF
*osf*) cat >> confdefs.h <<\EOF
#define OSF1 1
EOF
-;;
+
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-fPIC"
+ ;;
*sco*) cat >> confdefs.h <<\EOF
#define SCO 1
EOF
;;
+ *unixware*) cat >> confdefs.h <<\EOF
+#define UNIXWARE 1
+EOF
+
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-KPIC"
+ ;;
*next2*) cat >> confdefs.h <<\EOF
#define NEXT2 1
EOF
@@ -8339,7 +8572,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:8343: checking for $ac_word" >&5
+echo "configure:8576: 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
@@ -8391,10 +8624,17 @@ EOF
LDSHFLAGS="-G"
;;
esac
+echo "$ac_t""$BLDSHARED" 1>&6
+echo $ac_n "checking linker flags for shared libraries""... $ac_c" 1>&6
+echo "configure:8630: 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:8633: checking compiler flags for position-independent code" >&5
+echo "$ac_t""$PICFLAGS" 1>&6
# try to work out how to produce pic code with this compiler
echo $ac_n "checking whether ${CC-cc} accepts -fpic""... $ac_c" 1>&6
-echo "configure:8398: checking whether ${CC-cc} accepts -fpic" >&5
+echo "configure:8638: checking whether ${CC-cc} accepts -fpic" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_fpic'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8414,7 +8654,7 @@ if test $ac_cv_prog_cc_fpic = yes; then
fi
if test x$PICFLAG = x; then
echo $ac_n "checking whether ${CC-cc} accepts -KPIC""... $ac_c" 1>&6
-echo "configure:8418: checking whether ${CC-cc} accepts -KPIC" >&5
+echo "configure:8658: checking whether ${CC-cc} accepts -KPIC" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_KPIC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8435,7 +8675,7 @@ echo "$ac_t""$ac_cv_prog_cc_KPIC" 1>&6
fi
if test x$PICFLAG = x; then
echo $ac_n "checking whether ${CC-cc} accepts -Kpic""... $ac_c" 1>&6
-echo "configure:8439: checking whether ${CC-cc} accepts -Kpic" >&5
+echo "configure:8679: checking whether ${CC-cc} accepts -Kpic" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_Kpic'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8458,7 +8698,7 @@ fi
################
echo $ac_n "checking for long long""... $ac_c" 1>&6
-echo "configure:8462: checking for long long" >&5
+echo "configure:8702: 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
@@ -8467,12 +8707,12 @@ if test "$cross_compiling" = yes; then
samba_cv_have_longlong=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8471 "configure"
+#line 8711 "configure"
#include "confdefs.h"
#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }
EOF
-if { (eval echo configure:8476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8716: \"$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
@@ -8499,20 +8739,20 @@ fi
# AIX needs this.
echo $ac_n "checking for LL suffix on long long integers""... $ac_c" 1>&6
-echo "configure:8503: checking for LL suffix on long long integers" >&5
+echo "configure:8743: 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 <<EOF
-#line 8509 "configure"
+#line 8749 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
long long i = 0x8000000000LL
; return 0; }
EOF
-if { (eval echo configure:8516: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_compiler_supports_ll=yes
else
@@ -8534,7 +8774,7 @@ fi
echo $ac_n "checking for 64 bit off_t""... $ac_c" 1>&6
-echo "configure:8538: checking for 64 bit off_t" >&5
+echo "configure:8778: 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
@@ -8543,13 +8783,13 @@ if test "$cross_compiling" = yes; then
samba_cv_SIZEOF_OFF_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8547 "configure"
+#line 8787 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/stat.h>
main() { exit((sizeof(off_t) == 8) ? 0 : 1); }
EOF
-if { (eval echo configure:8553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8793: \"$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
@@ -8572,7 +8812,7 @@ EOF
fi
echo $ac_n "checking for off64_t""... $ac_c" 1>&6
-echo "configure:8576: checking for off64_t" >&5
+echo "configure:8816: 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
@@ -8581,7 +8821,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_OFF64_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8585 "configure"
+#line 8825 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -8591,7 +8831,7 @@ else
#include <sys/stat.h>
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:8595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8835: \"$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
@@ -8614,7 +8854,7 @@ EOF
fi
echo $ac_n "checking for 64 bit ino_t""... $ac_c" 1>&6
-echo "configure:8618: checking for 64 bit ino_t" >&5
+echo "configure:8858: 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
@@ -8623,13 +8863,13 @@ if test "$cross_compiling" = yes; then
samba_cv_SIZEOF_INO_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8627 "configure"
+#line 8867 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/stat.h>
main() { exit((sizeof(ino_t) == 8) ? 0 : 1); }
EOF
-if { (eval echo configure:8633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8873: \"$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
@@ -8652,7 +8892,7 @@ EOF
fi
echo $ac_n "checking for ino64_t""... $ac_c" 1>&6
-echo "configure:8656: checking for ino64_t" >&5
+echo "configure:8896: 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
@@ -8661,7 +8901,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_INO64_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8665 "configure"
+#line 8905 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -8671,7 +8911,7 @@ else
#include <sys/stat.h>
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:8675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8915: \"$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
@@ -8693,14 +8933,56 @@ EOF
fi
+echo $ac_n "checking for dev64_t""... $ac_c" 1>&6
+echo "configure:8938: 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
+
+if test "$cross_compiling" = yes; then
+ samba_cv_HAVE_DEV64_T=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 8947 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+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:8957: \"$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
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ samba_cv_HAVE_DEV64_T=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_DEV64_T" 1>&6
+if test x"$samba_cv_HAVE_DEV64_T" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_DEV64_T 1
+EOF
+
+fi
+
echo $ac_n "checking for struct dirent64""... $ac_c" 1>&6
-echo "configure:8698: checking for struct dirent64" >&5
+echo "configure:8980: 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 <<EOF
-#line 8704 "configure"
+#line 8986 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -8712,7 +8994,7 @@ int main() {
struct dirent64 de;
; return 0; }
EOF
-if { (eval echo configure:8716: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8998: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_STRUCT_DIRENT64=yes
else
@@ -8732,8 +9014,131 @@ EOF
fi
+echo $ac_n "checking for major macro""... $ac_c" 1>&6
+echo "configure:9019: 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
+
+if test "$cross_compiling" = yes; then
+ samba_cv_HAVE_DEVICE_MAJOR_FN=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9028 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev; int i = major(dev); return 0; }
+EOF
+if { (eval echo configure:9037: \"$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
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ samba_cv_HAVE_DEVICE_MAJOR_FN=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_DEVICE_MAJOR_FN" 1>&6
+if test x"$samba_cv_HAVE_DEVICE_MAJOR_FN" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_DEVICE_MAJOR_FN 1
+EOF
+
+fi
+
+echo $ac_n "checking for minor macro""... $ac_c" 1>&6
+echo "configure:9060: 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
+
+if test "$cross_compiling" = yes; then
+ samba_cv_HAVE_DEVICE_MINOR_FN=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9069 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev; int i = minor(dev); return 0; }
+EOF
+if { (eval echo configure:9078: \"$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
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ samba_cv_HAVE_DEVICE_MINOR_FN=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_DEVICE_MINOR_FN" 1>&6
+if test x"$samba_cv_HAVE_DEVICE_MINOR_FN" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_DEVICE_MINOR_FN 1
+EOF
+
+fi
+
+echo $ac_n "checking for makedev macro""... $ac_c" 1>&6
+echo "configure:9101: checking for makedev macro" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_MAKEDEV_FN'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+if test "$cross_compiling" = yes; then
+ samba_cv_HAVE_MAKEDEV_FN=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 9110 "configure"
+#include "confdefs.h"
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev = makedev(1,2); return 0; }
+EOF
+if { (eval echo configure:9119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ samba_cv_HAVE_MAKEDEV_FN=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ samba_cv_HAVE_MAKEDEV_FN=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$samba_cv_HAVE_MAKEDEV_FN" 1>&6
+if test x"$samba_cv_HAVE_MAKEDEV_FN" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define MAKEDEV_FN 1
+EOF
+
+fi
+
echo $ac_n "checking for unsigned char""... $ac_c" 1>&6
-echo "configure:8737: checking for unsigned char" >&5
+echo "configure:9142: 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
@@ -8742,12 +9147,12 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_UNSIGNED_CHAR=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8746 "configure"
+#line 9151 "configure"
#include "confdefs.h"
#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }
EOF
-if { (eval echo configure:8751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9156: \"$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
@@ -8770,13 +9175,13 @@ EOF
fi
echo $ac_n "checking for sin_len in sock""... $ac_c" 1>&6
-echo "configure:8774: checking for sin_len in sock" >&5
+echo "configure:9179: 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 <<EOF
-#line 8780 "configure"
+#line 9185 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
@@ -8785,7 +9190,7 @@ int main() {
struct sockaddr_in sock; sock.sin_len = sizeof(sock);
; return 0; }
EOF
-if { (eval echo configure:8789: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9194: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_SOCK_SIN_LEN=yes
else
@@ -8806,13 +9211,13 @@ EOF
fi
echo $ac_n "checking whether seekdir returns void""... $ac_c" 1>&6
-echo "configure:8810: checking whether seekdir returns void" >&5
+echo "configure:9215: 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 <<EOF
-#line 8816 "configure"
+#line 9221 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <dirent.h>
@@ -8821,7 +9226,7 @@ int main() {
return 0;
; return 0; }
EOF
-if { (eval echo configure:8825: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9230: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_SEEKDIR_RETURNS_VOID=yes
else
@@ -8842,20 +9247,20 @@ EOF
fi
echo $ac_n "checking for __FILE__ macro""... $ac_c" 1>&6
-echo "configure:8846: checking for __FILE__ macro" >&5
+echo "configure:9251: 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 <<EOF
-#line 8852 "configure"
+#line 9257 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
printf("%s\n", __FILE__);
; return 0; }
EOF
-if { (eval echo configure:8859: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_FILE_MACRO=yes
else
@@ -8876,20 +9281,20 @@ EOF
fi
echo $ac_n "checking for __FUNCTION__ macro""... $ac_c" 1>&6
-echo "configure:8880: checking for __FUNCTION__ macro" >&5
+echo "configure:9285: 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 <<EOF
-#line 8886 "configure"
+#line 9291 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
printf("%s\n", __FUNCTION__);
; return 0; }
EOF
-if { (eval echo configure:8893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9298: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_FUNCTION_MACRO=yes
else
@@ -8910,7 +9315,7 @@ EOF
fi
echo $ac_n "checking if gettimeofday takes tz argument""... $ac_c" 1>&6
-echo "configure:8914: checking if gettimeofday takes tz argument" >&5
+echo "configure:9319: 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
@@ -8919,14 +9324,14 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_GETTIMEOFDAY_TZ=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8923 "configure"
+#line 9328 "configure"
#include "confdefs.h"
#include <sys/time.h>
#include <unistd.h>
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}
EOF
-if { (eval echo configure:8930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9335: \"$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
@@ -8949,7 +9354,7 @@ EOF
fi
echo $ac_n "checking for C99 vsnprintf""... $ac_c" 1>&6
-echo "configure:8953: checking for C99 vsnprintf" >&5
+echo "configure:9358: 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
@@ -8958,7 +9363,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_C99_VSNPRINTF=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8962 "configure"
+#line 9367 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -8980,7 +9385,7 @@ void foo(const char *format, ...) {
main() { foo("hello"); }
EOF
-if { (eval echo configure:8984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9389: \"$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
@@ -9003,7 +9408,7 @@ EOF
fi
echo $ac_n "checking for broken readdir""... $ac_c" 1>&6
-echo "configure:9007: checking for broken readdir" >&5
+echo "configure:9412: 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
@@ -9012,7 +9417,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_BROKEN_READDIR=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9016 "configure"
+#line 9421 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <dirent.h>
@@ -9020,7 +9425,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:9024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9429: \"$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
@@ -9043,13 +9448,13 @@ EOF
fi
echo $ac_n "checking for utimbuf""... $ac_c" 1>&6
-echo "configure:9047: checking for utimbuf" >&5
+echo "configure:9452: 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 <<EOF
-#line 9053 "configure"
+#line 9458 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utime.h>
@@ -9057,7 +9462,7 @@ int main() {
struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));
; return 0; }
EOF
-if { (eval echo configure:9061: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9466: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UTIMBUF=yes
else
@@ -9081,12 +9486,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:9085: checking for $ac_func" >&5
+echo "configure:9490: 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 <<EOF
-#line 9090 "configure"
+#line 9495 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -9109,7 +9514,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:9113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:9518: \"$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
@@ -9135,13 +9540,13 @@ done
echo $ac_n "checking for ut_name in utmp""... $ac_c" 1>&6
-echo "configure:9139: checking for ut_name in utmp" >&5
+echo "configure:9544: 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 <<EOF
-#line 9145 "configure"
+#line 9550 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9149,7 +9554,7 @@ int main() {
struct utmp ut; ut.ut_name[0] = 'a';
; return 0; }
EOF
-if { (eval echo configure:9153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9558: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_NAME=yes
else
@@ -9170,13 +9575,13 @@ EOF
fi
echo $ac_n "checking for ut_user in utmp""... $ac_c" 1>&6
-echo "configure:9174: checking for ut_user in utmp" >&5
+echo "configure:9579: 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 <<EOF
-#line 9180 "configure"
+#line 9585 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9184,7 +9589,7 @@ int main() {
struct utmp ut; ut.ut_user[0] = 'a';
; return 0; }
EOF
-if { (eval echo configure:9188: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_USER=yes
else
@@ -9205,13 +9610,13 @@ EOF
fi
echo $ac_n "checking for ut_id in utmp""... $ac_c" 1>&6
-echo "configure:9209: checking for ut_id in utmp" >&5
+echo "configure:9614: 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 <<EOF
-#line 9215 "configure"
+#line 9620 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9219,7 +9624,7 @@ int main() {
struct utmp ut; ut.ut_id[0] = 'a';
; return 0; }
EOF
-if { (eval echo configure:9223: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_ID=yes
else
@@ -9240,13 +9645,13 @@ EOF
fi
echo $ac_n "checking for ut_host in utmp""... $ac_c" 1>&6
-echo "configure:9244: checking for ut_host in utmp" >&5
+echo "configure:9649: 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 <<EOF
-#line 9250 "configure"
+#line 9655 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9254,7 +9659,7 @@ int main() {
struct utmp ut; ut.ut_host[0] = 'a';
; return 0; }
EOF
-if { (eval echo configure:9258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9663: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_HOST=yes
else
@@ -9275,13 +9680,13 @@ EOF
fi
echo $ac_n "checking for ut_time in utmp""... $ac_c" 1>&6
-echo "configure:9279: checking for ut_time in utmp" >&5
+echo "configure:9684: 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 <<EOF
-#line 9285 "configure"
+#line 9690 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9289,7 +9694,7 @@ int main() {
struct utmp ut; time_t t; ut.ut_time = t;
; return 0; }
EOF
-if { (eval echo configure:9293: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_TIME=yes
else
@@ -9310,13 +9715,13 @@ EOF
fi
echo $ac_n "checking for ut_tv in utmp""... $ac_c" 1>&6
-echo "configure:9314: checking for ut_tv in utmp" >&5
+echo "configure:9719: 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 <<EOF
-#line 9320 "configure"
+#line 9725 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9324,7 +9729,7 @@ int main() {
struct utmp ut; struct timeval tv; ut.ut_tv = tv;
; return 0; }
EOF
-if { (eval echo configure:9328: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9733: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_TV=yes
else
@@ -9345,13 +9750,13 @@ EOF
fi
echo $ac_n "checking for ut_type in utmp""... $ac_c" 1>&6
-echo "configure:9349: checking for ut_type in utmp" >&5
+echo "configure:9754: 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 <<EOF
-#line 9355 "configure"
+#line 9760 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9359,7 +9764,7 @@ int main() {
struct utmp ut; ut.ut_type = 0;
; return 0; }
EOF
-if { (eval echo configure:9363: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9768: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_TYPE=yes
else
@@ -9380,13 +9785,13 @@ EOF
fi
echo $ac_n "checking for ut_pid in utmp""... $ac_c" 1>&6
-echo "configure:9384: checking for ut_pid in utmp" >&5
+echo "configure:9789: 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 <<EOF
-#line 9390 "configure"
+#line 9795 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9394,7 +9799,7 @@ int main() {
struct utmp ut; ut.ut_pid = 0;
; return 0; }
EOF
-if { (eval echo configure:9398: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9803: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_PID=yes
else
@@ -9415,13 +9820,13 @@ EOF
fi
echo $ac_n "checking for ut_exit in utmp""... $ac_c" 1>&6
-echo "configure:9419: checking for ut_exit in utmp" >&5
+echo "configure:9824: 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 <<EOF
-#line 9425 "configure"
+#line 9830 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9429,7 +9834,7 @@ int main() {
struct utmp ut; ut.ut_exit.e_exit = 0;
; return 0; }
EOF
-if { (eval echo configure:9433: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9838: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_EXIT=yes
else
@@ -9450,13 +9855,13 @@ EOF
fi
echo $ac_n "checking for ut_addr in utmp""... $ac_c" 1>&6
-echo "configure:9454: checking for ut_addr in utmp" >&5
+echo "configure:9859: 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 <<EOF
-#line 9460 "configure"
+#line 9865 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9464,7 +9869,7 @@ int main() {
struct utmp ut; ut.ut_addr = 0;
; return 0; }
EOF
-if { (eval echo configure:9468: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9873: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UT_UT_ADDR=yes
else
@@ -9486,13 +9891,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:9490: checking whether pututline returns pointer" >&5
+echo "configure:9895: 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 <<EOF
-#line 9496 "configure"
+#line 9901 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmp.h>
@@ -9500,7 +9905,7 @@ int main() {
struct utmp utarg; struct utmp *utreturn; utreturn = pututline(&utarg);
; return 0; }
EOF
-if { (eval echo configure:9504: \"$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_PUTUTLINE_RETURNS_UTMP=yes
else
@@ -9522,13 +9927,13 @@ EOF
fi
echo $ac_n "checking for ut_syslen in utmpx""... $ac_c" 1>&6
-echo "configure:9526: checking for ut_syslen in utmpx" >&5
+echo "configure:9931: 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 <<EOF
-#line 9532 "configure"
+#line 9937 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utmpx.h>
@@ -9536,7 +9941,7 @@ int main() {
struct utmpx ux; ux.ut_syslen = 0;
; return 0; }
EOF
-if { (eval echo configure:9540: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:9945: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UX_UT_SYSLEN=yes
else
@@ -9557,7 +9962,7 @@ EOF
fi
echo $ac_n "checking for Linux kernel oplocks""... $ac_c" 1>&6
-echo "configure:9561: checking for Linux kernel oplocks" >&5
+echo "configure:9966: 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
@@ -9566,7 +9971,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_KERNEL_OPLOCKS_LINUX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9570 "configure"
+#line 9975 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -9580,7 +9985,7 @@ main() {
}
EOF
-if { (eval echo configure:9584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9989: \"$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
@@ -9603,7 +10008,7 @@ EOF
fi
echo $ac_n "checking for kernel change notify support""... $ac_c" 1>&6
-echo "configure:9607: checking for kernel change notify support" >&5
+echo "configure:10012: 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
@@ -9612,7 +10017,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_KERNEL_CHANGE_NOTIFY=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9616 "configure"
+#line 10021 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -9626,7 +10031,7 @@ main() {
}
EOF
-if { (eval echo configure:9630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10035: \"$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
@@ -9649,7 +10054,7 @@ EOF
fi
echo $ac_n "checking for kernel share modes""... $ac_c" 1>&6
-echo "configure:9653: checking for kernel share modes" >&5
+echo "configure:10058: 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
@@ -9658,7 +10063,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_KERNEL_SHARE_MODES=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9662 "configure"
+#line 10067 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -9674,7 +10079,7 @@ main() {
}
EOF
-if { (eval echo configure:9678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10083: \"$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
@@ -9700,13 +10105,13 @@ fi
echo $ac_n "checking for IRIX kernel oplock type definitions""... $ac_c" 1>&6
-echo "configure:9704: checking for IRIX kernel oplock type definitions" >&5
+echo "configure:10109: 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 <<EOF
-#line 9710 "configure"
+#line 10115 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -9714,7 +10119,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:9718: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_KERNEL_OPLOCKS_IRIX=yes
else
@@ -9735,7 +10140,7 @@ EOF
fi
echo $ac_n "checking for irix specific capabilities""... $ac_c" 1>&6
-echo "configure:9739: checking for irix specific capabilities" >&5
+echo "configure:10144: 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
@@ -9744,7 +10149,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9748 "configure"
+#line 10153 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/capability.h>
@@ -9759,7 +10164,7 @@ main() {
}
EOF
-if { (eval echo configure:9763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10168: \"$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
@@ -9787,13 +10192,13 @@ fi
#
echo $ac_n "checking for int16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:9791: checking for int16 typedef included by rpc/rpc.h" >&5
+echo "configure:10196: 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 <<EOF
-#line 9797 "configure"
+#line 10202 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -9803,7 +10208,7 @@ int main() {
int16 testvar;
; return 0; }
EOF
-if { (eval echo configure:9807: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10212: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes
else
@@ -9824,13 +10229,13 @@ EOF
fi
echo $ac_n "checking for uint16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:9828: checking for uint16 typedef included by rpc/rpc.h" >&5
+echo "configure:10233: 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 <<EOF
-#line 9834 "configure"
+#line 10239 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -9840,7 +10245,7 @@ int main() {
uint16 testvar;
; return 0; }
EOF
-if { (eval echo configure:9844: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10249: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes
else
@@ -9861,13 +10266,13 @@ EOF
fi
echo $ac_n "checking for int32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:9865: checking for int32 typedef included by rpc/rpc.h" >&5
+echo "configure:10270: 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 <<EOF
-#line 9871 "configure"
+#line 10276 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -9877,7 +10282,7 @@ int main() {
int32 testvar;
; return 0; }
EOF
-if { (eval echo configure:9881: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10286: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes
else
@@ -9898,13 +10303,13 @@ EOF
fi
echo $ac_n "checking for uint32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:9902: checking for uint32 typedef included by rpc/rpc.h" >&5
+echo "configure:10307: 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 <<EOF
-#line 9908 "configure"
+#line 10313 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -9914,7 +10319,7 @@ int main() {
uint32 testvar;
; return 0; }
EOF
-if { (eval echo configure:9918: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10323: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes
else
@@ -9936,13 +10341,13 @@ fi
echo $ac_n "checking for conflicting AUTH_ERROR define in rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:9940: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5
+echo "configure:10345: 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 <<EOF
-#line 9946 "configure"
+#line 10351 "configure"
#include "confdefs.h"
#include <sys/types.h>
#ifdef HAVE_SYS_SECURITY_H
@@ -9956,7 +10361,7 @@ int main() {
int testvar;
; return 0; }
EOF
-if { (eval echo configure:9960: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10365: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no
else
@@ -9977,16 +10382,16 @@ EOF
fi
echo $ac_n "checking for test routines""... $ac_c" 1>&6
-echo "configure:9981: checking for test routines" >&5
+echo "configure:10386: 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 <<EOF
-#line 9986 "configure"
+#line 10391 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/trivial.c"
EOF
-if { (eval echo configure:9990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10395: \"$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
@@ -10000,7 +10405,7 @@ fi
echo $ac_n "checking for ftruncate extend""... $ac_c" 1>&6
-echo "configure:10004: checking for ftruncate extend" >&5
+echo "configure:10409: 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
@@ -10009,11 +10414,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_FTRUNCATE_EXTEND=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10013 "configure"
+#line 10418 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/ftruncate.c"
EOF
-if { (eval echo configure:10017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10422: \"$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
@@ -10036,7 +10441,7 @@ EOF
fi
echo $ac_n "checking for broken getgroups""... $ac_c" 1>&6
-echo "configure:10040: checking for broken getgroups" >&5
+echo "configure:10445: 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
@@ -10045,11 +10450,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_BROKEN_GETGROUPS=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10049 "configure"
+#line 10454 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/getgroups.c"
EOF
-if { (eval echo configure:10053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10458: \"$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
@@ -10072,7 +10477,7 @@ EOF
fi
echo $ac_n "checking whether getpass should be replaced""... $ac_c" 1>&6
-echo "configure:10076: checking whether getpass should be replaced" >&5
+echo "configure:10481: 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
@@ -10080,7 +10485,7 @@ else
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper"
cat > conftest.$ac_ext <<EOF
-#line 10084 "configure"
+#line 10489 "configure"
#include "confdefs.h"
#define REPLACE_GETPASS 1
@@ -10093,7 +10498,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:10097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:10502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_REPLACE_GETPASS=yes
else
@@ -10116,7 +10521,7 @@ EOF
fi
echo $ac_n "checking for broken inet_ntoa""... $ac_c" 1>&6
-echo "configure:10120: checking for broken inet_ntoa" >&5
+echo "configure:10525: 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
@@ -10125,7 +10530,7 @@ if test "$cross_compiling" = yes; then
samba_cv_REPLACE_INET_NTOA=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10129 "configure"
+#line 10534 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -10139,7 +10544,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:10143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10548: \"$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
@@ -10162,7 +10567,7 @@ EOF
fi
echo $ac_n "checking for secure mkstemp""... $ac_c" 1>&6
-echo "configure:10166: checking for secure mkstemp" >&5
+echo "configure:10571: 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
@@ -10171,7 +10576,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_SECURE_MKSTEMP=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10175 "configure"
+#line 10580 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <sys/types.h>
@@ -10188,7 +10593,7 @@ main() {
exit(0);
}
EOF
-if { (eval echo configure:10192: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10597: \"$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
@@ -10211,7 +10616,7 @@ EOF
fi
echo $ac_n "checking for sysconf(_SC_NGROUPS_MAX)""... $ac_c" 1>&6
-echo "configure:10215: checking for sysconf(_SC_NGROUPS_MAX)" >&5
+echo "configure:10620: 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
@@ -10220,12 +10625,12 @@ if test "$cross_compiling" = yes; then
samba_cv_SYSCONF_SC_NGROUPS_MAX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10224 "configure"
+#line 10629 "configure"
#include "confdefs.h"
#include <unistd.h>
main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); }
EOF
-if { (eval echo configure:10229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10634: \"$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
@@ -10248,7 +10653,7 @@ EOF
fi
echo $ac_n "checking for root""... $ac_c" 1>&6
-echo "configure:10252: checking for root" >&5
+echo "configure:10657: checking for root" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10257,11 +10662,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_ROOT=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10261 "configure"
+#line 10666 "configure"
#include "confdefs.h"
main() { exit(getuid() != 0); }
EOF
-if { (eval echo configure:10265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10670: \"$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
@@ -10289,7 +10694,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:10293: checking for iface AIX" >&5
+echo "configure:10698: 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
@@ -10298,7 +10703,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_IFACE_AIX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10302 "configure"
+#line 10707 "configure"
#include "confdefs.h"
#define HAVE_IFACE_AIX 1
@@ -10306,7 +10711,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/interfaces.c"
EOF
-if { (eval echo configure:10310: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10715: \"$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
@@ -10330,7 +10735,7 @@ fi
if test $iface = no; then
echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6
-echo "configure:10334: checking for iface ifconf" >&5
+echo "configure:10739: 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
@@ -10339,7 +10744,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_IFACE_IFCONF=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10343 "configure"
+#line 10748 "configure"
#include "confdefs.h"
#define HAVE_IFACE_IFCONF 1
@@ -10347,7 +10752,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/interfaces.c"
EOF
-if { (eval echo configure:10351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10756: \"$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
@@ -10372,7 +10777,7 @@ fi
if test $iface = no; then
echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6
-echo "configure:10376: checking for iface ifreq" >&5
+echo "configure:10781: 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
@@ -10381,7 +10786,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_IFACE_IFREQ=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10385 "configure"
+#line 10790 "configure"
#include "confdefs.h"
#define HAVE_IFACE_IFREQ 1
@@ -10389,7 +10794,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/interfaces.c"
EOF
-if { (eval echo configure:10393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10798: \"$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
@@ -10418,7 +10823,7 @@ fi
seteuid=no;
if test $seteuid = no; then
echo $ac_n "checking for setresuid""... $ac_c" 1>&6
-echo "configure:10422: checking for setresuid" >&5
+echo "configure:10827: checking for setresuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10427,7 +10832,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETRESUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10431 "configure"
+#line 10836 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -10435,7 +10840,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:10439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10844: \"$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
@@ -10461,7 +10866,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for setreuid""... $ac_c" 1>&6
-echo "configure:10465: checking for setreuid" >&5
+echo "configure:10870: checking for setreuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10470,7 +10875,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETREUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10474 "configure"
+#line 10879 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -10478,7 +10883,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:10482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10887: \"$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
@@ -10503,7 +10908,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for seteuid""... $ac_c" 1>&6
-echo "configure:10507: checking for seteuid" >&5
+echo "configure:10912: checking for seteuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10512,7 +10917,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETEUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10516 "configure"
+#line 10921 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -10520,7 +10925,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:10524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10929: \"$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
@@ -10545,7 +10950,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for setuidx""... $ac_c" 1>&6
-echo "configure:10549: checking for setuidx" >&5
+echo "configure:10954: checking for setuidx" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10554,7 +10959,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETUIDX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10558 "configure"
+#line 10963 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -10562,7 +10967,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:10566: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10971: \"$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
@@ -10587,7 +10992,7 @@ fi
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:10591: checking for working mmap" >&5
+echo "configure:10996: 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
@@ -10596,11 +11001,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_MMAP=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10600 "configure"
+#line 11005 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/shared_mmap.c"
EOF
-if { (eval echo configure:10604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11009: \"$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
@@ -10623,7 +11028,7 @@ EOF
fi
echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6
-echo "configure:10627: checking for ftruncate needs root" >&5
+echo "configure:11032: 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
@@ -10632,11 +11037,11 @@ if test "$cross_compiling" = yes; then
samba_cv_FTRUNCATE_NEEDS_ROOT=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10636 "configure"
+#line 11041 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/ftruncroot.c"
EOF
-if { (eval echo configure:10640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11045: \"$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
@@ -10659,7 +11064,7 @@ EOF
fi
echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6
-echo "configure:10663: checking for fcntl locking" >&5
+echo "configure:11068: 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
@@ -10668,11 +11073,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_FCNTL_LOCK=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10672 "configure"
+#line 11077 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/fcntl_lock.c"
EOF
-if { (eval echo configure:10676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11081: \"$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
@@ -10695,7 +11100,7 @@ EOF
fi
echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6
-echo "configure:10699: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5
+echo "configure:11104: 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
@@ -10704,11 +11109,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10708 "configure"
+#line 11113 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/fcntl_lock64.c"
EOF
-if { (eval echo configure:10712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11117: \"$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
@@ -10733,7 +11138,7 @@ else
echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6
-echo "configure:10737: checking for 64 bit fcntl locking" >&5
+echo "configure:11142: 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
@@ -10742,7 +11147,7 @@ else
samba_cv_HAVE_STRUCT_FLOCK64=cross
else
cat > conftest.$ac_ext <<EOF
-#line 10746 "configure"
+#line 11151 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -10766,7 +11171,7 @@ exit(1);
#endif
}
EOF
-if { (eval echo configure:10770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11175: \"$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
@@ -10790,24 +11195,105 @@ EOF
fi
fi
+echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6
+echo "configure:11200: 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 <<EOF
+#line 11206 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+int main() {
+struct stat st; st.st_blocks = 0;
+; return 0; }
+EOF
+if { (eval echo configure:11215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ samba_cv_HAVE_STAT_ST_BLOCKS=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_HAVE_STAT_ST_BLOCKS=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_HAVE_STAT_ST_BLOCKS" 1>&6
+if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_STAT_ST_BLOCKS 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:11238: 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 <<EOF
+#line 11244 "configure"
+#include "confdefs.h"
+
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:11258: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" 1>&6
+if test x"$samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define BROKEN_REDHAT_7_SYSTEM_HEADERS 1
+EOF
+
+fi
+;;
+esac
+
echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6
-echo "configure:10795: checking for broken nisplus include files" >&5
+echo "configure:11281: 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 <<EOF
-#line 10801 "configure"
+#line 11287 "configure"
#include "confdefs.h"
#include <sys/acl.h>
#if defined(HAVE_RPCSVC_NIS_H)
#include <rpcsvc/nis.h>
#endif
int main() {
-return 0;
+int i;
; return 0; }
EOF
-if { (eval echo configure:10811: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:11297: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no
else
@@ -10831,7 +11317,7 @@ fi
#################################################
# check for smbwrapper support
echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6
-echo "configure:10835: checking whether to use smbwrapper" >&5
+echo "configure:11321: 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"
@@ -10875,7 +11361,7 @@ fi
#################################################
# check for the AFS filesystem
echo $ac_n "checking whether to use AFS""... $ac_c" 1>&6
-echo "configure:10879: checking whether to use AFS" >&5
+echo "configure:11365: checking whether to use AFS" >&5
# Check whether --with-afs or --without-afs was given.
if test "${with_afs+set}" = set; then
withval="$with_afs"
@@ -10901,7 +11387,7 @@ fi
#################################################
# check for the DFS auth system
echo $ac_n "checking whether to use DCE/DFS auth""... $ac_c" 1>&6
-echo "configure:10905: checking whether to use DCE/DFS auth" >&5
+echo "configure:11391: checking whether to use DCE/DFS auth" >&5
# Check whether --with-dfs or --without-dfs was given.
if test "${with_dfs+set}" = set; then
withval="$with_dfs"
@@ -10926,7 +11412,7 @@ fi
#################################################
# check for Kerberos IV auth system
echo $ac_n "checking whether to use Kerberos IV""... $ac_c" 1>&6
-echo "configure:10930: checking whether to use Kerberos IV" >&5
+echo "configure:11416: checking whether to use Kerberos IV" >&5
# Check whether --with-krb4 or --without-krb4 was given.
if test "${with_krb4+set}" = set; then
withval="$with_krb4"
@@ -10938,7 +11424,7 @@ if test "${with_krb4+set}" = set; then
EOF
echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6
-echo "configure:10942: checking for dn_expand in -lresolv" >&5
+echo "configure:11428: 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
@@ -10946,7 +11432,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 10950 "configure"
+#line 11436 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -10957,7 +11443,7 @@ int main() {
dn_expand()
; return 0; }
EOF
-if { (eval echo configure:10961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11447: \"$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
@@ -11001,7 +11487,7 @@ fi
#################################################
# check for Kerberos 5 auth system
echo $ac_n "checking whether to use Kerberos 5""... $ac_c" 1>&6
-echo "configure:11005: checking whether to use Kerberos 5" >&5
+echo "configure:11491: checking whether to use Kerberos 5" >&5
# Check whether --with-krb5 or --without-krb5 was given.
if test "${with_krb5+set}" = set; then
withval="$with_krb5"
@@ -11029,7 +11515,7 @@ fi
#################################################
# check for automount support
echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6
-echo "configure:11033: checking whether to use AUTOMOUNT" >&5
+echo "configure:11519: 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"
@@ -11054,7 +11540,7 @@ fi
#################################################
# check for smbmount support
echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6
-echo "configure:11058: checking whether to use SMBMOUNT" >&5
+echo "configure:11544: 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"
@@ -11091,7 +11577,7 @@ fi
# check for a PAM password database
with_pam_for_crypt=no
echo $ac_n "checking whether to use PAM password database""... $ac_c" 1>&6
-echo "configure:11095: checking whether to use PAM password database" >&5
+echo "configure:11581: checking whether to use PAM password database" >&5
# Check whether --with-pam or --without-pam was given.
if test "${with_pam+set}" = set; then
withval="$with_pam"
@@ -11117,7 +11603,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:11121: checking for pam_get_data in -lpam" >&5
+echo "configure:11607: 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
@@ -11125,7 +11611,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lpam $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 11129 "configure"
+#line 11615 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -11136,7 +11622,7 @@ int main() {
pam_get_data()
; return 0; }
EOF
-if { (eval echo configure:11140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11626: \"$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
@@ -11163,7 +11649,7 @@ fi
#################################################
# check for pam_smbpass support
echo $ac_n "checking whether to use pam_smbpass""... $ac_c" 1>&6
-echo "configure:11167: checking whether to use pam_smbpass" >&5
+echo "configure:11653: 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"
@@ -11205,12 +11691,12 @@ if test $with_pam_for_crypt = no; then
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:11209: checking for $ac_func" >&5
+echo "configure:11695: 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 <<EOF
-#line 11214 "configure"
+#line 11700 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -11233,7 +11719,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:11237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11723: \"$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
@@ -11259,7 +11745,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:11263: checking for crypt in -lcrypt" >&5
+echo "configure:11749: 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
@@ -11267,7 +11753,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 11271 "configure"
+#line 11757 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -11278,7 +11764,7 @@ int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:11282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:11768: \"$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
@@ -11313,7 +11799,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:11317: checking for a crypt that needs truncated salt" >&5
+echo "configure:11803: 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
@@ -11322,11 +11808,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_TRUNCATED_SALT=cross
else
cat > conftest.$ac_ext <<EOF
-#line 11326 "configure"
+#line 11812 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/crypttest.c"
EOF
-if { (eval echo configure:11330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:11816: \"$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
@@ -11364,7 +11850,7 @@ with_smbpasswd_sam=yes
#################################################
# check for a TDB password database
echo $ac_n "checking whether to use TDB SAM database""... $ac_c" 1>&6
-echo "configure:11368: checking whether to use TDB SAM database" >&5
+echo "configure:11854: 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"
@@ -11390,7 +11876,7 @@ fi
#################################################
# check for a LDAP password database
echo $ac_n "checking whether to use LDAP SAM database""... $ac_c" 1>&6
-echo "configure:11394: checking whether to use LDAP SAM database" >&5
+echo "configure:11880: checking whether to use LDAP SAM database" >&5
# Check whether --with-ldapsam or --without-ldapsam was given.
if test "${with_ldapsam+set}" = set; then
withval="$with_ldapsam"
@@ -11417,7 +11903,7 @@ fi
#################################################
# check for a NISPLUS password database
echo $ac_n "checking whether to use NISPLUS SAM database""... $ac_c" 1>&6
-echo "configure:11421: checking whether to use NISPLUS SAM database" >&5
+echo "configure:11907: 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"
@@ -11445,7 +11931,7 @@ fi
# smbpasswd SAM is only used if another format
# has not been defined
echo $ac_n "checking whether to use traditional smbpasswd file""... $ac_c" 1>&6
-echo "configure:11449: checking whether to use traditional smbpasswd file" >&5
+echo "configure:11935: checking whether to use traditional smbpasswd file" >&5
if test $with_smbpasswd_sam = yes; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
@@ -11467,7 +11953,7 @@ fi
#################################################
# check for a NISPLUS_HOME support
echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6
-echo "configure:11471: checking whether to use NISPLUS_HOME" >&5
+echo "configure:11957: 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"
@@ -11492,7 +11978,7 @@ fi
#################################################
# check for the secure socket layer
echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6
-echo "configure:11496: checking whether to use SSL" >&5
+echo "configure:11982: checking whether to use SSL" >&5
# Check whether --with-ssl or --without-ssl was given.
if test "${with_ssl+set}" = set; then
withval="$with_ssl"
@@ -11566,7 +12052,7 @@ fi
#################################################
# check for syslog logging
echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6
-echo "configure:11570: checking whether to use syslog logging" >&5
+echo "configure:12056: 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"
@@ -11591,7 +12077,7 @@ fi
#################################################
# check for a shared memory profiling support
echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6
-echo "configure:11595: checking whether to use profiling" >&5
+echo "configure:12081: 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"
@@ -11619,7 +12105,7 @@ fi
QUOTAOBJS=smbd/noquotas.o
echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6
-echo "configure:11623: checking whether to support disk-quotas" >&5
+echo "configure:12109: 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"
@@ -11631,13 +12117,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:11635: checking for linux 2.4.x quota braindamage.." >&5
+echo "configure:12121: 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 <<EOF
-#line 11641 "configure"
+#line 12127 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/types.h>
@@ -11649,7 +12135,7 @@ int main() {
struct mem_dqblk D;
; return 0; }
EOF
-if { (eval echo configure:11653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:12139: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_linux_2_4_quota_braindamage=yes
else
@@ -11693,7 +12179,7 @@ fi
# check for experimental utmp accounting
echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6
-echo "configure:11697: checking whether to support utmp accounting" >&5
+echo "configure:12183: 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"
@@ -11719,7 +12205,7 @@ fi
# check for MS Dfs support
echo $ac_n "checking whether to support Microsoft Dfs""... $ac_c" 1>&6
-echo "configure:11723: checking whether to support Microsoft Dfs" >&5
+echo "configure:12209: checking whether to support Microsoft Dfs" >&5
# Check whether --with-msdfs or --without-msdfs was given.
if test "${with_msdfs+set}" = set; then
withval="$with_msdfs"
@@ -11744,8 +12230,8 @@ fi
#################################################
# check for Samba VFS support
-echo $ac_n "checking whether to support the experimantal Samba vfs""... $ac_c" 1>&6
-echo "configure:11749: checking whether to support the experimantal Samba vfs" >&5
+echo $ac_n "checking whether to support the experimental Samba vfs""... $ac_c" 1>&6
+echo "configure:12235: checking whether to support the experimental Samba vfs" >&5
# Check whether --with-vfs or --without-vfs was given.
if test "${with_vfs+set}" = set; then
withval="$with_vfs"
@@ -11774,7 +12260,7 @@ fi
LIBSMBCLIENT_SHARED=
LIBSMBCLIENT=
echo $ac_n "checking whether to build the libsmbclient shared library""... $ac_c" 1>&6
-echo "configure:11778: checking whether to build the libsmbclient shared library" >&5
+echo "configure:12264: 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"
@@ -11801,14 +12287,14 @@ fi
#################################################
# these tests are taken from the GNU fileutils package
echo "checking how to get filesystem space usage" 1>&6
-echo "configure:11805: checking how to get filesystem space usage" >&5
+echo "configure:12291: 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:11812: checking statvfs64 function (SVR4)" >&5
+echo "configure:12298: 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
@@ -11816,7 +12302,7 @@ else
fu_cv_sys_stat_statvfs64=cross
else
cat > conftest.$ac_ext <<EOF
-#line 11820 "configure"
+#line 12306 "configure"
#include "confdefs.h"
#if defined(HAVE_UNISTD_H)
@@ -11830,7 +12316,7 @@ else
exit (statvfs64 (".", &fsd));
}
EOF
-if { (eval echo configure:11834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12320: \"$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
@@ -11863,12 +12349,12 @@ fi
if test $space = no; then
# SVR4
echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6
-echo "configure:11867: checking statvfs function (SVR4)" >&5
+echo "configure:12353: 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 <<EOF
-#line 11872 "configure"
+#line 12358 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -11876,7 +12362,7 @@ int main() {
struct statvfs fsd; statvfs (0, &fsd);
; return 0; }
EOF
-if { (eval echo configure:11880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12366: \"$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
@@ -11901,7 +12387,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:11905: checking for 3-argument statfs function (DEC OSF/1)" >&5
+echo "configure:12391: 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
@@ -11909,7 +12395,7 @@ else
fu_cv_sys_stat_statfs3_osf1=no
else
cat > conftest.$ac_ext <<EOF
-#line 11913 "configure"
+#line 12399 "configure"
#include "confdefs.h"
#include <sys/param.h>
@@ -11922,7 +12408,7 @@ else
exit (statfs (".", &fsd, sizeof (struct statfs)));
}
EOF
-if { (eval echo configure:11926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12412: \"$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
@@ -11949,7 +12435,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:11953: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
+echo "configure:12439: 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
@@ -11957,7 +12443,7 @@ else
fu_cv_sys_stat_statfs2_bsize=no
else
cat > conftest.$ac_ext <<EOF
-#line 11961 "configure"
+#line 12447 "configure"
#include "confdefs.h"
#ifdef HAVE_SYS_PARAM_H
@@ -11976,7 +12462,7 @@ else
exit (statfs (".", &fsd));
}
EOF
-if { (eval echo configure:11980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12466: \"$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
@@ -12003,7 +12489,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:12007: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
+echo "configure:12493: 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
@@ -12011,7 +12497,7 @@ else
fu_cv_sys_stat_statfs4=no
else
cat > conftest.$ac_ext <<EOF
-#line 12015 "configure"
+#line 12501 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/statfs.h>
@@ -12021,7 +12507,7 @@ else
exit (statfs (".", &fsd, sizeof fsd, 0));
}
EOF
-if { (eval echo configure:12025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12511: \"$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
@@ -12048,7 +12534,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:12052: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
+echo "configure:12538: 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
@@ -12056,7 +12542,7 @@ else
fu_cv_sys_stat_statfs2_fsize=no
else
cat > conftest.$ac_ext <<EOF
-#line 12060 "configure"
+#line 12546 "configure"
#include "confdefs.h"
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
@@ -12072,7 +12558,7 @@ else
exit (statfs (".", &fsd));
}
EOF
-if { (eval echo configure:12076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12562: \"$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
@@ -12099,7 +12585,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:12103: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
+echo "configure:12589: 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
@@ -12107,7 +12593,7 @@ else
fu_cv_sys_stat_fs_data=no
else
cat > conftest.$ac_ext <<EOF
-#line 12111 "configure"
+#line 12597 "configure"
#include "confdefs.h"
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
@@ -12127,7 +12613,7 @@ else
exit (statfs (".", &fsd) != 1);
}
EOF
-if { (eval echo configure:12131: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12617: \"$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
@@ -12159,10 +12645,10 @@ fi
# If we don't have all of these then disable large
# file support.
#
-echo $ac_n "checking checking if large file support can be enabled""... $ac_c" 1>&6
-echo "configure:12164: checking checking if large file support can be enabled" >&5
+echo $ac_n "checking if large file support can be enabled""... $ac_c" 1>&6
+echo "configure:12650: checking if large file support can be enabled" >&5
cat > conftest.$ac_ext <<EOF
-#line 12166 "configure"
+#line 12652 "configure"
#include "confdefs.h"
#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
@@ -12175,7 +12661,7 @@ int main() {
int i
; return 0; }
EOF
-if { (eval echo configure:12179: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:12665: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes
else
@@ -12242,7 +12728,7 @@ fi
# check for ACL support
echo $ac_n "checking whether to support ACLs""... $ac_c" 1>&6
-echo "configure:12246: checking whether to support ACLs" >&5
+echo "configure:12732: 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"
@@ -12264,6 +12750,13 @@ EOF
EOF
;;
+ *hpux*)
+ echo "$ac_t""Using HPUX ACLs" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_HPUX_ACLS 1
+EOF
+
+ ;;
*irix*)
echo "$ac_t""Using IRIX ACLs" 1>&6
cat >> confdefs.h <<\EOF
@@ -12288,7 +12781,7 @@ EOF
;;
*)
echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6
-echo "configure:12292: checking for acl_get_file in -lacl" >&5
+echo "configure:12785: 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
@@ -12296,7 +12789,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lacl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 12300 "configure"
+#line 12793 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -12307,7 +12800,7 @@ int main() {
acl_get_file()
; return 0; }
EOF
-if { (eval echo configure:12311: \"$ac_link\") 1>&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_lib_$ac_lib_var=yes"
else
@@ -12335,13 +12828,13 @@ else
fi
echo $ac_n "checking for ACL support""... $ac_c" 1>&6
-echo "configure:12339: checking for ACL support" >&5
+echo "configure:12832: 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 <<EOF
-#line 12345 "configure"
+#line 12838 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/acl.h>
@@ -12349,7 +12842,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:12353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12846: \"$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
@@ -12369,13 +12862,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:12373: checking for acl_get_perm_np" >&5
+echo "configure:12866: 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 <<EOF
-#line 12379 "configure"
+#line 12872 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/acl.h>
@@ -12383,7 +12876,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:12387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12880: \"$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
@@ -12438,12 +12931,12 @@ fi
# (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS).
echo $ac_n "checking whether to build winbind""... $ac_c" 1>&6
-echo "configure:12442: checking whether to build winbind" >&5
+echo "configure:12935: checking whether to build winbind" >&5
# Initially, the value of $host_os decides whether winbind is supported
case "$host_os" in
- *linux*|*solaris*)
+ *linux*|*solaris*|*irix*)
HAVE_WINBIND=yes
;;
*)
@@ -12517,11 +13010,11 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 12521 "configure"
+#line 13014 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/summary.c"
EOF
-if { (eval echo configure:12525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "configure OK";
else
@@ -12679,6 +13172,7 @@ s%@swatdir@%$swatdir%g
s%@RUNPROG@%$RUNPROG%g
s%@MPROGS@%$MPROGS%g
s%@LDSHFLAGS@%$LDSHFLAGS%g
+s%@SONAMEFLAG@%$SONAMEFLAG%g
s%@SHLD@%$SHLD%g
s%@HOST_OS@%$HOST_OS%g
s%@PAM_MOD@%$PAM_MOD%g
@@ -12942,4 +13436,3 @@ chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/source/configure.in b/source/configure.in
index 657819cccc9..fe53556cef3 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -103,6 +103,21 @@ AC_ARG_WITH(codepagedir,
;;
esac])
+#################################################
+# set log directory location
+AC_ARG_WITH(logfilebase,
+[ --with-logfilebase=DIR Where to put log files (\$(VARDIR))],
+[ case "$withval" in
+ yes|no)
+ #
+ # Just in case anybody does it
+ #
+ AC_MSG_WARN([--with-logfilebase called without argument - will use default])
+ ;;
+ * )
+ logfilebase="$withval"
+ ;;
+ esac])
AC_SUBST(codepagedir)
AC_SUBST(configdir)
@@ -118,6 +133,7 @@ AC_SUBST(SHELL)
AC_SUBST(RUNPROG)
AC_SUBST(MPROGS)
AC_SUBST(LDSHFLAGS)
+AC_SUBST(SONAMEFLAG)
AC_SUBST(SHLD)
AC_SUBST(HOST_OS)
AC_SUBST(PAM_MOD)
@@ -196,15 +212,24 @@ case "$host_os" in
#
case `uname -r` in
*9*|*10*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
+ CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4"
AC_DEFINE(USE_BOTH_CRYPT_CALLS)
;;
*11*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
+ CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE -D_ALIGNMENT_REQUIRED=1 -D_MAX_ALIGNMENT=4"
AC_DEFINE(USE_BOTH_CRYPT_CALLS)
;;
esac
;;
+
+
+#
+# CRAY Unicos has broken const handling
+ *unicos*)
+ AC_MSG_RESULT([disabling const])
+ CPPFLAGS="$CPPFLAGS -Dconst="
+ ;;
+
#
# AIX4.x doesn't even admit to having large
# files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
@@ -356,7 +381,7 @@ AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/i
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
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)
+AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h synch.h pthread.h)
#
# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
@@ -372,7 +397,7 @@ case "$host_os" in
;;
esac
AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
-AC_CHECK_HEADERS(nss.h nss_common.h sys/security.h security/pam_appl.h security/pam_modules.h)
+AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
@@ -383,6 +408,9 @@ AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h)
# For quotas on Veritas VxFS filesystems
AC_CHECK_HEADERS(sys/fs/vx_quota.h)
+# For quotas on Linux XFS filesystems
+AC_CHECK_HEADERS(linux/xqm.h)
+
AC_CHECK_SIZEOF(int,cross)
AC_CHECK_SIZEOF(long,cross)
AC_CHECK_SIZEOF(short,cross)
@@ -428,6 +456,21 @@ AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl";
AC_DEFINE(HAVE_LIBDL)])
############################################
+# check if the compiler can do immediate structures
+AC_CACHE_CHECK([for immediate structures],samba_cv_immediate_structures, [
+ AC_TRY_COMPILE([
+#include <stdio.h>],
+[
+ #define X_FOOBAR(x) ((FOOBAR) { x })
+ typedef struct {unsigned x;} FOOBAR;
+ FOOBAR f = X_FOOBAR(1);
+],
+ samba_cv_immediate_structures=yes,samba_cv_immediate_structures=no)])
+if test x"$samba_cv_immediate_structures" = x"yes"; then
+ AC_DEFINE(HAVE_IMMEDIATE_STRUCTURES)
+fi
+
+############################################
# check for unix domain sockets
AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [
AC_TRY_COMPILE([
@@ -615,15 +658,16 @@ else
RUNPROG=""
fi
-AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot)
-AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset)
+AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown fchown chmod fchmod chroot link)
+AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset setpgid mknod mknod64)
AC_CHECK_FUNCS(memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid)
AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent)
-AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf)
+AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf realpath)
AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64)
AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf)
AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink)
+AC_CHECK_FUNCS(syslog vsyslog)
# syscall() is needed for smbwrapper.
AC_CHECK_FUNCS(syscall)
@@ -731,12 +775,14 @@ AC_LIBTESTFUNC(sec, getprpwnam)
# these are the defaults, good for lots of systems
HOST_OS="$host_os"
LDSHFLAGS="-shared"
+SONAMEFLAG="#"
SHLD="\${CC}"
PICFLAG=""
PICSUFFIX="po.o"
SHLIBEXT="so"
# Assume non-shared by default and override below
BLDSHARED="false"
+AC_MSG_CHECKING([ability to build shared libraries])
# and these are for particular systems
case "$host_os" in
@@ -744,12 +790,30 @@ case "$host_os" in
BLDSHARED="true"
LDSHFLAGS="-shared"
PICFLAG="-fPIC"
- ;;
+ SONAMEFLAG="-Wl,-soname="
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ ;;
*solaris*) AC_DEFINE(SUNOS5)
- ;;
+ BLDSHARED="true"
+ LDSHFLAGS="-h \$@ -G"
+ if test "${ac_cv_prog_CC}" = "gcc"; then
+ PICFLAG="-fPIC"
+ else
+ PICFLAG="-KPIC"
+ POBAD_CC=""
+ PICSUFFIX="po.o"
+ fi
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
+ ;;
*sunos*) AC_DEFINE(SUNOS4)
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-h,\$@ -G"
+ PICFLAG="-KPIC" # Is this correct for SunOS
;;
- *bsd*) LDSHFLAGS="-shared -Bshareable"
+ *bsd*) BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-fPIC"
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*irix*) AC_DEFINE(IRIX)
case "$host_os" in
@@ -757,21 +821,44 @@ case "$host_os" in
;;
esac
ATTEMPT_WRAP32_BUILD=yes
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ if test "${ac_cv_prog_CC}" = "gcc"; then
+ PICFLAG="-fPIC"
+ else
+ PICFLAG="-KPIC"
+ fi
+ AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*aix*) AC_DEFINE(AIX)
- # AIX is too ugly for now
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry"
+ PICFLAG="-O2 -qmaxmem=6000"
+ AC_DEFINE(STAT_ST_BLOCKSIZE,DEV_BSIZE)
;;
*hpux*) AC_DEFINE(HPUX)
SHLIBEXT="sl"
# Use special PIC flags for the native HP-UX compiler.
if test $ac_cv_prog_cc_Ae = yes; then
- LDSHFLAGS="-b"
+ BLDSHARED="true"
+ SHLD="/usr/bin/ld"
+ LDSHFLAGS="-B symbolic -b -z +h \$@"
PICFLAG="+z"
fi
- ;;
+ AC_DEFINE(STAT_ST_BLOCKSIZE,8192)
+ ;;
*qnx*) AC_DEFINE(QNX);;
- *osf*) AC_DEFINE(OSF1);;
+ *osf*) AC_DEFINE(OSF1)
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-fPIC"
+ ;;
*sco*) AC_DEFINE(SCO);;
+ *unixware*) AC_DEFINE(UNIXWARE)
+ BLDSHARED="true"
+ LDSHFLAGS="-Wl,-soname,\$@ -shared"
+ PICFLAG="-KPIC"
+ ;;
*next2*) AC_DEFINE(NEXT2);;
*dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man]);;
*sysv4*)
@@ -791,6 +878,11 @@ case "$host_os" in
LDSHFLAGS="-G"
;;
esac
+AC_MSG_RESULT($BLDSHARED)
+AC_MSG_CHECKING([linker flags for shared libraries])
+AC_MSG_RESULT([$LDSHFLAGS])
+AC_MSG_CHECKING([compiler flags for position-independent code])
+AC_MSG_RESULT([$PICFLAGS])
# try to work out how to produce pic code with this compiler
AC_PROG_CC_FLAG(fpic)
@@ -876,6 +968,19 @@ if test x"$samba_cv_HAVE_INO64_T" = x"yes"; then
AC_DEFINE(HAVE_INO64_T)
fi
+AC_CACHE_CHECK([for dev64_t],samba_cv_HAVE_DEV64_T,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <sys/stat.h>
+main() { struct stat64 st; dev64_t s; if (sizeof(dev_t) == sizeof(dev64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
+samba_cv_HAVE_DEV64_T=yes,samba_cv_HAVE_DEV64_T=no,samba_cv_HAVE_DEV64_T=cross)])
+if test x"$samba_cv_HAVE_DEV64_T" = x"yes"; then
+ AC_DEFINE(HAVE_DEV64_T)
+fi
+
AC_CACHE_CHECK([for struct dirent64],samba_cv_HAVE_STRUCT_DIRENT64,[
AC_TRY_COMPILE([
#if defined(HAVE_UNISTD_H)
@@ -889,6 +994,42 @@ if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes"; then
AC_DEFINE(HAVE_STRUCT_DIRENT64)
fi
+AC_CACHE_CHECK([for major macro],samba_cv_HAVE_DEVICE_MAJOR_FN,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev; int i = major(dev); return 0; }],
+samba_cv_HAVE_DEVICE_MAJOR_FN=yes,samba_cv_HAVE_DEVICE_MAJOR_FN=no,samba_cv_HAVE_DEVICE_MAJOR_FN=cross)])
+if test x"$samba_cv_HAVE_DEVICE_MAJOR_FN" = x"yes"; then
+ AC_DEFINE(HAVE_DEVICE_MAJOR_FN)
+fi
+
+AC_CACHE_CHECK([for minor macro],samba_cv_HAVE_DEVICE_MINOR_FN,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev; int i = minor(dev); return 0; }],
+samba_cv_HAVE_DEVICE_MINOR_FN=yes,samba_cv_HAVE_DEVICE_MINOR_FN=no,samba_cv_HAVE_DEVICE_MINOR_FN=cross)])
+if test x"$samba_cv_HAVE_DEVICE_MINOR_FN" = x"yes"; then
+ AC_DEFINE(HAVE_DEVICE_MINOR_FN)
+fi
+
+AC_CACHE_CHECK([for makedev macro],samba_cv_HAVE_MAKEDEV_FN,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev = makedev(1,2); return 0; }],
+samba_cv_HAVE_MAKEDEV_FN=yes,samba_cv_HAVE_MAKEDEV_FN=no,samba_cv_HAVE_MAKEDEV_FN=cross)])
+if test x"$samba_cv_HAVE_MAKEDEV_FN" = x"yes"; then
+ AC_DEFINE(MAKEDEV_FN)
+fi
+
AC_CACHE_CHECK([for unsigned char],samba_cv_HAVE_UNSIGNED_CHAR,[
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
@@ -1509,12 +1650,40 @@ exit(1);
fi
fi
+AC_CACHE_CHECK([for st_blocks in struct stat],samba_cv_HAVE_STAT_ST_BLOCKS,[
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>],
+[struct stat st; st.st_blocks = 0;],
+samba_cv_HAVE_STAT_ST_BLOCKS=yes,samba_cv_HAVE_STAT_ST_BLOCKS=no,samba_cv_HAVE_STAT_ST_BLOCKS=cross)])
+if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then
+ AC_DEFINE(HAVE_STAT_ST_BLOCKS)
+fi
+
+case "$host_os" in
+*linux*)
+AC_CACHE_CHECK([for broken RedHat 7.2 system header files],samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[
+AC_TRY_COMPILE([
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif
+],[int i;],
+ samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no,samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes)])
+if test x"$samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then
+ AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS)
+fi
+;;
+esac
+
AC_CACHE_CHECK([for broken nisplus include files],samba_cv_BROKEN_NISPLUS_INCLUDE_FILES,[
AC_TRY_COMPILE([#include <sys/acl.h>
#if defined(HAVE_RPCSVC_NIS_H)
#include <rpcsvc/nis.h>
#endif],
-[return 0;],
+[int i;],
samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no,samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes)])
if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
AC_DEFINE(BROKEN_NISPLUS_INCLUDE_FILES)
@@ -2043,7 +2212,7 @@ AC_ARG_WITH(msdfs,
#################################################
# check for Samba VFS support
-AC_MSG_CHECKING(whether to support the experimantal Samba vfs)
+AC_MSG_CHECKING(whether to support the experimental Samba vfs)
AC_ARG_WITH(vfs,
[ --with-vfs Include Samba vfs support (default=no)],
[ case "$withval" in
@@ -2276,7 +2445,7 @@ fi
# If we don't have all of these then disable large
# file support.
#
-AC_MSG_CHECKING(checking if large file support can be enabled)
+AC_MSG_CHECKING(if large file support can be enabled)
AC_TRY_COMPILE([
#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
#include <sys/types.h>
@@ -2335,6 +2504,10 @@ AC_ARG_WITH(acl-support,
AC_MSG_RESULT(Using solaris ACLs)
AC_DEFINE(HAVE_SOLARIS_ACLS)
;;
+ *hpux*)
+ AC_MSG_RESULT(Using HPUX ACLs)
+ AC_DEFINE(HAVE_HPUX_ACLS)
+ ;;
*irix*)
AC_MSG_RESULT(Using IRIX ACLs)
AC_DEFINE(HAVE_IRIX_ACLS)
@@ -2397,7 +2570,7 @@ AC_MSG_CHECKING(whether to build winbind)
# Initially, the value of $host_os decides whether winbind is supported
case "$host_os" in
- *linux*|*solaris*)
+ *linux*|*solaris*|*irix*)
HAVE_WINBIND=yes
;;
*)
diff --git a/source/groupdb/aliasdb.c b/source/groupdb/aliasdb.c
index 536b4576bb1..33b9fcc37f5 100644
--- a/source/groupdb/aliasdb.c
+++ b/source/groupdb/aliasdb.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern fstring global_sam_name;
/*
diff --git a/source/groupdb/aliasfile.c b/source/groupdb/aliasfile.c
index 2fb5a86a800..0844a420a0a 100644
--- a/source/groupdb/aliasfile.c
+++ b/source/groupdb/aliasfile.c
@@ -22,7 +22,6 @@
#ifdef USE_SMBPASS_DB
static int al_file_lock_depth = 0;
-extern int DEBUGLEVEL;
static char s_readbuf[1024];
diff --git a/source/groupdb/groupdb.c b/source/groupdb/groupdb.c
index 15d15667bd6..3bbc8f66d7c 100644
--- a/source/groupdb/groupdb.c
+++ b/source/groupdb/groupdb.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
* NOTE. All these functions are abstracted into a structure
* that points to the correct function for the selected database. JRA.
diff --git a/source/groupdb/groupfile.c b/source/groupdb/groupfile.c
index 322bbcef7b7..7f3cec5c180 100644
--- a/source/groupdb/groupfile.c
+++ b/source/groupdb/groupfile.c
@@ -22,7 +22,6 @@
#ifdef USE_SMBPASS_DB
static int gp_file_lock_depth = 0;
-extern int DEBUGLEVEL;
static char s_readbuf[1024];
diff --git a/source/include/.cvsignore b/source/include/.cvsignore
index b423e995198..1a8ab03528d 100644
--- a/source/include/.cvsignore
+++ b/source/include/.cvsignore
@@ -1,2 +1,3 @@
+build_env.h
config.h
stamp-h
diff --git a/source/include/byteorder.h b/source/include/byteorder.h
index e6cce73cebf..fab77060be0 100644
--- a/source/include/byteorder.h
+++ b/source/include/byteorder.h
@@ -106,23 +106,25 @@ it also defines lots of intermediate macros, just ignore those :-)
#define CAREFUL_ALIGNMENT 1
#endif
-#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
-#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
-#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
+#define CVAL(buf,pos) (((const unsigned char *)(buf))[pos])
+#define CVAL_NC(buf,pos) (((unsigned char *)(buf))[pos]) /* Non-const version of CVAL */
+#define PVAL(buf,pos) ((const unsigned)CVAL(buf,pos))
+#define PVAL_NC(buf,pos) ((unsigned)CVAL(buf,pos)) /* Non const version of PVAL */
+#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
#if CAREFUL_ALIGNMENT
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
-#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
+#define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(val)&0xFF,CVAL_NC(buf,pos+1)=(val)>>8)
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
-#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
-#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
-#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
-#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
-#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
-#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
+#define SVALS(buf,pos) ((const int16)SVAL(buf,pos))
+#define IVALS(buf,pos) ((const int32)IVAL(buf,pos))
+#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((const uint16)(val)))
+#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((const uint32)(val)))
+#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((const int16)(val)))
+#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((const int32)(val)))
#else /* CAREFUL_ALIGNMENT */
@@ -134,16 +136,20 @@ it also defines lots of intermediate macros, just ignore those :-)
*/
/* get single value from an SMB buffer */
-#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
-#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
-#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
-#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+#define SVAL(buf,pos) (*(const uint16 *)((const char *)(buf) + (pos)))
+#define SVAL_NC(buf,pos) (*(uint16 *)((char *)(buf) + (pos))) /* Non const version of above. */
+#define IVAL(buf,pos) (*(const uint32 *)((const char *)(buf) + (pos)))
+#define IVAL_NC(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) /* Non const version of above. */
+#define SVALS(buf,pos) (*(const int16 *)((const char *)(buf) + (pos)))
+#define SVALS_NC(buf,pos) (*(int16 *)((char *)(buf) + (pos))) /* Non const version of above. */
+#define IVALS(buf,pos) (*(const int32 *)((const char *)(buf) + (pos)))
+#define IVALS_NC(buf,pos) (*(int32 *)((char *)(buf) + (pos))) /* Non const version of above. */
/* store single value in an SMB buffer */
-#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
-#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
-#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
-#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
+#define SSVAL(buf,pos,val) SVAL_NC(buf,pos)=((const uint16)(val))
+#define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((const uint32)(val))
+#define SSVALS(buf,pos,val) SVALS_NC(buf,pos)=((const int16)(val))
+#define SIVALS(buf,pos,val) IVALS_NC(buf,pos)=((const int32)(val))
#endif /* CAREFUL_ALIGNMENT */
diff --git a/source/include/charset.h b/source/include/charset.h
index 7c6fbe5509b..5a683e09683 100644
--- a/source/include/charset.h
+++ b/source/include/charset.h
@@ -54,11 +54,11 @@ extern void charset_initialise(void);
#undef isspace
#endif
-#define toupper(c) (upper_char_map[(c&0xff)] & 0xff)
-#define tolower(c) (lower_char_map[(c&0xff)] & 0xff)
-#define isupper(c) ((c&0xff) != tolower(c&0xff))
-#define islower(c) ((c&0xff) != toupper(c&0xff))
-#define isdoschar(c) (dos_char_map[(c&0xff)] != 0)
+#define toupper(c) (upper_char_map[((c)&0xff)] & 0xff)
+#define tolower(c) (lower_char_map[((c)&0xff)] & 0xff)
+#define isupper(c) (((c)&0xff) != tolower((c)&0xff))
+#define islower(c) (((c)&0xff) != toupper((c)&0xff))
+#define isdoschar(c) (dos_char_map[((c)&0xff)] != 0)
#define isspace(c) ((c)==' ' || (c) == '\t')
/* this is used to determine if a character is safe to use in
diff --git a/source/include/client.h b/source/include/client.h
index ae7229b516c..cb601c9335f 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -44,7 +44,7 @@ typedef struct file_info
time_t atime;
time_t ctime;
pstring name;
- char short_name[13];
+ char short_name[13*3]; /* the *3 is to cope with multi-byte */
} file_info;
struct print_job_info
@@ -131,6 +131,15 @@ struct cli_state {
BOOL use_oplocks; /* should we use oplocks? */
BOOL use_level_II_oplocks; /* should we use level II oplocks? */
+
+ /* a oplock break request handler */
+ BOOL (*oplock_handler)(struct cli_state *cli, int fnum, unsigned char level);
+
+ BOOL force_dos_errors;
+
+ /* was this structure allocated by cli_initialise? If so, then
+ free in cli_shutdown() */
+ BOOL allocated;
};
#endif /* _CLIENT_H */
diff --git a/source/include/clitar.h b/source/include/clitar.h
index 2305fceeec7..ad76191fb75 100644
--- a/source/include/clitar.h
+++ b/source/include/clitar.h
@@ -1,3 +1,26 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 3.0
+ * clitar file format
+ * Copyright (C) Andrew Tridgell 2000
+ *
+ * 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 (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _CLITAR_H
+#define _CLITAR_H
#define TBLOCK 512
#define NAMSIZ 100
@@ -15,3 +38,5 @@ union hblock {
char linkname[NAMSIZ];
} dbuf;
};
+
+#endif /* _CLITAR_H */
diff --git a/source/include/config.h.in b/source/include/config.h.in
index 43e166d82e5..803c2a6ca0e 100644
--- a/source/include/config.h.in
+++ b/source/include/config.h.in
@@ -142,6 +142,7 @@
#undef WITH_MSDFS
#undef WITH_VFS
#undef HAVE_INO64_T
+#undef HAVE_DEV64_T
#undef HAVE_STRUCT_FLOCK64
#undef SIZEOF_INO_T
#undef SIZEOF_OFF_T
@@ -209,6 +210,7 @@
#undef HAVE_ACL_GET_PERM_NP
#undef HAVE_UNIXWARE_ACLS
#undef HAVE_SOLARIS_ACLS
+#undef HAVE_HPUX_ACLS
#undef HAVE_IRIX_ACLS
#undef HAVE_AIX_ACLS
#undef HAVE_TRU64_ACLS
@@ -227,6 +229,13 @@
#undef WITH_TDB_SAM
#undef LINUX_QUOTAS_1
#undef LINUX_QUOTAS_2
+#undef BROKEN_REDHAT_7_SYSTEM_HEADERS
+#undef HAVE_IMMEDIATE_STRUCTURES
+#undef HAVE_STAT_ST_BLOCKS
+#undef STAT_ST_BLOCKSIZE
+#undef HAVE_DEVICE_MAJOR_FN
+#undef HAVE_DEVICE_MINOR_FN
+#undef HAVE_MAKEDEV_FN
/* The number of bytes in a int. */
#undef SIZEOF_INT
@@ -576,6 +585,9 @@
/* Define if you have the innetgr function. */
#undef HAVE_INNETGR
+/* Define if you have the link function. */
+#undef HAVE_LINK
+
/* Define if you have the llseek function. */
#undef HAVE_LLSEEK
@@ -591,6 +603,12 @@
/* Define if you have the memset function. */
#undef HAVE_MEMSET
+/* Define if you have the mknod function. */
+#undef HAVE_MKNOD
+
+/* Define if you have the mknod64 function. */
+#undef HAVE_MKNOD64
+
/* Define if you have the mktime function. */
#undef HAVE_MKTIME
@@ -642,6 +660,9 @@
/* Define if you have the readlink function. */
#undef HAVE_READLINK
+/* Define if you have the realpath function. */
+#undef HAVE_REALPATH
+
/* Define if you have the rename function. */
#undef HAVE_RENAME
@@ -669,6 +690,9 @@
/* Define if you have the setnetgrent function. */
#undef HAVE_SETNETGRENT
+/* Define if you have the setpgid function. */
+#undef HAVE_SETPGID
+
/* Define if you have the setpriv function. */
#undef HAVE_SETPRIV
@@ -732,6 +756,9 @@
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
+/* Define if you have the syslog function. */
+#undef HAVE_SYSLOG
+
/* Define if you have the updwtmp function. */
#undef HAVE_UPDWTMP
@@ -753,6 +780,9 @@
/* Define if you have the vsnprintf function. */
#undef HAVE_VSNPRINTF
+/* Define if you have the vsyslog function. */
+#undef HAVE_VSYSLOG
+
/* Define if you have the waitpid function. */
#undef HAVE_WAITPID
@@ -795,6 +825,9 @@
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define if you have the <linux/xqm.h> header file. */
+#undef HAVE_LINUX_XQM_H
+
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@@ -816,6 +849,9 @@
/* Define if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
+/* Define if you have the <ns_api.h> header file. */
+#undef HAVE_NS_API_H
+
/* Define if you have the <nss.h> header file. */
#undef HAVE_NSS_H
@@ -825,6 +861,9 @@
/* Define if you have the <poll.h> header file. */
#undef HAVE_POLL_H
+/* Define if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
/* Define if you have the <readline.h> header file. */
#undef HAVE_READLINE_H
@@ -873,6 +912,9 @@
/* Define if you have the <stropts.h> header file. */
#undef HAVE_STROPTS_H
+/* Define if you have the <synch.h> header file. */
+#undef HAVE_SYNCH_H
+
/* Define if you have the <sys/acl.h> header file. */
#undef HAVE_SYS_ACL_H
diff --git a/source/include/doserr.h b/source/include/doserr.h
index 827582ae19e..a2c53791cc8 100644
--- a/source/include/doserr.h
+++ b/source/include/doserr.h
@@ -1,7 +1,7 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
- SMB parameters and setup
+ DOS error code constants
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) John H Terpstra 1996-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
@@ -51,9 +51,11 @@
#define ERRremcd 16 /* Attempt to delete current directory */
#define ERRdiffdevice 17 /* rename/move across different filesystems */
#define ERRnofiles 18 /* no more files found in file search */
+#define ERRgeneral 31 /* General failure */
#define ERRbadshare 32 /* Share mode on file conflict with open mode */
#define ERRlock 33 /* Lock request conflicts with existing lock */
#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
+#define ERRnetnamedel 64 /* Network name deleted or not available */
#define ERRnosuchshare 67 /* You specified an invalid share name */
#define ERRfilexists 80 /* File in operation already exists */
#define ERRinvalidparam 87
@@ -71,9 +73,11 @@
#define ERRnomoreitems 259
#define ERRbaddirectory 267 /* Invalid directory name in a path. */
#define ERReasnotsupported 282 /* Extended attributes */
+#define ERRlogonfailure 1326 /* Unknown username or bad password */
#define ERRbuftoosmall 2123
#define ERRunknownipc 2142
#define ERRnosuchprintjob 2151
+#define ERRinvgroup 2455
/* here's a special one from observing NT */
#define ERRnoipc 66 /* don't support ipc */
@@ -82,6 +86,7 @@
#define ERRunknownprinterdriver 1797 /* ERROR_UNKNOWN_PRINTER_DRIVER */
#define ERRinvalidprintername 1801 /* ERROR_INVALID_PRINTER_NAME */
+#define ERRprinteralreadyexists 1802 /* ERROR_PRINTER_ALREADY_EXISTS */
#define ERRinvaliddatatype 1804 /* ERROR_INVALID_DATATYPE */
#define ERRinvalidenvironment 1805 /* ERROR_INVALID_ENVIRONMENT */
#define ERRprinterdriverinuse 3001 /* ERROR_PRINTER_DRIVER_IN_USE */
@@ -140,4 +145,47 @@
#define ERRsharebufexc 36 /* share buffer exceeded */
#define ERRdiskfull 39
+
+/* 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_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_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_NAME W_ERROR(123)
+#define WERR_UNKNOWN_LEVEL W_ERROR(124)
+#define WERR_NO_MORE_ITEMS W_ERROR(259)
+#define WERR_MORE_DATA W_ERROR(234)
+#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(1797)
+#define WERR_INVALID_PRINTER_NAME W_ERROR(1801)
+#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(1802)
+#define WERR_INVALID_DATATYPE W_ERROR(1804)
+#define WERR_INVALID_ENVIRONMENT W_ERROR(1805)
+#define WERR_BUF_TOO_SMALL W_ERROR(2123)
+#define WERR_JOB_NOT_FOUND W_ERROR(2151)
+#define WERR_DEST_NOT_FOUND W_ERROR(2152)
+#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320)
+#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(3001)
+#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105)
+
+/* DFS errors */
+
+#ifndef NERR_BASE
+#define NERR_BASE (2100)
+#endif
+
+#define WERR_DFS_NO_SUCH_VOL W_ERROR(NERR_BASE+562)
+#define WERR_DFS_NO_SUCH_SHARE W_ERROR(NERR_BASE+565)
+#define WERR_DFS_NO_SUCH_SERVER W_ERROR(NERR_BASE+573)
+#define WERR_DFS_INTERNAL_ERROR W_ERROR(NERR_BASE+590)
+#define WERR_DFS_CANT_CREATE_JUNCT W_ERROR(NERR_BASE+569)
+
#endif /* _DOSERR_H */
diff --git a/source/include/includes.h b/source/include/includes.h
index 09e6bcf9eee..d19862cf124 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -327,7 +327,19 @@
#endif
#ifdef HAVE_SYS_CAPABILITY_H
+
+#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H)
+#define _I386_STATFS_H
+#define BROKEN_REDHAT_7_STATFS_WORKAROUND
+#endif
+
#include <sys/capability.h>
+
+#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
+#undef _I386_STATFS_H
+#undef BROKEN_REDHAT_7_STATFS_WORKAROUND
+#endif
+
#endif
#if defined(HAVE_RPC_RPC_H)
@@ -463,7 +475,11 @@ typedef int socklen_t;
*/
#ifndef SMB_DEV_T
-#define SMB_DEV_T dev_t
+# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_DEV64_T)
+# define SMB_DEV_T dev64_t
+# else
+# define SMB_DEV_T dev_t
+# endif
#endif
/*
@@ -667,6 +683,8 @@ extern int errno;
#include "mapping.h"
+#include "rap.h"
+
#ifndef MAXCODEPAGELINES
#define MAXCODEPAGELINES 256
#endif
diff --git a/source/include/interfaces.h b/source/include/interfaces.h
index ae5905e682e..3b786f1ebcb 100644
--- a/source/include/interfaces.h
+++ b/source/include/interfaces.h
@@ -3,6 +3,8 @@
interfaces on the machine
*/
+#define MAX_INTERFACES 128
+
struct iface_struct {
char name[16];
struct in_addr ip;
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index 54660c48535..98701b2693e 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -1,25 +1,25 @@
/*=====================================================================
- Unix SMB/Netbios implementation.
- Version 2.0
- SMB client library API definitions
- Copyright (C) Andrew Tridgell 1998
- Copyright (C) Richard Sharpe 2000
- Copyright (C) John Terpsra 2000
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ SMB client library API definitions
+ Copyright (C) Andrew Tridgell 1998
+ Copyright (C) Richard Sharpe 2000
+ Copyright (C) John Terpsra 2000
- 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
- (at your option) any later version.
+ 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
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-=====================================================================*/
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ =====================================================================*/
#ifndef SMBCLIENT_H_INCLUDED
#define SMBCLIENT_H_INCLUDED
@@ -28,22 +28,30 @@
/* The following are special comments to instruct DOXYGEN (automated
* documentation tool:
*/
+/** \defgroup libsmbclient
+*/
/** \defgroup structure Data Structures Type and Constants
+* \ingroup libsmbclient
* Data structures, types, and constants
*/
/** \defgroup file File Functions
+* \ingroup libsmbclient
* Functions used to access individual file contents
*/
/** \defgroup directory Directory Functions
+* \ingroup libsmbclient
* Functions used to access directory entries
*/
/** \defgroup attribute Attributes Functions
+* \ingroup libsmbclient
* Functions used to view or change file and directory attributes
*/
/** \defgroup print Print Functions
+* \ingroup libsmbclient
* Functions used to access printing functionality
*/
/** \defgroup attribute Miscellaneous Functions
+* \ingroup libsmbclient
* Functions that don't fit in to other categories
*/
/*-------------------------------------------------------------------*/
@@ -67,41 +75,44 @@
#define SMBC_FILE_MODE (S_IFREG | 0444)
#define SMBC_DIR_MODE (S_IFDIR | 0555)
+#define SMBC_MAX_FD 10000
+
+
/**@ingroup structure
* Structure that represents a directory entry.
*
-*/
+ */
struct smbc_dirent
{
- /** Type of entity.
- SMBC_WORKGROUP=1,
- SMBC_SERVER=2,
- SMBC_FILE_SHARE=3,
- SMBC_PRINTER_SHARE=4,
- SMBC_COMMS_SHARE=5,
- SMBC_IPC_SHARE=6,
- SMBC_DIR=7,
- SMBC_FILE=8,
- SMBC_LINK=9,*/
- uint smbc_type;
-
- /** Length of this smbc_dirent in bytes
- */
- uint dirlen;
- /** The length of the comment string in bytes (includes null
- * terminator)
- */
- uint commentlen;
- /** Points to the null terminated comment string
- */
- char *comment;
- /** The length of the name string in bytes (includes null
- * terminator)
- */
- uint namelen;
- /** Points to the null terminated name string
- */
- char name[1];
+ /** Type of entity.
+ SMBC_WORKGROUP=1,
+ SMBC_SERVER=2,
+ SMBC_FILE_SHARE=3,
+ SMBC_PRINTER_SHARE=4,
+ SMBC_COMMS_SHARE=5,
+ SMBC_IPC_SHARE=6,
+ SMBC_DIR=7,
+ SMBC_FILE=8,
+ SMBC_LINK=9,*/
+ uint smbc_type;
+
+ /** Length of this smbc_dirent in bytes
+ */
+ uint dirlen;
+ /** The length of the comment string in bytes (includes null
+ * terminator)
+ */
+ uint commentlen;
+ /** Points to the null terminated comment string
+ */
+ char *comment;
+ /** The length of the name string in bytes (includes null
+ * terminator)
+ */
+ uint namelen;
+ /** Points to the null terminated name string
+ */
+ char name[1];
};
@@ -114,30 +125,30 @@ typedef unsigned short uint16;
*/
struct print_job_info
{
- /** numeric ID of the print job
- */
- uint16 id;
+ /** numeric ID of the print job
+ */
+ uint16 id;
- /** represents print job priority (lower numbers mean higher priority)
- */
- uint16 priority;
+ /** represents print job priority (lower numbers mean higher priority)
+ */
+ uint16 priority;
- /** Size of the print job
- */
- size_t size;
+ /** Size of the print job
+ */
+ size_t size;
- /** Name of the user that owns the print job
- */
- char user[128];
+ /** Name of the user that owns the print job
+ */
+ char user[128];
- /** Name of the print job. This will have no name if an anonymous print
- * file was opened. Ie smb://server/printer
- */
- char name[128];
-
- /** Time the print job was spooled
- */
- time_t t;
+ /** Name of the print job. This will have no name if an anonymous print
+ * file was opened. Ie smb://server/printer
+ */
+ char name[128];
+
+ /** Time the print job was spooled
+ */
+ time_t t;
};
#endif
@@ -257,7 +268,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug);
* auth_fn in the smbc_init call, fail, this call will
* try again with an empty username and password. This
* often gets mapped to the guest account on some machines.
-*/
+ */
int smbc_open(const char *furl, int flags, mode_t mode);
@@ -291,7 +302,7 @@ int smbc_open(const char *furl, int flags, mode_t mode);
* - ENODEV The requested share does not exist.
* @see smbc_open()
*
-*/
+ */
int smbc_creat(const char *furl, mode_t mode);
@@ -368,7 +379,7 @@ ssize_t smbc_write(int fd, void *buf, size_t bufsize);
* @todo Are all the whence values really supported?
*
* @todo Are errno values complete and correct?
-*/
+ */
off_t smbc_lseek(int fd, off_t offset, int whence);
@@ -382,7 +393,7 @@ off_t smbc_lseek(int fd, off_t offset, int whence);
* - EINVAL smbc_init() failed or has not been called
*
* @see smbc_open(), smbc_creat()
-*/
+ */
int smbc_close(int fd);
@@ -406,7 +417,7 @@ int smbc_close(int fd);
* @see smbc_rmdir()s
*
* @todo Are errno values complete and correct?
-*/
+ */
int smbc_unlink(const char *furl);
@@ -449,7 +460,7 @@ int smbc_unlink(const char *furl);
* @todo Are we going to support copying when urls are not on the same
* share? I say no... NOTE. I agree for the moment.
*
-*/
+ */
int smbc_rename(const char *ourl, const char *nurl);
@@ -472,7 +483,7 @@ int smbc_rename(const char *ourl, const char *nurl);
*
* @see smbc_getdents(), smbc_readdir(), smbc_closedir()
*
-*/
+ */
int smbc_opendir(const char *durl);
@@ -485,7 +496,7 @@ int smbc_opendir(const char *durl);
* - EBADF dh is an invalid directory handle
*
* @see smbc_opendir()
-*/
+ */
int smbc_closedir(int dh);
@@ -529,7 +540,7 @@ int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
* - EINVAL smbc_init() failed or has not been called
*
* @see smbc_dirent, smbc_getdents(), smbc_open()
-*/
+ */
struct smbc_dirent* smbc_readdir(unsigned int dh);
@@ -552,7 +563,7 @@ struct smbc_dirent* smbc_readdir(unsigned int dh);
*
* @see smbc_readdir()
*
-*/
+ */
off_t smbc_telldir(int dh);
@@ -600,7 +611,7 @@ int smbc_lseekdir(int fd, off_t offset);
*
* @see smbc_rmdir()
*
-*/
+ */
int smbc_mkdir(const char *durl, mode_t mode);
@@ -731,7 +742,7 @@ int smbc_chmod(const char *url, mode_t mode);
* not called.
* and errors returned by smbc_open
*
-*/
+ */
int smbc_print_file(const char *fname, const char *printq);
/**@ingroup print
diff --git a/source/include/local.h b/source/include/local.h
index 1a58e9e2d11..b41eb7b2078 100644
--- a/source/include/local.h
+++ b/source/include/local.h
@@ -58,9 +58,6 @@
#define MAX_OPEN_FILES 10000
#endif
-/* the max number of simultanous connections to the server by all clients */
-#define MAXSTATUS 100000
-
#define WORDMAX 0xFFFF
/* the maximum password length before we declare a likely attack */
@@ -139,9 +136,6 @@
accessible to root */
#define DUMP_CORE 1
-#define SMB_ALIGNMENT 1
-
-
/* shall we support browse requests via a FIFO to nmbd? */
#define ENABLE_FIFO 1
@@ -189,4 +183,10 @@
#define SESSION_TEMPLATE "smb/%d"
#endif
+/* the maximum age in seconds of a password. Should be a lp_ parameter */
+#define MAX_PASSWORD_AGE (21*24*60*60)
+
+/* Allocation roundup. */
+#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000
+
#endif
diff --git a/source/include/messages.h b/source/include/messages.h
index b41f1f38a8e..dfbc4862117 100644
--- a/source/include/messages.h
+++ b/source/include/messages.h
@@ -37,8 +37,12 @@
/* rpc messages */
#define MSG_PRINTER_NOTIFY 2001
+#define MSG_PRINTER_UPDATE 2002
+/* smbd messages */
#define MSG_SMB_CONF_UPDATED 3001
#define MSG_SMB_FORCE_TDIS 3002
+#define MSG_SMB_SAM_SYNC 3003
+#define MSG_SMB_SAM_REPL 3004
#endif
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 912e6f76f49..49b6f1d3aac 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -507,6 +507,7 @@ struct packet_struct
/* NETLOGON opcodes */
#define QUERYFORPDC 7 /* Query for PDC. */
+#define SAM_UAS_CHANGE 10 /* Announce change to UAS or SAM. */
#define QUERYFORPDC_R 12 /* Response to Query for PDC. */
#define SAMLOGON 18
#define SAMLOGON_R 19
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 58ed1759e71..42679945011 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -38,18 +38,6 @@
* A bunch of stuff that was put into smb.h
* in the NTDOM branch - it didn't belong there.
*/
-
-#define CHECK_STRUCT(data) \
-{ \
- if ((data)->struct_start != 0xfefefefe || \
- (data)->struct_end != 0xdcdcdcdc) \
- { \
- DEBUG(0,("uninitialised structure (%s, %d)\n", \
- FUNCTION_MACRO, __LINE__)); \
- sleep(30); \
- } \
-}
-
typedef struct _prs_struct
{
@@ -221,6 +209,12 @@ typedef struct pipes_struct
BOOL fault_state;
/*
+ * Set to true when we should return fault PDU's for a bad handle.
+ */
+
+ BOOL bad_handle_fault_state;
+
+ /*
* Set to RPC_BIG_ENDIAN when dealing with big-endian PDU's
*/
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 14f3fc08938..69b5d7981de 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -27,518 +27,537 @@
/* Win32 Status codes. */
-#define STATUS_BUFFER_OVERFLOW (5)
-#define STATUS_MORE_ENTRIES (0x105)
-#define ERROR_INVALID_PARAMETER (87)
-#define ERROR_INSUFFICIENT_BUFFER (122)
-#define STATUS_1804 (1804)
-#define STATUS_NOTIFY_ENUM_DIR (0x10C)
+#define STATUS_BUFFER_OVERFLOW NT_STATUS(0x80000005)
+#define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a)
+
+#define STATUS_MORE_ENTRIES NT_STATUS(0x0105)
+#define ERROR_INVALID_PARAMETER NT_STATUS(0x0057)
+#define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a)
+#define STATUS_1804 NT_STATUS(0x070c)
+#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c)
/* Win32 Error codes extracted using a loop in smbclient then printing a
netmon sniff to a file. */
-#define NT_STATUS_OK (0x0000)
-#define NT_STATUS_UNSUCCESSFUL (0xC0000000 | 0x0001)
-#define NT_STATUS_NOT_IMPLEMENTED (0xC0000000 | 0x0002)
-#define NT_STATUS_INVALID_INFO_CLASS (0xC0000000 | 0x0003)
-#define NT_STATUS_INFO_LENGTH_MISMATCH (0xC0000000 | 0x0004)
-#define NT_STATUS_ACCESS_VIOLATION (0xC0000000 | 0x0005)
-#define NT_STATUS_IN_PAGE_ERROR (0xC0000000 | 0x0006)
-#define NT_STATUS_PAGEFILE_QUOTA (0xC0000000 | 0x0007)
-#define NT_STATUS_INVALID_HANDLE (0xC0000000 | 0x0008)
-#define NT_STATUS_BAD_INITIAL_STACK (0xC0000000 | 0x0009)
-#define NT_STATUS_BAD_INITIAL_PC (0xC0000000 | 0x000a)
-#define NT_STATUS_INVALID_CID (0xC0000000 | 0x000b)
-#define NT_STATUS_TIMER_NOT_CANCELED (0xC0000000 | 0x000c)
-#define NT_STATUS_INVALID_PARAMETER (0xC0000000 | 0x000d)
-#define NT_STATUS_NO_SUCH_DEVICE (0xC0000000 | 0x000e)
-#define NT_STATUS_NO_SUCH_FILE (0xC0000000 | 0x000f)
-#define NT_STATUS_INVALID_DEVICE_REQUEST (0xC0000000 | 0x0010)
-#define NT_STATUS_END_OF_FILE (0xC0000000 | 0x0011)
-#define NT_STATUS_WRONG_VOLUME (0xC0000000 | 0x0012)
-#define NT_STATUS_NO_MEDIA_IN_DEVICE (0xC0000000 | 0x0013)
-#define NT_STATUS_UNRECOGNIZED_MEDIA (0xC0000000 | 0x0014)
-#define NT_STATUS_NONEXISTENT_SECTOR (0xC0000000 | 0x0015)
-#define NT_STATUS_MORE_PROCESSING_REQUIRED (0xC0000000 | 0x0016)
-#define NT_STATUS_NO_MEMORY (0xC0000000 | 0x0017)
-#define NT_STATUS_CONFLICTING_ADDRESSES (0xC0000000 | 0x0018)
-#define NT_STATUS_NOT_MAPPED_VIEW (0xC0000000 | 0x0019)
-#define NT_STATUS_UNABLE_TO_FREE_VM (0x80000000 | 0x001a)
-#define NT_STATUS_UNABLE_TO_DELETE_SECTION (0xC0000000 | 0x001b)
-#define NT_STATUS_INVALID_SYSTEM_SERVICE (0xC0000000 | 0x001c)
-#define NT_STATUS_ILLEGAL_INSTRUCTION (0xC0000000 | 0x001d)
-#define NT_STATUS_INVALID_LOCK_SEQUENCE (0xC0000000 | 0x001e)
-#define NT_STATUS_INVALID_VIEW_SIZE (0xC0000000 | 0x001f)
-#define NT_STATUS_INVALID_FILE_FOR_SECTION (0xC0000000 | 0x0020)
-#define NT_STATUS_ALREADY_COMMITTED (0xC0000000 | 0x0021)
-#define NT_STATUS_ACCESS_DENIED (0xC0000000 | 0x0022)
-#define NT_STATUS_BUFFER_TOO_SMALL (0xC0000000 | 0x0023)
-#define NT_STATUS_OBJECT_TYPE_MISMATCH (0xC0000000 | 0x0024)
-#define NT_STATUS_NONCONTINUABLE_EXCEPTION (0xC0000000 | 0x0025)
-#define NT_STATUS_INVALID_DISPOSITION (0xC0000000 | 0x0026)
-#define NT_STATUS_UNWIND (0xC0000000 | 0x0027)
-#define NT_STATUS_BAD_STACK (0xC0000000 | 0x0028)
-#define NT_STATUS_INVALID_UNWIND_TARGET (0xC0000000 | 0x0029)
-#define NT_STATUS_NOT_LOCKED (0xC0000000 | 0x002a)
-#define NT_STATUS_PARITY_ERROR (0xC0000000 | 0x002b)
-#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (0xC0000000 | 0x002c)
-#define NT_STATUS_NOT_COMMITTED (0xC0000000 | 0x002d)
-#define NT_STATUS_INVALID_PORT_ATTRIBUTES (0xC0000000 | 0x002e)
-#define NT_STATUS_PORT_MESSAGE_TOO_LONG (0xC0000000 | 0x002f)
-#define NT_STATUS_INVALID_PARAMETER_MIX (0xC0000000 | 0x0030)
-#define NT_STATUS_INVALID_QUOTA_LOWER (0xC0000000 | 0x0031)
-#define NT_STATUS_DISK_CORRUPT_ERROR (0xC0000000 | 0x0032)
-#define NT_STATUS_OBJECT_NAME_INVALID (0xC0000000 | 0x0033)
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND (0xC0000000 | 0x0034)
-#define NT_STATUS_OBJECT_NAME_COLLISION (0xC0000000 | 0x0035)
-#define NT_STATUS_HANDLE_NOT_WAITABLE (0xC0000000 | 0x0036)
-#define NT_STATUS_PORT_DISCONNECTED (0xC0000000 | 0x0037)
-#define NT_STATUS_DEVICE_ALREADY_ATTACHED (0xC0000000 | 0x0038)
-#define NT_STATUS_OBJECT_PATH_INVALID (0xC0000000 | 0x0039)
-#define NT_STATUS_OBJECT_PATH_NOT_FOUND (0xC0000000 | 0x003a)
-#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (0xC0000000 | 0x003b)
-#define NT_STATUS_DATA_OVERRUN (0xC0000000 | 0x003c)
-#define NT_STATUS_DATA_LATE_ERROR (0xC0000000 | 0x003d)
-#define NT_STATUS_DATA_ERROR (0xC0000000 | 0x003e)
-#define NT_STATUS_CRC_ERROR (0xC0000000 | 0x003f)
-#define NT_STATUS_SECTION_TOO_BIG (0xC0000000 | 0x0040)
-#define NT_STATUS_PORT_CONNECTION_REFUSED (0xC0000000 | 0x0041)
-#define NT_STATUS_INVALID_PORT_HANDLE (0xC0000000 | 0x0042)
-#define NT_STATUS_SHARING_VIOLATION (0xC0000000 | 0x0043)
-#define NT_STATUS_QUOTA_EXCEEDED (0xC0000000 | 0x0044)
-#define NT_STATUS_INVALID_PAGE_PROTECTION (0xC0000000 | 0x0045)
-#define NT_STATUS_MUTANT_NOT_OWNED (0xC0000000 | 0x0046)
-#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (0xC0000000 | 0x0047)
-#define NT_STATUS_PORT_ALREADY_SET (0xC0000000 | 0x0048)
-#define NT_STATUS_SECTION_NOT_IMAGE (0xC0000000 | 0x0049)
-#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (0xC0000000 | 0x004a)
-#define NT_STATUS_THREAD_IS_TERMINATING (0xC0000000 | 0x004b)
-#define NT_STATUS_BAD_WORKING_SET_LIMIT (0xC0000000 | 0x004c)
-#define NT_STATUS_INCOMPATIBLE_FILE_MAP (0xC0000000 | 0x004d)
-#define NT_STATUS_SECTION_PROTECTION (0xC0000000 | 0x004e)
-#define NT_STATUS_EAS_NOT_SUPPORTED (0xC0000000 | 0x004f)
-#define NT_STATUS_EA_TOO_LARGE (0xC0000000 | 0x0050)
-#define NT_STATUS_NONEXISTENT_EA_ENTRY (0xC0000000 | 0x0051)
-#define NT_STATUS_NO_EAS_ON_FILE (0xC0000000 | 0x0052)
-#define NT_STATUS_EA_CORRUPT_ERROR (0xC0000000 | 0x0053)
-#define NT_STATUS_FILE_LOCK_CONFLICT (0xC0000000 | 0x0054)
-#define NT_STATUS_LOCK_NOT_GRANTED (0xC0000000 | 0x0055)
-#define NT_STATUS_DELETE_PENDING (0xC0000000 | 0x0056)
-#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (0xC0000000 | 0x0057)
-#define NT_STATUS_UNKNOWN_REVISION (0xC0000000 | 0x0058)
-#define NT_STATUS_REVISION_MISMATCH (0xC0000000 | 0x0059)
-#define NT_STATUS_INVALID_OWNER (0xC0000000 | 0x005a)
-#define NT_STATUS_INVALID_PRIMARY_GROUP (0xC0000000 | 0x005b)
-#define NT_STATUS_NO_IMPERSONATION_TOKEN (0xC0000000 | 0x005c)
-#define NT_STATUS_CANT_DISABLE_MANDATORY (0xC0000000 | 0x005d)
-#define NT_STATUS_NO_LOGON_SERVERS (0xC0000000 | 0x005e)
-#define NT_STATUS_NO_SUCH_LOGON_SESSION (0xC0000000 | 0x005f)
-#define NT_STATUS_NO_SUCH_PRIVILEGE (0xC0000000 | 0x0060)
-#define NT_STATUS_PRIVILEGE_NOT_HELD (0xC0000000 | 0x0061)
-#define NT_STATUS_INVALID_ACCOUNT_NAME (0xC0000000 | 0x0062)
-#define NT_STATUS_USER_EXISTS (0xC0000000 | 0x0063)
-#define NT_STATUS_NO_SUCH_USER (0xC0000000 | 0x0064)
-#define NT_STATUS_GROUP_EXISTS (0xC0000000 | 0x0065)
-#define NT_STATUS_NO_SUCH_GROUP (0xC0000000 | 0x0066)
-#define NT_STATUS_MEMBER_IN_GROUP (0xC0000000 | 0x0067)
-#define NT_STATUS_MEMBER_NOT_IN_GROUP (0xC0000000 | 0x0068)
-#define NT_STATUS_LAST_ADMIN (0xC0000000 | 0x0069)
-#define NT_STATUS_WRONG_PASSWORD (0xC0000000 | 0x006a)
-#define NT_STATUS_ILL_FORMED_PASSWORD (0xC0000000 | 0x006b)
-#define NT_STATUS_PASSWORD_RESTRICTION (0xC0000000 | 0x006c)
-#define NT_STATUS_LOGON_FAILURE (0xC0000000 | 0x006d)
-#define NT_STATUS_ACCOUNT_RESTRICTION (0xC0000000 | 0x006e)
-#define NT_STATUS_INVALID_LOGON_HOURS (0xC0000000 | 0x006f)
-#define NT_STATUS_INVALID_WORKSTATION (0xC0000000 | 0x0070)
-#define NT_STATUS_PASSWORD_EXPIRED (0xC0000000 | 0x0071)
-#define NT_STATUS_ACCOUNT_DISABLED (0xC0000000 | 0x0072)
-#define NT_STATUS_NONE_MAPPED (0xC0000000 | 0x0073)
-#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (0xC0000000 | 0x0074)
-#define NT_STATUS_LUIDS_EXHAUSTED (0xC0000000 | 0x0075)
-#define NT_STATUS_INVALID_SUB_AUTHORITY (0xC0000000 | 0x0076)
-#define NT_STATUS_INVALID_ACL (0xC0000000 | 0x0077)
-#define NT_STATUS_INVALID_SID (0xC0000000 | 0x0078)
-#define NT_STATUS_INVALID_SECURITY_DESCR (0xC0000000 | 0x0079)
-#define NT_STATUS_PROCEDURE_NOT_FOUND (0xC0000000 | 0x007a)
-#define NT_STATUS_INVALID_IMAGE_FORMAT (0xC0000000 | 0x007b)
-#define NT_STATUS_NO_TOKEN (0xC0000000 | 0x007c)
-#define NT_STATUS_BAD_INHERITANCE_ACL (0xC0000000 | 0x007d)
-#define NT_STATUS_RANGE_NOT_LOCKED (0xC0000000 | 0x007e)
-#define NT_STATUS_DISK_FULL (0xC0000000 | 0x007f)
-#define NT_STATUS_SERVER_DISABLED (0xC0000000 | 0x0080)
-#define NT_STATUS_SERVER_NOT_DISABLED (0xC0000000 | 0x0081)
-#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (0xC0000000 | 0x0082)
-#define NT_STATUS_GUIDS_EXHAUSTED (0xC0000000 | 0x0083)
-#define NT_STATUS_INVALID_ID_AUTHORITY (0xC0000000 | 0x0084)
-#define NT_STATUS_AGENTS_EXHAUSTED (0xC0000000 | 0x0085)
-#define NT_STATUS_INVALID_VOLUME_LABEL (0xC0000000 | 0x0086)
-#define NT_STATUS_SECTION_NOT_EXTENDED (0xC0000000 | 0x0087)
-#define NT_STATUS_NOT_MAPPED_DATA (0xC0000000 | 0x0088)
-#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (0xC0000000 | 0x0089)
-#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (0xC0000000 | 0x008a)
-#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (0xC0000000 | 0x008b)
-#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (0xC0000000 | 0x008c)
-#define NT_STATUS_FLOAT_DENORMAL_OPERAND (0xC0000000 | 0x008d)
-#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (0xC0000000 | 0x008e)
-#define NT_STATUS_FLOAT_INEXACT_RESULT (0xC0000000 | 0x008f)
-#define NT_STATUS_FLOAT_INVALID_OPERATION (0xC0000000 | 0x0090)
-#define NT_STATUS_FLOAT_OVERFLOW (0xC0000000 | 0x0091)
-#define NT_STATUS_FLOAT_STACK_CHECK (0xC0000000 | 0x0092)
-#define NT_STATUS_FLOAT_UNDERFLOW (0xC0000000 | 0x0093)
-#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000000 | 0x0094)
-#define NT_STATUS_INTEGER_OVERFLOW (0xC0000000 | 0x0095)
-#define NT_STATUS_PRIVILEGED_INSTRUCTION (0xC0000000 | 0x0096)
-#define NT_STATUS_TOO_MANY_PAGING_FILES (0xC0000000 | 0x0097)
-#define NT_STATUS_FILE_INVALID (0xC0000000 | 0x0098)
-#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (0xC0000000 | 0x0099)
-#define NT_STATUS_INSUFFICIENT_RESOURCES (0xC0000000 | 0x009a)
-#define NT_STATUS_DFS_EXIT_PATH_FOUND (0xC0000000 | 0x009b)
-#define NT_STATUS_DEVICE_DATA_ERROR (0xC0000000 | 0x009c)
-#define NT_STATUS_DEVICE_NOT_CONNECTED (0xC0000000 | 0x009d)
-#define NT_STATUS_DEVICE_POWER_FAILURE (0xC0000000 | 0x009e)
-#define NT_STATUS_FREE_VM_NOT_AT_BASE (0xC0000000 | 0x009f)
-#define NT_STATUS_MEMORY_NOT_ALLOCATED (0xC0000000 | 0x00a0)
-#define NT_STATUS_WORKING_SET_QUOTA (0xC0000000 | 0x00a1)
-#define NT_STATUS_MEDIA_WRITE_PROTECTED (0xC0000000 | 0x00a2)
-#define NT_STATUS_DEVICE_NOT_READY (0xC0000000 | 0x00a3)
-#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (0xC0000000 | 0x00a4)
-#define NT_STATUS_BAD_IMPERSONATION_LEVEL (0xC0000000 | 0x00a5)
-#define NT_STATUS_CANT_OPEN_ANONYMOUS (0xC0000000 | 0x00a6)
-#define NT_STATUS_BAD_VALIDATION_CLASS (0xC0000000 | 0x00a7)
-#define NT_STATUS_BAD_TOKEN_TYPE (0xC0000000 | 0x00a8)
-#define NT_STATUS_BAD_MASTER_BOOT_RECORD (0xC0000000 | 0x00a9)
-#define NT_STATUS_INSTRUCTION_MISALIGNMENT (0xC0000000 | 0x00aa)
-#define NT_STATUS_INSTANCE_NOT_AVAILABLE (0xC0000000 | 0x00ab)
-#define NT_STATUS_PIPE_NOT_AVAILABLE (0xC0000000 | 0x00ac)
-#define NT_STATUS_INVALID_PIPE_STATE (0xC0000000 | 0x00ad)
-#define NT_STATUS_PIPE_BUSY (0xC0000000 | 0x00ae)
-#define NT_STATUS_ILLEGAL_FUNCTION (0xC0000000 | 0x00af)
-#define NT_STATUS_PIPE_DISCONNECTED (0xC0000000 | 0x00b0)
-#define NT_STATUS_PIPE_CLOSING (0xC0000000 | 0x00b1)
-#define NT_STATUS_PIPE_CONNECTED (0xC0000000 | 0x00b2)
-#define NT_STATUS_PIPE_LISTENING (0xC0000000 | 0x00b3)
-#define NT_STATUS_INVALID_READ_MODE (0xC0000000 | 0x00b4)
-#define NT_STATUS_IO_TIMEOUT (0xC0000000 | 0x00b5)
-#define NT_STATUS_FILE_FORCED_CLOSED (0xC0000000 | 0x00b6)
-#define NT_STATUS_PROFILING_NOT_STARTED (0xC0000000 | 0x00b7)
-#define NT_STATUS_PROFILING_NOT_STOPPED (0xC0000000 | 0x00b8)
-#define NT_STATUS_COULD_NOT_INTERPRET (0xC0000000 | 0x00b9)
-#define NT_STATUS_FILE_IS_A_DIRECTORY (0xC0000000 | 0x00ba)
-#define NT_STATUS_NOT_SUPPORTED (0xC0000000 | 0x00bb)
-#define NT_STATUS_REMOTE_NOT_LISTENING (0xC0000000 | 0x00bc)
-#define NT_STATUS_DUPLICATE_NAME (0xC0000000 | 0x00bd)
-#define NT_STATUS_BAD_NETWORK_PATH (0xC0000000 | 0x00be)
-#define NT_STATUS_NETWORK_BUSY (0xC0000000 | 0x00bf)
-#define NT_STATUS_DEVICE_DOES_NOT_EXIST (0xC0000000 | 0x00c0)
-#define NT_STATUS_TOO_MANY_COMMANDS (0xC0000000 | 0x00c1)
-#define NT_STATUS_ADAPTER_HARDWARE_ERROR (0xC0000000 | 0x00c2)
-#define NT_STATUS_INVALID_NETWORK_RESPONSE (0xC0000000 | 0x00c3)
-#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (0xC0000000 | 0x00c4)
-#define NT_STATUS_BAD_REMOTE_ADAPTER (0xC0000000 | 0x00c5)
-#define NT_STATUS_PRINT_QUEUE_FULL (0xC0000000 | 0x00c6)
-#define NT_STATUS_NO_SPOOL_SPACE (0xC0000000 | 0x00c7)
-#define NT_STATUS_PRINT_CANCELLED (0xC0000000 | 0x00c8)
-#define NT_STATUS_NETWORK_NAME_DELETED (0xC0000000 | 0x00c9)
-#define NT_STATUS_NETWORK_ACCESS_DENIED (0xC0000000 | 0x00ca)
-#define NT_STATUS_BAD_DEVICE_TYPE (0xC0000000 | 0x00cb)
-#define NT_STATUS_BAD_NETWORK_NAME (0xC0000000 | 0x00cc)
-#define NT_STATUS_TOO_MANY_NAMES (0xC0000000 | 0x00cd)
-#define NT_STATUS_TOO_MANY_SESSIONS (0xC0000000 | 0x00ce)
-#define NT_STATUS_SHARING_PAUSED (0xC0000000 | 0x00cf)
-#define NT_STATUS_REQUEST_NOT_ACCEPTED (0xC0000000 | 0x00d0)
-#define NT_STATUS_REDIRECTOR_PAUSED (0xC0000000 | 0x00d1)
-#define NT_STATUS_NET_WRITE_FAULT (0xC0000000 | 0x00d2)
-#define NT_STATUS_PROFILING_AT_LIMIT (0xC0000000 | 0x00d3)
-#define NT_STATUS_NOT_SAME_DEVICE (0xC0000000 | 0x00d4)
-#define NT_STATUS_FILE_RENAMED (0xC0000000 | 0x00d5)
-#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (0xC0000000 | 0x00d6)
-#define NT_STATUS_NO_SECURITY_ON_OBJECT (0xC0000000 | 0x00d7)
-#define NT_STATUS_CANT_WAIT (0xC0000000 | 0x00d8)
-#define NT_STATUS_PIPE_EMPTY (0xC0000000 | 0x00d9)
-#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (0xC0000000 | 0x00da)
-#define NT_STATUS_CANT_TERMINATE_SELF (0xC0000000 | 0x00db)
-#define NT_STATUS_INVALID_SERVER_STATE (0xC0000000 | 0x00dc)
-#define NT_STATUS_INVALID_DOMAIN_STATE (0xC0000000 | 0x00dd)
-#define NT_STATUS_INVALID_DOMAIN_ROLE (0xC0000000 | 0x00de)
-#define NT_STATUS_NO_SUCH_DOMAIN (0xC0000000 | 0x00df)
-#define NT_STATUS_DOMAIN_EXISTS (0xC0000000 | 0x00e0)
-#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (0xC0000000 | 0x00e1)
-#define NT_STATUS_OPLOCK_NOT_GRANTED (0xC0000000 | 0x00e2)
-#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (0xC0000000 | 0x00e3)
-#define NT_STATUS_INTERNAL_DB_CORRUPTION (0xC0000000 | 0x00e4)
-#define NT_STATUS_INTERNAL_ERROR (0xC0000000 | 0x00e5)
-#define NT_STATUS_GENERIC_NOT_MAPPED (0xC0000000 | 0x00e6)
-#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (0xC0000000 | 0x00e7)
-#define NT_STATUS_INVALID_USER_BUFFER (0xC0000000 | 0x00e8)
-#define NT_STATUS_UNEXPECTED_IO_ERROR (0xC0000000 | 0x00e9)
-#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (0xC0000000 | 0x00ea)
-#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (0xC0000000 | 0x00eb)
-#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (0xC0000000 | 0x00ec)
-#define NT_STATUS_NOT_LOGON_PROCESS (0xC0000000 | 0x00ed)
-#define NT_STATUS_LOGON_SESSION_EXISTS (0xC0000000 | 0x00ee)
-#define NT_STATUS_INVALID_PARAMETER_1 (0xC0000000 | 0x00ef)
-#define NT_STATUS_INVALID_PARAMETER_2 (0xC0000000 | 0x00f0)
-#define NT_STATUS_INVALID_PARAMETER_3 (0xC0000000 | 0x00f1)
-#define NT_STATUS_INVALID_PARAMETER_4 (0xC0000000 | 0x00f2)
-#define NT_STATUS_INVALID_PARAMETER_5 (0xC0000000 | 0x00f3)
-#define NT_STATUS_INVALID_PARAMETER_6 (0xC0000000 | 0x00f4)
-#define NT_STATUS_INVALID_PARAMETER_7 (0xC0000000 | 0x00f5)
-#define NT_STATUS_INVALID_PARAMETER_8 (0xC0000000 | 0x00f6)
-#define NT_STATUS_INVALID_PARAMETER_9 (0xC0000000 | 0x00f7)
-#define NT_STATUS_INVALID_PARAMETER_10 (0xC0000000 | 0x00f8)
-#define NT_STATUS_INVALID_PARAMETER_11 (0xC0000000 | 0x00f9)
-#define NT_STATUS_INVALID_PARAMETER_12 (0xC0000000 | 0x00fa)
-#define NT_STATUS_REDIRECTOR_NOT_STARTED (0xC0000000 | 0x00fb)
-#define NT_STATUS_REDIRECTOR_STARTED (0xC0000000 | 0x00fc)
-#define NT_STATUS_STACK_OVERFLOW (0xC0000000 | 0x00fd)
-#define NT_STATUS_NO_SUCH_PACKAGE (0xC0000000 | 0x00fe)
-#define NT_STATUS_BAD_FUNCTION_TABLE (0xC0000000 | 0x00ff)
-#define NT_STATUS_DIRECTORY_NOT_EMPTY (0xC0000000 | 0x0101)
-#define NT_STATUS_FILE_CORRUPT_ERROR (0xC0000000 | 0x0102)
-#define NT_STATUS_NOT_A_DIRECTORY (0xC0000000 | 0x0103)
-#define NT_STATUS_BAD_LOGON_SESSION_STATE (0xC0000000 | 0x0104)
-#define NT_STATUS_LOGON_SESSION_COLLISION (0xC0000000 | 0x0105)
-#define NT_STATUS_NAME_TOO_LONG (0xC0000000 | 0x0106)
-#define NT_STATUS_FILES_OPEN (0xC0000000 | 0x0107)
-#define NT_STATUS_CONNECTION_IN_USE (0xC0000000 | 0x0108)
-#define NT_STATUS_MESSAGE_NOT_FOUND (0xC0000000 | 0x0109)
-#define NT_STATUS_PROCESS_IS_TERMINATING (0xC0000000 | 0x010a)
-#define NT_STATUS_INVALID_LOGON_TYPE (0xC0000000 | 0x010b)
-#define NT_STATUS_NO_GUID_TRANSLATION (0xC0000000 | 0x010c)
-#define NT_STATUS_CANNOT_IMPERSONATE (0xC0000000 | 0x010d)
-#define NT_STATUS_IMAGE_ALREADY_LOADED (0xC0000000 | 0x010e)
-#define NT_STATUS_ABIOS_NOT_PRESENT (0xC0000000 | 0x010f)
-#define NT_STATUS_ABIOS_LID_NOT_EXIST (0xC0000000 | 0x0110)
-#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (0xC0000000 | 0x0111)
-#define NT_STATUS_ABIOS_NOT_LID_OWNER (0xC0000000 | 0x0112)
-#define NT_STATUS_ABIOS_INVALID_COMMAND (0xC0000000 | 0x0113)
-#define NT_STATUS_ABIOS_INVALID_LID (0xC0000000 | 0x0114)
-#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (0xC0000000 | 0x0115)
-#define NT_STATUS_ABIOS_INVALID_SELECTOR (0xC0000000 | 0x0116)
-#define NT_STATUS_NO_LDT (0xC0000000 | 0x0117)
-#define NT_STATUS_INVALID_LDT_SIZE (0xC0000000 | 0x0118)
-#define NT_STATUS_INVALID_LDT_OFFSET (0xC0000000 | 0x0119)
-#define NT_STATUS_INVALID_LDT_DESCRIPTOR (0xC0000000 | 0x011a)
-#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (0xC0000000 | 0x011b)
-#define NT_STATUS_RXACT_INVALID_STATE (0xC0000000 | 0x011c)
-#define NT_STATUS_RXACT_COMMIT_FAILURE (0xC0000000 | 0x011d)
-#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (0xC0000000 | 0x011e)
-#define NT_STATUS_TOO_MANY_OPENED_FILES (0xC0000000 | 0x011f)
-#define NT_STATUS_CANCELLED (0xC0000000 | 0x0120)
-#define NT_STATUS_CANNOT_DELETE (0xC0000000 | 0x0121)
-#define NT_STATUS_INVALID_COMPUTER_NAME (0xC0000000 | 0x0122)
-#define NT_STATUS_FILE_DELETED (0xC0000000 | 0x0123)
-#define NT_STATUS_SPECIAL_ACCOUNT (0xC0000000 | 0x0124)
-#define NT_STATUS_SPECIAL_GROUP (0xC0000000 | 0x0125)
-#define NT_STATUS_SPECIAL_USER (0xC0000000 | 0x0126)
-#define NT_STATUS_MEMBERS_PRIMARY_GROUP (0xC0000000 | 0x0127)
-#define NT_STATUS_FILE_CLOSED (0xC0000000 | 0x0128)
-#define NT_STATUS_TOO_MANY_THREADS (0xC0000000 | 0x0129)
-#define NT_STATUS_THREAD_NOT_IN_PROCESS (0xC0000000 | 0x012a)
-#define NT_STATUS_TOKEN_ALREADY_IN_USE (0xC0000000 | 0x012b)
-#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (0xC0000000 | 0x012c)
-#define NT_STATUS_COMMITMENT_LIMIT (0xC0000000 | 0x012d)
-#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (0xC0000000 | 0x012e)
-#define NT_STATUS_INVALID_IMAGE_NOT_MZ (0xC0000000 | 0x012f)
-#define NT_STATUS_INVALID_IMAGE_PROTECT (0xC0000000 | 0x0130)
-#define NT_STATUS_INVALID_IMAGE_WIN_16 (0xC0000000 | 0x0131)
-#define NT_STATUS_LOGON_SERVER_CONFLICT (0xC0000000 | 0x0132)
-#define NT_STATUS_TIME_DIFFERENCE_AT_DC (0xC0000000 | 0x0133)
-#define NT_STATUS_SYNCHRONIZATION_REQUIRED (0xC0000000 | 0x0134)
-#define NT_STATUS_DLL_NOT_FOUND (0xC0000000 | 0x0135)
-#define NT_STATUS_OPEN_FAILED (0xC0000000 | 0x0136)
-#define NT_STATUS_IO_PRIVILEGE_FAILED (0xC0000000 | 0x0137)
-#define NT_STATUS_ORDINAL_NOT_FOUND (0xC0000000 | 0x0138)
-#define NT_STATUS_ENTRYPOINT_NOT_FOUND (0xC0000000 | 0x0139)
-#define NT_STATUS_CONTROL_C_EXIT (0xC0000000 | 0x013a)
-#define NT_STATUS_LOCAL_DISCONNECT (0xC0000000 | 0x013b)
-#define NT_STATUS_REMOTE_DISCONNECT (0xC0000000 | 0x013c)
-#define NT_STATUS_REMOTE_RESOURCES (0xC0000000 | 0x013d)
-#define NT_STATUS_LINK_FAILED (0xC0000000 | 0x013e)
-#define NT_STATUS_LINK_TIMEOUT (0xC0000000 | 0x013f)
-#define NT_STATUS_INVALID_CONNECTION (0xC0000000 | 0x0140)
-#define NT_STATUS_INVALID_ADDRESS (0xC0000000 | 0x0141)
-#define NT_STATUS_DLL_INIT_FAILED (0xC0000000 | 0x0142)
-#define NT_STATUS_MISSING_SYSTEMFILE (0xC0000000 | 0x0143)
-#define NT_STATUS_UNHANDLED_EXCEPTION (0xC0000000 | 0x0144)
-#define NT_STATUS_APP_INIT_FAILURE (0xC0000000 | 0x0145)
-#define NT_STATUS_PAGEFILE_CREATE_FAILED (0xC0000000 | 0x0146)
-#define NT_STATUS_NO_PAGEFILE (0xC0000000 | 0x0147)
-#define NT_STATUS_INVALID_LEVEL (0xC0000000 | 0x0148)
-#define NT_STATUS_WRONG_PASSWORD_CORE (0xC0000000 | 0x0149)
-#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (0xC0000000 | 0x014a)
-#define NT_STATUS_PIPE_BROKEN (0xC0000000 | 0x014b)
-#define NT_STATUS_REGISTRY_CORRUPT (0xC0000000 | 0x014c)
-#define NT_STATUS_REGISTRY_IO_FAILED (0xC0000000 | 0x014d)
-#define NT_STATUS_NO_EVENT_PAIR (0xC0000000 | 0x014e)
-#define NT_STATUS_UNRECOGNIZED_VOLUME (0xC0000000 | 0x014f)
-#define NT_STATUS_SERIAL_NO_DEVICE_INITED (0xC0000000 | 0x0150)
-#define NT_STATUS_NO_SUCH_ALIAS (0xC0000000 | 0x0151)
-#define NT_STATUS_MEMBER_NOT_IN_ALIAS (0xC0000000 | 0x0152)
-#define NT_STATUS_MEMBER_IN_ALIAS (0xC0000000 | 0x0153)
-#define NT_STATUS_ALIAS_EXISTS (0xC0000000 | 0x0154)
-#define NT_STATUS_LOGON_NOT_GRANTED (0xC0000000 | 0x0155)
-#define NT_STATUS_TOO_MANY_SECRETS (0xC0000000 | 0x0156)
-#define NT_STATUS_SECRET_TOO_LONG (0xC0000000 | 0x0157)
-#define NT_STATUS_INTERNAL_DB_ERROR (0xC0000000 | 0x0158)
-#define NT_STATUS_FULLSCREEN_MODE (0xC0000000 | 0x0159)
-#define NT_STATUS_TOO_MANY_CONTEXT_IDS (0xC0000000 | 0x015a)
-#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (0xC0000000 | 0x015b)
-#define NT_STATUS_NOT_REGISTRY_FILE (0xC0000000 | 0x015c)
-#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 0x015d)
-#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (0xC0000000 | 0x015e)
-#define NT_STATUS_FT_MISSING_MEMBER (0xC0000000 | 0x015f)
-#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (0xC0000000 | 0x0160)
-#define NT_STATUS_ILLEGAL_CHARACTER (0xC0000000 | 0x0161)
-#define NT_STATUS_UNMAPPABLE_CHARACTER (0xC0000000 | 0x0162)
-#define NT_STATUS_UNDEFINED_CHARACTER (0xC0000000 | 0x0163)
-#define NT_STATUS_FLOPPY_VOLUME (0xC0000000 | 0x0164)
-#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (0xC0000000 | 0x0165)
-#define NT_STATUS_FLOPPY_WRONG_CYLINDER (0xC0000000 | 0x0166)
-#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (0xC0000000 | 0x0167)
-#define NT_STATUS_FLOPPY_BAD_REGISTERS (0xC0000000 | 0x0168)
-#define NT_STATUS_DISK_RECALIBRATE_FAILED (0xC0000000 | 0x0169)
-#define NT_STATUS_DISK_OPERATION_FAILED (0xC0000000 | 0x016a)
-#define NT_STATUS_DISK_RESET_FAILED (0xC0000000 | 0x016b)
-#define NT_STATUS_SHARED_IRQ_BUSY (0xC0000000 | 0x016c)
-#define NT_STATUS_FT_ORPHANING (0xC0000000 | 0x016d)
-#define NT_STATUS_PARTITION_FAILURE (0xC0000000 | 0x0172)
-#define NT_STATUS_INVALID_BLOCK_LENGTH (0xC0000000 | 0x0173)
-#define NT_STATUS_DEVICE_NOT_PARTITIONED (0xC0000000 | 0x0174)
-#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (0xC0000000 | 0x0175)
-#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (0xC0000000 | 0x0176)
-#define NT_STATUS_EOM_OVERFLOW (0xC0000000 | 0x0177)
-#define NT_STATUS_NO_MEDIA (0xC0000000 | 0x0178)
-#define NT_STATUS_NO_SUCH_MEMBER (0xC0000000 | 0x017a)
-#define NT_STATUS_INVALID_MEMBER (0xC0000000 | 0x017b)
-#define NT_STATUS_KEY_DELETED (0xC0000000 | 0x017c)
-#define NT_STATUS_NO_LOG_SPACE (0xC0000000 | 0x017d)
-#define NT_STATUS_TOO_MANY_SIDS (0xC0000000 | 0x017e)
-#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 0x017f)
-#define NT_STATUS_KEY_HAS_CHILDREN (0xC0000000 | 0x0180)
-#define NT_STATUS_CHILD_MUST_BE_VOLATILE (0xC0000000 | 0x0181)
-#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (0xC0000000 | 0x0182)
-#define NT_STATUS_DRIVER_INTERNAL_ERROR (0xC0000000 | 0x0183)
-#define NT_STATUS_INVALID_DEVICE_STATE (0xC0000000 | 0x0184)
-#define NT_STATUS_IO_DEVICE_ERROR (0xC0000000 | 0x0185)
-#define NT_STATUS_DEVICE_PROTOCOL_ERROR (0xC0000000 | 0x0186)
-#define NT_STATUS_BACKUP_CONTROLLER (0xC0000000 | 0x0187)
-#define NT_STATUS_LOG_FILE_FULL (0xC0000000 | 0x0188)
-#define NT_STATUS_TOO_LATE (0xC0000000 | 0x0189)
-#define NT_STATUS_NO_TRUST_LSA_SECRET (0xC0000000 | 0x018a)
-#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (0xC0000000 | 0x018b)
-#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (0xC0000000 | 0x018c)
-#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (0xC0000000 | 0x018d)
-#define NT_STATUS_EVENTLOG_FILE_CORRUPT (0xC0000000 | 0x018e)
-#define NT_STATUS_EVENTLOG_CANT_START (0xC0000000 | 0x018f)
-#define NT_STATUS_TRUST_FAILURE (0xC0000000 | 0x0190)
-#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (0xC0000000 | 0x0191)
-#define NT_STATUS_NETLOGON_NOT_STARTED (0xC0000000 | 0x0192)
-#define NT_STATUS_ACCOUNT_EXPIRED (0xC0000000 | 0x0193)
-#define NT_STATUS_POSSIBLE_DEADLOCK (0xC0000000 | 0x0194)
-#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (0xC0000000 | 0x0195)
-#define NT_STATUS_REMOTE_SESSION_LIMIT (0xC0000000 | 0x0196)
-#define NT_STATUS_EVENTLOG_FILE_CHANGED (0xC0000000 | 0x0197)
-#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (0xC0000000 | 0x0198)
-#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (0xC0000000 | 0x0199)
-#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (0xC0000000 | 0x019a)
-#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (0xC0000000 | 0x019b)
-#define NT_STATUS_FS_DRIVER_REQUIRED (0xC0000000 | 0x019c)
-#define NT_STATUS_NO_USER_SESSION_KEY (0xC0000000 | 0x0202)
-#define NT_STATUS_USER_SESSION_DELETED (0xC0000000 | 0x0203)
-#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (0xC0000000 | 0x0204)
-#define NT_STATUS_INSUFF_SERVER_RESOURCES (0xC0000000 | 0x0205)
-#define NT_STATUS_INVALID_BUFFER_SIZE (0xC0000000 | 0x0206)
-#define NT_STATUS_INVALID_ADDRESS_COMPONENT (0xC0000000 | 0x0207)
-#define NT_STATUS_INVALID_ADDRESS_WILDCARD (0xC0000000 | 0x0208)
-#define NT_STATUS_TOO_MANY_ADDRESSES (0xC0000000 | 0x0209)
-#define NT_STATUS_ADDRESS_ALREADY_EXISTS (0xC0000000 | 0x020a)
-#define NT_STATUS_ADDRESS_CLOSED (0xC0000000 | 0x020b)
-#define NT_STATUS_CONNECTION_DISCONNECTED (0xC0000000 | 0x020c)
-#define NT_STATUS_CONNECTION_RESET (0xC0000000 | 0x020d)
-#define NT_STATUS_TOO_MANY_NODES (0xC0000000 | 0x020e)
-#define NT_STATUS_TRANSACTION_ABORTED (0xC0000000 | 0x020f)
-#define NT_STATUS_TRANSACTION_TIMED_OUT (0xC0000000 | 0x0210)
-#define NT_STATUS_TRANSACTION_NO_RELEASE (0xC0000000 | 0x0211)
-#define NT_STATUS_TRANSACTION_NO_MATCH (0xC0000000 | 0x0212)
-#define NT_STATUS_TRANSACTION_RESPONDED (0xC0000000 | 0x0213)
-#define NT_STATUS_TRANSACTION_INVALID_ID (0xC0000000 | 0x0214)
-#define NT_STATUS_TRANSACTION_INVALID_TYPE (0xC0000000 | 0x0215)
-#define NT_STATUS_NOT_SERVER_SESSION (0xC0000000 | 0x0216)
-#define NT_STATUS_NOT_CLIENT_SESSION (0xC0000000 | 0x0217)
-#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (0xC0000000 | 0x0218)
-#define NT_STATUS_DEBUG_ATTACH_FAILED (0xC0000000 | 0x0219)
-#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (0xC0000000 | 0x021a)
-#define NT_STATUS_DATA_NOT_ACCEPTED (0xC0000000 | 0x021b)
-#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (0xC0000000 | 0x021c)
-#define NT_STATUS_VDM_HARD_ERROR (0xC0000000 | 0x021d)
-#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (0xC0000000 | 0x021e)
-#define NT_STATUS_REPLY_MESSAGE_MISMATCH (0xC0000000 | 0x021f)
-#define NT_STATUS_MAPPED_ALIGNMENT (0xC0000000 | 0x0220)
-#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (0xC0000000 | 0x0221)
-#define NT_STATUS_LOST_WRITEBEHIND_DATA (0xC0000000 | 0x0222)
-#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (0xC0000000 | 0x0223)
-#define NT_STATUS_PASSWORD_MUST_CHANGE (0xC0000000 | 0x0224)
-#define NT_STATUS_NOT_FOUND (0xC0000000 | 0x0225)
-#define NT_STATUS_NOT_TINY_STREAM (0xC0000000 | 0x0226)
-#define NT_STATUS_RECOVERY_FAILURE (0xC0000000 | 0x0227)
-#define NT_STATUS_STACK_OVERFLOW_READ (0xC0000000 | 0x0228)
-#define NT_STATUS_FAIL_CHECK (0xC0000000 | 0x0229)
-#define NT_STATUS_DUPLICATE_OBJECTID (0xC0000000 | 0x022a)
-#define NT_STATUS_OBJECTID_EXISTS (0xC0000000 | 0x022b)
-#define NT_STATUS_CONVERT_TO_LARGE (0xC0000000 | 0x022c)
-#define NT_STATUS_RETRY (0xC0000000 | 0x022d)
-#define NT_STATUS_FOUND_OUT_OF_SCOPE (0xC0000000 | 0x022e)
-#define NT_STATUS_ALLOCATE_BUCKET (0xC0000000 | 0x022f)
-#define NT_STATUS_PROPSET_NOT_FOUND (0xC0000000 | 0x0230)
-#define NT_STATUS_MARSHALL_OVERFLOW (0xC0000000 | 0x0231)
-#define NT_STATUS_INVALID_VARIANT (0xC0000000 | 0x0232)
-#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xC0000000 | 0x0233)
-#define NT_STATUS_ACCOUNT_LOCKED_OUT (0xC0000000 | 0x0234)
-#define NT_STATUS_HANDLE_NOT_CLOSABLE (0xC0000000 | 0x0235)
-#define NT_STATUS_CONNECTION_REFUSED (0xC0000000 | 0x0236)
-#define NT_STATUS_GRACEFUL_DISCONNECT (0xC0000000 | 0x0237)
-#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (0xC0000000 | 0x0238)
-#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (0xC0000000 | 0x0239)
-#define NT_STATUS_CONNECTION_INVALID (0xC0000000 | 0x023a)
-#define NT_STATUS_CONNECTION_ACTIVE (0xC0000000 | 0x023b)
-#define NT_STATUS_NETWORK_UNREACHABLE (0xC0000000 | 0x023c)
-#define NT_STATUS_HOST_UNREACHABLE (0xC0000000 | 0x023d)
-#define NT_STATUS_PROTOCOL_UNREACHABLE (0xC0000000 | 0x023e)
-#define NT_STATUS_PORT_UNREACHABLE (0xC0000000 | 0x023f)
-#define NT_STATUS_REQUEST_ABORTED (0xC0000000 | 0x0240)
-#define NT_STATUS_CONNECTION_ABORTED (0xC0000000 | 0x0241)
-#define NT_STATUS_BAD_COMPRESSION_BUFFER (0xC0000000 | 0x0242)
-#define NT_STATUS_USER_MAPPED_FILE (0xC0000000 | 0x0243)
-#define NT_STATUS_AUDIT_FAILED (0xC0000000 | 0x0244)
-#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (0xC0000000 | 0x0245)
-#define NT_STATUS_CONNECTION_COUNT_LIMIT (0xC0000000 | 0x0246)
-#define NT_STATUS_LOGIN_TIME_RESTRICTION (0xC0000000 | 0x0247)
-#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (0xC0000000 | 0x0248)
-#define NT_STATUS_IMAGE_MP_UP_MISMATCH (0xC0000000 | 0x0249)
-#define NT_STATUS_INSUFFICIENT_LOGON_INFO (0xC0000000 | 0x0250)
-#define NT_STATUS_BAD_DLL_ENTRYPOINT (0xC0000000 | 0x0251)
-#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (0xC0000000 | 0x0252)
-#define NT_STATUS_LPC_REPLY_LOST (0xC0000000 | 0x0253)
-#define NT_STATUS_IP_ADDRESS_CONFLICT1 (0xC0000000 | 0x0254)
-#define NT_STATUS_IP_ADDRESS_CONFLICT2 (0xC0000000 | 0x0255)
-#define NT_STATUS_REGISTRY_QUOTA_LIMIT (0xC0000000 | 0x0256)
-#define NT_STATUS_PATH_NOT_COVERED (0xC0000000 | 0x0257)
-#define NT_STATUS_NO_CALLBACK_ACTIVE (0xC0000000 | 0x0258)
-#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (0xC0000000 | 0x0259)
-#define NT_STATUS_PWD_TOO_SHORT (0xC0000000 | 0x025a)
-#define NT_STATUS_PWD_TOO_RECENT (0xC0000000 | 0x025b)
-#define NT_STATUS_PWD_HISTORY_CONFLICT (0xC0000000 | 0x025c)
-#define NT_STATUS_PLUGPLAY_NO_DEVICE (0xC0000000 | 0x025e)
-#define NT_STATUS_UNSUPPORTED_COMPRESSION (0xC0000000 | 0x025f)
-#define NT_STATUS_INVALID_HW_PROFILE (0xC0000000 | 0x0260)
-#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (0xC0000000 | 0x0261)
-#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (0xC0000000 | 0x0262)
-#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (0xC0000000 | 0x0263)
-#define NT_STATUS_RESOURCE_NOT_OWNED (0xC0000000 | 0x0264)
-#define NT_STATUS_TOO_MANY_LINKS (0xC0000000 | 0x0265)
-#define NT_STATUS_QUOTA_LIST_INCONSISTENT (0xC0000000 | 0x0266)
-#define NT_STATUS_FILE_IS_OFFLINE (0xC0000000 | 0x0267)
-#define NT_STATUS_NO_SUCH_JOB (0xC0000000 | 0xEDE) /* scheduler */
+/*
+ --------------
+ / \
+ / REST \
+ / IN \
+ / PEACE \
+ / \
+ | NT_STATUS_NOPROBLEMO |
+ | |
+ | |
+ | 4 September |
+ | |
+ | 2001 |
+ *| * * * | *
+ _________)/\\_//(\/(/\)/\//\/\///|_)_______
+*/
+
+#define NT_STATUS_OK NT_STATUS(0x0000)
+#define NT_STATUS_UNSUCCESSFUL NT_STATUS(0xC0000000 | 0x0001)
+#define NT_STATUS_NOT_IMPLEMENTED NT_STATUS(0xC0000000 | 0x0002)
+#define NT_STATUS_INVALID_INFO_CLASS NT_STATUS(0xC0000000 | 0x0003)
+#define NT_STATUS_INFO_LENGTH_MISMATCH NT_STATUS(0xC0000000 | 0x0004)
+#define NT_STATUS_ACCESS_VIOLATION NT_STATUS(0xC0000000 | 0x0005)
+#define NT_STATUS_IN_PAGE_ERROR NT_STATUS(0xC0000000 | 0x0006)
+#define NT_STATUS_PAGEFILE_QUOTA NT_STATUS(0xC0000000 | 0x0007)
+#define NT_STATUS_INVALID_HANDLE NT_STATUS(0xC0000000 | 0x0008)
+#define NT_STATUS_BAD_INITIAL_STACK NT_STATUS(0xC0000000 | 0x0009)
+#define NT_STATUS_BAD_INITIAL_PC NT_STATUS(0xC0000000 | 0x000a)
+#define NT_STATUS_INVALID_CID NT_STATUS(0xC0000000 | 0x000b)
+#define NT_STATUS_TIMER_NOT_CANCELED NT_STATUS(0xC0000000 | 0x000c)
+#define NT_STATUS_INVALID_PARAMETER NT_STATUS(0xC0000000 | 0x000d)
+#define NT_STATUS_NO_SUCH_DEVICE NT_STATUS(0xC0000000 | 0x000e)
+#define NT_STATUS_NO_SUCH_FILE NT_STATUS(0xC0000000 | 0x000f)
+#define NT_STATUS_INVALID_DEVICE_REQUEST NT_STATUS(0xC0000000 | 0x0010)
+#define NT_STATUS_END_OF_FILE NT_STATUS(0xC0000000 | 0x0011)
+#define NT_STATUS_WRONG_VOLUME NT_STATUS(0xC0000000 | 0x0012)
+#define NT_STATUS_NO_MEDIA_IN_DEVICE NT_STATUS(0xC0000000 | 0x0013)
+#define NT_STATUS_UNRECOGNIZED_MEDIA NT_STATUS(0xC0000000 | 0x0014)
+#define NT_STATUS_NONEXISTENT_SECTOR NT_STATUS(0xC0000000 | 0x0015)
+#define NT_STATUS_MORE_PROCESSING_REQUIRED NT_STATUS(0xC0000000 | 0x0016)
+#define NT_STATUS_NO_MEMORY NT_STATUS(0xC0000000 | 0x0017)
+#define NT_STATUS_CONFLICTING_ADDRESSES NT_STATUS(0xC0000000 | 0x0018)
+#define NT_STATUS_NOT_MAPPED_VIEW NT_STATUS(0xC0000000 | 0x0019)
+#define NT_STATUS_UNABLE_TO_FREE_VM NT_STATUS(0xC0000000 | 0x001a)
+#define NT_STATUS_UNABLE_TO_DELETE_SECTION NT_STATUS(0xC0000000 | 0x001b)
+#define NT_STATUS_INVALID_SYSTEM_SERVICE NT_STATUS(0xC0000000 | 0x001c)
+#define NT_STATUS_ILLEGAL_INSTRUCTION NT_STATUS(0xC0000000 | 0x001d)
+#define NT_STATUS_INVALID_LOCK_SEQUENCE NT_STATUS(0xC0000000 | 0x001e)
+#define NT_STATUS_INVALID_VIEW_SIZE NT_STATUS(0xC0000000 | 0x001f)
+#define NT_STATUS_INVALID_FILE_FOR_SECTION NT_STATUS(0xC0000000 | 0x0020)
+#define NT_STATUS_ALREADY_COMMITTED NT_STATUS(0xC0000000 | 0x0021)
+#define NT_STATUS_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x0022)
+#define NT_STATUS_BUFFER_TOO_SMALL NT_STATUS(0xC0000000 | 0x0023)
+#define NT_STATUS_OBJECT_TYPE_MISMATCH NT_STATUS(0xC0000000 | 0x0024)
+#define NT_STATUS_NONCONTINUABLE_EXCEPTION NT_STATUS(0xC0000000 | 0x0025)
+#define NT_STATUS_INVALID_DISPOSITION NT_STATUS(0xC0000000 | 0x0026)
+#define NT_STATUS_UNWIND NT_STATUS(0xC0000000 | 0x0027)
+#define NT_STATUS_BAD_STACK NT_STATUS(0xC0000000 | 0x0028)
+#define NT_STATUS_INVALID_UNWIND_TARGET NT_STATUS(0xC0000000 | 0x0029)
+#define NT_STATUS_NOT_LOCKED NT_STATUS(0xC0000000 | 0x002a)
+#define NT_STATUS_PARITY_ERROR NT_STATUS(0xC0000000 | 0x002b)
+#define NT_STATUS_UNABLE_TO_DECOMMIT_VM NT_STATUS(0xC0000000 | 0x002c)
+#define NT_STATUS_NOT_COMMITTED NT_STATUS(0xC0000000 | 0x002d)
+#define NT_STATUS_INVALID_PORT_ATTRIBUTES NT_STATUS(0xC0000000 | 0x002e)
+#define NT_STATUS_PORT_MESSAGE_TOO_LONG NT_STATUS(0xC0000000 | 0x002f)
+#define NT_STATUS_INVALID_PARAMETER_MIX NT_STATUS(0xC0000000 | 0x0030)
+#define NT_STATUS_INVALID_QUOTA_LOWER NT_STATUS(0xC0000000 | 0x0031)
+#define NT_STATUS_DISK_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0032)
+#define NT_STATUS_OBJECT_NAME_INVALID NT_STATUS(0xC0000000 | 0x0033)
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x0034)
+#define NT_STATUS_OBJECT_NAME_COLLISION NT_STATUS(0xC0000000 | 0x0035)
+#define NT_STATUS_HANDLE_NOT_WAITABLE NT_STATUS(0xC0000000 | 0x0036)
+#define NT_STATUS_PORT_DISCONNECTED NT_STATUS(0xC0000000 | 0x0037)
+#define NT_STATUS_DEVICE_ALREADY_ATTACHED NT_STATUS(0xC0000000 | 0x0038)
+#define NT_STATUS_OBJECT_PATH_INVALID NT_STATUS(0xC0000000 | 0x0039)
+#define NT_STATUS_OBJECT_PATH_NOT_FOUND NT_STATUS(0xC0000000 | 0x003a)
+#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD NT_STATUS(0xC0000000 | 0x003b)
+#define NT_STATUS_DATA_OVERRUN NT_STATUS(0xC0000000 | 0x003c)
+#define NT_STATUS_DATA_LATE_ERROR NT_STATUS(0xC0000000 | 0x003d)
+#define NT_STATUS_DATA_ERROR NT_STATUS(0xC0000000 | 0x003e)
+#define NT_STATUS_CRC_ERROR NT_STATUS(0xC0000000 | 0x003f)
+#define NT_STATUS_SECTION_TOO_BIG NT_STATUS(0xC0000000 | 0x0040)
+#define NT_STATUS_PORT_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0041)
+#define NT_STATUS_INVALID_PORT_HANDLE NT_STATUS(0xC0000000 | 0x0042)
+#define NT_STATUS_SHARING_VIOLATION NT_STATUS(0xC0000000 | 0x0043)
+#define NT_STATUS_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0044)
+#define NT_STATUS_INVALID_PAGE_PROTECTION NT_STATUS(0xC0000000 | 0x0045)
+#define NT_STATUS_MUTANT_NOT_OWNED NT_STATUS(0xC0000000 | 0x0046)
+#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0047)
+#define NT_STATUS_PORT_ALREADY_SET NT_STATUS(0xC0000000 | 0x0048)
+#define NT_STATUS_SECTION_NOT_IMAGE NT_STATUS(0xC0000000 | 0x0049)
+#define NT_STATUS_SUSPEND_COUNT_EXCEEDED NT_STATUS(0xC0000000 | 0x004a)
+#define NT_STATUS_THREAD_IS_TERMINATING NT_STATUS(0xC0000000 | 0x004b)
+#define NT_STATUS_BAD_WORKING_SET_LIMIT NT_STATUS(0xC0000000 | 0x004c)
+#define NT_STATUS_INCOMPATIBLE_FILE_MAP NT_STATUS(0xC0000000 | 0x004d)
+#define NT_STATUS_SECTION_PROTECTION NT_STATUS(0xC0000000 | 0x004e)
+#define NT_STATUS_EAS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x004f)
+#define NT_STATUS_EA_TOO_LARGE NT_STATUS(0xC0000000 | 0x0050)
+#define NT_STATUS_NONEXISTENT_EA_ENTRY NT_STATUS(0xC0000000 | 0x0051)
+#define NT_STATUS_NO_EAS_ON_FILE NT_STATUS(0xC0000000 | 0x0052)
+#define NT_STATUS_EA_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0053)
+#define NT_STATUS_FILE_LOCK_CONFLICT NT_STATUS(0xC0000000 | 0x0054)
+#define NT_STATUS_LOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0055)
+#define NT_STATUS_DELETE_PENDING NT_STATUS(0xC0000000 | 0x0056)
+#define NT_STATUS_CTL_FILE_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x0057)
+#define NT_STATUS_UNKNOWN_REVISION NT_STATUS(0xC0000000 | 0x0058)
+#define NT_STATUS_REVISION_MISMATCH NT_STATUS(0xC0000000 | 0x0059)
+#define NT_STATUS_INVALID_OWNER NT_STATUS(0xC0000000 | 0x005a)
+#define NT_STATUS_INVALID_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x005b)
+#define NT_STATUS_NO_IMPERSONATION_TOKEN NT_STATUS(0xC0000000 | 0x005c)
+#define NT_STATUS_CANT_DISABLE_MANDATORY NT_STATUS(0xC0000000 | 0x005d)
+#define NT_STATUS_NO_LOGON_SERVERS NT_STATUS(0xC0000000 | 0x005e)
+#define NT_STATUS_NO_SUCH_LOGON_SESSION NT_STATUS(0xC0000000 | 0x005f)
+#define NT_STATUS_NO_SUCH_PRIVILEGE NT_STATUS(0xC0000000 | 0x0060)
+#define NT_STATUS_PRIVILEGE_NOT_HELD NT_STATUS(0xC0000000 | 0x0061)
+#define NT_STATUS_INVALID_ACCOUNT_NAME NT_STATUS(0xC0000000 | 0x0062)
+#define NT_STATUS_USER_EXISTS NT_STATUS(0xC0000000 | 0x0063)
+#define NT_STATUS_NO_SUCH_USER NT_STATUS(0xC0000000 | 0x0064)
+#define NT_STATUS_GROUP_EXISTS NT_STATUS(0xC0000000 | 0x0065)
+#define NT_STATUS_NO_SUCH_GROUP NT_STATUS(0xC0000000 | 0x0066)
+#define NT_STATUS_MEMBER_IN_GROUP NT_STATUS(0xC0000000 | 0x0067)
+#define NT_STATUS_MEMBER_NOT_IN_GROUP NT_STATUS(0xC0000000 | 0x0068)
+#define NT_STATUS_LAST_ADMIN NT_STATUS(0xC0000000 | 0x0069)
+#define NT_STATUS_WRONG_PASSWORD NT_STATUS(0xC0000000 | 0x006a)
+#define NT_STATUS_ILL_FORMED_PASSWORD NT_STATUS(0xC0000000 | 0x006b)
+#define NT_STATUS_PASSWORD_RESTRICTION NT_STATUS(0xC0000000 | 0x006c)
+#define NT_STATUS_LOGON_FAILURE NT_STATUS(0xC0000000 | 0x006d)
+#define NT_STATUS_ACCOUNT_RESTRICTION NT_STATUS(0xC0000000 | 0x006e)
+#define NT_STATUS_INVALID_LOGON_HOURS NT_STATUS(0xC0000000 | 0x006f)
+#define NT_STATUS_INVALID_WORKSTATION NT_STATUS(0xC0000000 | 0x0070)
+#define NT_STATUS_PASSWORD_EXPIRED NT_STATUS(0xC0000000 | 0x0071)
+#define NT_STATUS_ACCOUNT_DISABLED NT_STATUS(0xC0000000 | 0x0072)
+#define NT_STATUS_NONE_MAPPED NT_STATUS(0xC0000000 | 0x0073)
+#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0074)
+#define NT_STATUS_LUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0075)
+#define NT_STATUS_INVALID_SUB_AUTHORITY NT_STATUS(0xC0000000 | 0x0076)
+#define NT_STATUS_INVALID_ACL NT_STATUS(0xC0000000 | 0x0077)
+#define NT_STATUS_INVALID_SID NT_STATUS(0xC0000000 | 0x0078)
+#define NT_STATUS_INVALID_SECURITY_DESCR NT_STATUS(0xC0000000 | 0x0079)
+#define NT_STATUS_PROCEDURE_NOT_FOUND NT_STATUS(0xC0000000 | 0x007a)
+#define NT_STATUS_INVALID_IMAGE_FORMAT NT_STATUS(0xC0000000 | 0x007b)
+#define NT_STATUS_NO_TOKEN NT_STATUS(0xC0000000 | 0x007c)
+#define NT_STATUS_BAD_INHERITANCE_ACL NT_STATUS(0xC0000000 | 0x007d)
+#define NT_STATUS_RANGE_NOT_LOCKED NT_STATUS(0xC0000000 | 0x007e)
+#define NT_STATUS_DISK_FULL NT_STATUS(0xC0000000 | 0x007f)
+#define NT_STATUS_SERVER_DISABLED NT_STATUS(0xC0000000 | 0x0080)
+#define NT_STATUS_SERVER_NOT_DISABLED NT_STATUS(0xC0000000 | 0x0081)
+#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED NT_STATUS(0xC0000000 | 0x0082)
+#define NT_STATUS_GUIDS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0083)
+#define NT_STATUS_INVALID_ID_AUTHORITY NT_STATUS(0xC0000000 | 0x0084)
+#define NT_STATUS_AGENTS_EXHAUSTED NT_STATUS(0xC0000000 | 0x0085)
+#define NT_STATUS_INVALID_VOLUME_LABEL NT_STATUS(0xC0000000 | 0x0086)
+#define NT_STATUS_SECTION_NOT_EXTENDED NT_STATUS(0xC0000000 | 0x0087)
+#define NT_STATUS_NOT_MAPPED_DATA NT_STATUS(0xC0000000 | 0x0088)
+#define NT_STATUS_RESOURCE_DATA_NOT_FOUND NT_STATUS(0xC0000000 | 0x0089)
+#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND NT_STATUS(0xC0000000 | 0x008a)
+#define NT_STATUS_RESOURCE_NAME_NOT_FOUND NT_STATUS(0xC0000000 | 0x008b)
+#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED NT_STATUS(0xC0000000 | 0x008c)
+#define NT_STATUS_FLOAT_DENORMAL_OPERAND NT_STATUS(0xC0000000 | 0x008d)
+#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x008e)
+#define NT_STATUS_FLOAT_INEXACT_RESULT NT_STATUS(0xC0000000 | 0x008f)
+#define NT_STATUS_FLOAT_INVALID_OPERATION NT_STATUS(0xC0000000 | 0x0090)
+#define NT_STATUS_FLOAT_OVERFLOW NT_STATUS(0xC0000000 | 0x0091)
+#define NT_STATUS_FLOAT_STACK_CHECK NT_STATUS(0xC0000000 | 0x0092)
+#define NT_STATUS_FLOAT_UNDERFLOW NT_STATUS(0xC0000000 | 0x0093)
+#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO NT_STATUS(0xC0000000 | 0x0094)
+#define NT_STATUS_INTEGER_OVERFLOW NT_STATUS(0xC0000000 | 0x0095)
+#define NT_STATUS_PRIVILEGED_INSTRUCTION NT_STATUS(0xC0000000 | 0x0096)
+#define NT_STATUS_TOO_MANY_PAGING_FILES NT_STATUS(0xC0000000 | 0x0097)
+#define NT_STATUS_FILE_INVALID NT_STATUS(0xC0000000 | 0x0098)
+#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED NT_STATUS(0xC0000000 | 0x0099)
+#define NT_STATUS_INSUFFICIENT_RESOURCES NT_STATUS(0xC0000000 | 0x009a)
+#define NT_STATUS_DFS_EXIT_PATH_FOUND NT_STATUS(0xC0000000 | 0x009b)
+#define NT_STATUS_DEVICE_DATA_ERROR NT_STATUS(0xC0000000 | 0x009c)
+#define NT_STATUS_DEVICE_NOT_CONNECTED NT_STATUS(0xC0000000 | 0x009d)
+#define NT_STATUS_DEVICE_POWER_FAILURE NT_STATUS(0xC0000000 | 0x009e)
+#define NT_STATUS_FREE_VM_NOT_AT_BASE NT_STATUS(0xC0000000 | 0x009f)
+#define NT_STATUS_MEMORY_NOT_ALLOCATED NT_STATUS(0xC0000000 | 0x00a0)
+#define NT_STATUS_WORKING_SET_QUOTA NT_STATUS(0xC0000000 | 0x00a1)
+#define NT_STATUS_MEDIA_WRITE_PROTECTED NT_STATUS(0xC0000000 | 0x00a2)
+#define NT_STATUS_DEVICE_NOT_READY NT_STATUS(0xC0000000 | 0x00a3)
+#define NT_STATUS_INVALID_GROUP_ATTRIBUTES NT_STATUS(0xC0000000 | 0x00a4)
+#define NT_STATUS_BAD_IMPERSONATION_LEVEL NT_STATUS(0xC0000000 | 0x00a5)
+#define NT_STATUS_CANT_OPEN_ANONYMOUS NT_STATUS(0xC0000000 | 0x00a6)
+#define NT_STATUS_BAD_VALIDATION_CLASS NT_STATUS(0xC0000000 | 0x00a7)
+#define NT_STATUS_BAD_TOKEN_TYPE NT_STATUS(0xC0000000 | 0x00a8)
+#define NT_STATUS_BAD_MASTER_BOOT_RECORD NT_STATUS(0xC0000000 | 0x00a9)
+#define NT_STATUS_INSTRUCTION_MISALIGNMENT NT_STATUS(0xC0000000 | 0x00aa)
+#define NT_STATUS_INSTANCE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ab)
+#define NT_STATUS_PIPE_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x00ac)
+#define NT_STATUS_INVALID_PIPE_STATE NT_STATUS(0xC0000000 | 0x00ad)
+#define NT_STATUS_PIPE_BUSY NT_STATUS(0xC0000000 | 0x00ae)
+#define NT_STATUS_ILLEGAL_FUNCTION NT_STATUS(0xC0000000 | 0x00af)
+#define NT_STATUS_PIPE_DISCONNECTED NT_STATUS(0xC0000000 | 0x00b0)
+#define NT_STATUS_PIPE_CLOSING NT_STATUS(0xC0000000 | 0x00b1)
+#define NT_STATUS_PIPE_CONNECTED NT_STATUS(0xC0000000 | 0x00b2)
+#define NT_STATUS_PIPE_LISTENING NT_STATUS(0xC0000000 | 0x00b3)
+#define NT_STATUS_INVALID_READ_MODE NT_STATUS(0xC0000000 | 0x00b4)
+#define NT_STATUS_IO_TIMEOUT NT_STATUS(0xC0000000 | 0x00b5)
+#define NT_STATUS_FILE_FORCED_CLOSED NT_STATUS(0xC0000000 | 0x00b6)
+#define NT_STATUS_PROFILING_NOT_STARTED NT_STATUS(0xC0000000 | 0x00b7)
+#define NT_STATUS_PROFILING_NOT_STOPPED NT_STATUS(0xC0000000 | 0x00b8)
+#define NT_STATUS_COULD_NOT_INTERPRET NT_STATUS(0xC0000000 | 0x00b9)
+#define NT_STATUS_FILE_IS_A_DIRECTORY NT_STATUS(0xC0000000 | 0x00ba)
+#define NT_STATUS_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x00bb)
+#define NT_STATUS_REMOTE_NOT_LISTENING NT_STATUS(0xC0000000 | 0x00bc)
+#define NT_STATUS_DUPLICATE_NAME NT_STATUS(0xC0000000 | 0x00bd)
+#define NT_STATUS_BAD_NETWORK_PATH NT_STATUS(0xC0000000 | 0x00be)
+#define NT_STATUS_NETWORK_BUSY NT_STATUS(0xC0000000 | 0x00bf)
+#define NT_STATUS_DEVICE_DOES_NOT_EXIST NT_STATUS(0xC0000000 | 0x00c0)
+#define NT_STATUS_TOO_MANY_COMMANDS NT_STATUS(0xC0000000 | 0x00c1)
+#define NT_STATUS_ADAPTER_HARDWARE_ERROR NT_STATUS(0xC0000000 | 0x00c2)
+#define NT_STATUS_INVALID_NETWORK_RESPONSE NT_STATUS(0xC0000000 | 0x00c3)
+#define NT_STATUS_UNEXPECTED_NETWORK_ERROR NT_STATUS(0xC0000000 | 0x00c4)
+#define NT_STATUS_BAD_REMOTE_ADAPTER NT_STATUS(0xC0000000 | 0x00c5)
+#define NT_STATUS_PRINT_QUEUE_FULL NT_STATUS(0xC0000000 | 0x00c6)
+#define NT_STATUS_NO_SPOOL_SPACE NT_STATUS(0xC0000000 | 0x00c7)
+#define NT_STATUS_PRINT_CANCELLED NT_STATUS(0xC0000000 | 0x00c8)
+#define NT_STATUS_NETWORK_NAME_DELETED NT_STATUS(0xC0000000 | 0x00c9)
+#define NT_STATUS_NETWORK_ACCESS_DENIED NT_STATUS(0xC0000000 | 0x00ca)
+#define NT_STATUS_BAD_DEVICE_TYPE NT_STATUS(0xC0000000 | 0x00cb)
+#define NT_STATUS_BAD_NETWORK_NAME NT_STATUS(0xC0000000 | 0x00cc)
+#define NT_STATUS_TOO_MANY_NAMES NT_STATUS(0xC0000000 | 0x00cd)
+#define NT_STATUS_TOO_MANY_SESSIONS NT_STATUS(0xC0000000 | 0x00ce)
+#define NT_STATUS_SHARING_PAUSED NT_STATUS(0xC0000000 | 0x00cf)
+#define NT_STATUS_REQUEST_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x00d0)
+#define NT_STATUS_REDIRECTOR_PAUSED NT_STATUS(0xC0000000 | 0x00d1)
+#define NT_STATUS_NET_WRITE_FAULT NT_STATUS(0xC0000000 | 0x00d2)
+#define NT_STATUS_PROFILING_AT_LIMIT NT_STATUS(0xC0000000 | 0x00d3)
+#define NT_STATUS_NOT_SAME_DEVICE NT_STATUS(0xC0000000 | 0x00d4)
+#define NT_STATUS_FILE_RENAMED NT_STATUS(0xC0000000 | 0x00d5)
+#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED NT_STATUS(0xC0000000 | 0x00d6)
+#define NT_STATUS_NO_SECURITY_ON_OBJECT NT_STATUS(0xC0000000 | 0x00d7)
+#define NT_STATUS_CANT_WAIT NT_STATUS(0xC0000000 | 0x00d8)
+#define NT_STATUS_PIPE_EMPTY NT_STATUS(0xC0000000 | 0x00d9)
+#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO NT_STATUS(0xC0000000 | 0x00da)
+#define NT_STATUS_CANT_TERMINATE_SELF NT_STATUS(0xC0000000 | 0x00db)
+#define NT_STATUS_INVALID_SERVER_STATE NT_STATUS(0xC0000000 | 0x00dc)
+#define NT_STATUS_INVALID_DOMAIN_STATE NT_STATUS(0xC0000000 | 0x00dd)
+#define NT_STATUS_INVALID_DOMAIN_ROLE NT_STATUS(0xC0000000 | 0x00de)
+#define NT_STATUS_NO_SUCH_DOMAIN NT_STATUS(0xC0000000 | 0x00df)
+#define NT_STATUS_DOMAIN_EXISTS NT_STATUS(0xC0000000 | 0x00e0)
+#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x00e1)
+#define NT_STATUS_OPLOCK_NOT_GRANTED NT_STATUS(0xC0000000 | 0x00e2)
+#define NT_STATUS_INVALID_OPLOCK_PROTOCOL NT_STATUS(0xC0000000 | 0x00e3)
+#define NT_STATUS_INTERNAL_DB_CORRUPTION NT_STATUS(0xC0000000 | 0x00e4)
+#define NT_STATUS_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x00e5)
+#define NT_STATUS_GENERIC_NOT_MAPPED NT_STATUS(0xC0000000 | 0x00e6)
+#define NT_STATUS_BAD_DESCRIPTOR_FORMAT NT_STATUS(0xC0000000 | 0x00e7)
+#define NT_STATUS_INVALID_USER_BUFFER NT_STATUS(0xC0000000 | 0x00e8)
+#define NT_STATUS_UNEXPECTED_IO_ERROR NT_STATUS(0xC0000000 | 0x00e9)
+#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR NT_STATUS(0xC0000000 | 0x00ea)
+#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR NT_STATUS(0xC0000000 | 0x00eb)
+#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR NT_STATUS(0xC0000000 | 0x00ec)
+#define NT_STATUS_NOT_LOGON_PROCESS NT_STATUS(0xC0000000 | 0x00ed)
+#define NT_STATUS_LOGON_SESSION_EXISTS NT_STATUS(0xC0000000 | 0x00ee)
+#define NT_STATUS_INVALID_PARAMETER_1 NT_STATUS(0xC0000000 | 0x00ef)
+#define NT_STATUS_INVALID_PARAMETER_2 NT_STATUS(0xC0000000 | 0x00f0)
+#define NT_STATUS_INVALID_PARAMETER_3 NT_STATUS(0xC0000000 | 0x00f1)
+#define NT_STATUS_INVALID_PARAMETER_4 NT_STATUS(0xC0000000 | 0x00f2)
+#define NT_STATUS_INVALID_PARAMETER_5 NT_STATUS(0xC0000000 | 0x00f3)
+#define NT_STATUS_INVALID_PARAMETER_6 NT_STATUS(0xC0000000 | 0x00f4)
+#define NT_STATUS_INVALID_PARAMETER_7 NT_STATUS(0xC0000000 | 0x00f5)
+#define NT_STATUS_INVALID_PARAMETER_8 NT_STATUS(0xC0000000 | 0x00f6)
+#define NT_STATUS_INVALID_PARAMETER_9 NT_STATUS(0xC0000000 | 0x00f7)
+#define NT_STATUS_INVALID_PARAMETER_10 NT_STATUS(0xC0000000 | 0x00f8)
+#define NT_STATUS_INVALID_PARAMETER_11 NT_STATUS(0xC0000000 | 0x00f9)
+#define NT_STATUS_INVALID_PARAMETER_12 NT_STATUS(0xC0000000 | 0x00fa)
+#define NT_STATUS_REDIRECTOR_NOT_STARTED NT_STATUS(0xC0000000 | 0x00fb)
+#define NT_STATUS_REDIRECTOR_STARTED NT_STATUS(0xC0000000 | 0x00fc)
+#define NT_STATUS_STACK_OVERFLOW NT_STATUS(0xC0000000 | 0x00fd)
+#define NT_STATUS_NO_SUCH_PACKAGE NT_STATUS(0xC0000000 | 0x00fe)
+#define NT_STATUS_BAD_FUNCTION_TABLE NT_STATUS(0xC0000000 | 0x00ff)
+#define NT_STATUS_DIRECTORY_NOT_EMPTY NT_STATUS(0xC0000000 | 0x0101)
+#define NT_STATUS_FILE_CORRUPT_ERROR NT_STATUS(0xC0000000 | 0x0102)
+#define NT_STATUS_NOT_A_DIRECTORY NT_STATUS(0xC0000000 | 0x0103)
+#define NT_STATUS_BAD_LOGON_SESSION_STATE NT_STATUS(0xC0000000 | 0x0104)
+#define NT_STATUS_LOGON_SESSION_COLLISION NT_STATUS(0xC0000000 | 0x0105)
+#define NT_STATUS_NAME_TOO_LONG NT_STATUS(0xC0000000 | 0x0106)
+#define NT_STATUS_FILES_OPEN NT_STATUS(0xC0000000 | 0x0107)
+#define NT_STATUS_CONNECTION_IN_USE NT_STATUS(0xC0000000 | 0x0108)
+#define NT_STATUS_MESSAGE_NOT_FOUND NT_STATUS(0xC0000000 | 0x0109)
+#define NT_STATUS_PROCESS_IS_TERMINATING NT_STATUS(0xC0000000 | 0x010a)
+#define NT_STATUS_INVALID_LOGON_TYPE NT_STATUS(0xC0000000 | 0x010b)
+#define NT_STATUS_NO_GUID_TRANSLATION NT_STATUS(0xC0000000 | 0x010c)
+#define NT_STATUS_CANNOT_IMPERSONATE NT_STATUS(0xC0000000 | 0x010d)
+#define NT_STATUS_IMAGE_ALREADY_LOADED NT_STATUS(0xC0000000 | 0x010e)
+#define NT_STATUS_ABIOS_NOT_PRESENT NT_STATUS(0xC0000000 | 0x010f)
+#define NT_STATUS_ABIOS_LID_NOT_EXIST NT_STATUS(0xC0000000 | 0x0110)
+#define NT_STATUS_ABIOS_LID_ALREADY_OWNED NT_STATUS(0xC0000000 | 0x0111)
+#define NT_STATUS_ABIOS_NOT_LID_OWNER NT_STATUS(0xC0000000 | 0x0112)
+#define NT_STATUS_ABIOS_INVALID_COMMAND NT_STATUS(0xC0000000 | 0x0113)
+#define NT_STATUS_ABIOS_INVALID_LID NT_STATUS(0xC0000000 | 0x0114)
+#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE NT_STATUS(0xC0000000 | 0x0115)
+#define NT_STATUS_ABIOS_INVALID_SELECTOR NT_STATUS(0xC0000000 | 0x0116)
+#define NT_STATUS_NO_LDT NT_STATUS(0xC0000000 | 0x0117)
+#define NT_STATUS_INVALID_LDT_SIZE NT_STATUS(0xC0000000 | 0x0118)
+#define NT_STATUS_INVALID_LDT_OFFSET NT_STATUS(0xC0000000 | 0x0119)
+#define NT_STATUS_INVALID_LDT_DESCRIPTOR NT_STATUS(0xC0000000 | 0x011a)
+#define NT_STATUS_INVALID_IMAGE_NE_FORMAT NT_STATUS(0xC0000000 | 0x011b)
+#define NT_STATUS_RXACT_INVALID_STATE NT_STATUS(0xC0000000 | 0x011c)
+#define NT_STATUS_RXACT_COMMIT_FAILURE NT_STATUS(0xC0000000 | 0x011d)
+#define NT_STATUS_MAPPED_FILE_SIZE_ZERO NT_STATUS(0xC0000000 | 0x011e)
+#define NT_STATUS_TOO_MANY_OPENED_FILES NT_STATUS(0xC0000000 | 0x011f)
+#define NT_STATUS_CANCELLED NT_STATUS(0xC0000000 | 0x0120)
+#define NT_STATUS_CANNOT_DELETE NT_STATUS(0xC0000000 | 0x0121)
+#define NT_STATUS_INVALID_COMPUTER_NAME NT_STATUS(0xC0000000 | 0x0122)
+#define NT_STATUS_FILE_DELETED NT_STATUS(0xC0000000 | 0x0123)
+#define NT_STATUS_SPECIAL_ACCOUNT NT_STATUS(0xC0000000 | 0x0124)
+#define NT_STATUS_SPECIAL_GROUP NT_STATUS(0xC0000000 | 0x0125)
+#define NT_STATUS_SPECIAL_USER NT_STATUS(0xC0000000 | 0x0126)
+#define NT_STATUS_MEMBERS_PRIMARY_GROUP NT_STATUS(0xC0000000 | 0x0127)
+#define NT_STATUS_FILE_CLOSED NT_STATUS(0xC0000000 | 0x0128)
+#define NT_STATUS_TOO_MANY_THREADS NT_STATUS(0xC0000000 | 0x0129)
+#define NT_STATUS_THREAD_NOT_IN_PROCESS NT_STATUS(0xC0000000 | 0x012a)
+#define NT_STATUS_TOKEN_ALREADY_IN_USE NT_STATUS(0xC0000000 | 0x012b)
+#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x012c)
+#define NT_STATUS_COMMITMENT_LIMIT NT_STATUS(0xC0000000 | 0x012d)
+#define NT_STATUS_INVALID_IMAGE_LE_FORMAT NT_STATUS(0xC0000000 | 0x012e)
+#define NT_STATUS_INVALID_IMAGE_NOT_MZ NT_STATUS(0xC0000000 | 0x012f)
+#define NT_STATUS_INVALID_IMAGE_PROTECT NT_STATUS(0xC0000000 | 0x0130)
+#define NT_STATUS_INVALID_IMAGE_WIN_16 NT_STATUS(0xC0000000 | 0x0131)
+#define NT_STATUS_LOGON_SERVER_CONFLICT NT_STATUS(0xC0000000 | 0x0132)
+#define NT_STATUS_TIME_DIFFERENCE_AT_DC NT_STATUS(0xC0000000 | 0x0133)
+#define NT_STATUS_SYNCHRONIZATION_REQUIRED NT_STATUS(0xC0000000 | 0x0134)
+#define NT_STATUS_DLL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0135)
+#define NT_STATUS_OPEN_FAILED NT_STATUS(0xC0000000 | 0x0136)
+#define NT_STATUS_IO_PRIVILEGE_FAILED NT_STATUS(0xC0000000 | 0x0137)
+#define NT_STATUS_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0138)
+#define NT_STATUS_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0139)
+#define NT_STATUS_CONTROL_C_EXIT NT_STATUS(0xC0000000 | 0x013a)
+#define NT_STATUS_LOCAL_DISCONNECT NT_STATUS(0xC0000000 | 0x013b)
+#define NT_STATUS_REMOTE_DISCONNECT NT_STATUS(0xC0000000 | 0x013c)
+#define NT_STATUS_REMOTE_RESOURCES NT_STATUS(0xC0000000 | 0x013d)
+#define NT_STATUS_LINK_FAILED NT_STATUS(0xC0000000 | 0x013e)
+#define NT_STATUS_LINK_TIMEOUT NT_STATUS(0xC0000000 | 0x013f)
+#define NT_STATUS_INVALID_CONNECTION NT_STATUS(0xC0000000 | 0x0140)
+#define NT_STATUS_INVALID_ADDRESS NT_STATUS(0xC0000000 | 0x0141)
+#define NT_STATUS_DLL_INIT_FAILED NT_STATUS(0xC0000000 | 0x0142)
+#define NT_STATUS_MISSING_SYSTEMFILE NT_STATUS(0xC0000000 | 0x0143)
+#define NT_STATUS_UNHANDLED_EXCEPTION NT_STATUS(0xC0000000 | 0x0144)
+#define NT_STATUS_APP_INIT_FAILURE NT_STATUS(0xC0000000 | 0x0145)
+#define NT_STATUS_PAGEFILE_CREATE_FAILED NT_STATUS(0xC0000000 | 0x0146)
+#define NT_STATUS_NO_PAGEFILE NT_STATUS(0xC0000000 | 0x0147)
+#define NT_STATUS_INVALID_LEVEL NT_STATUS(0xC0000000 | 0x0148)
+#define NT_STATUS_WRONG_PASSWORD_CORE NT_STATUS(0xC0000000 | 0x0149)
+#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT NT_STATUS(0xC0000000 | 0x014a)
+#define NT_STATUS_PIPE_BROKEN NT_STATUS(0xC0000000 | 0x014b)
+#define NT_STATUS_REGISTRY_CORRUPT NT_STATUS(0xC0000000 | 0x014c)
+#define NT_STATUS_REGISTRY_IO_FAILED NT_STATUS(0xC0000000 | 0x014d)
+#define NT_STATUS_NO_EVENT_PAIR NT_STATUS(0xC0000000 | 0x014e)
+#define NT_STATUS_UNRECOGNIZED_VOLUME NT_STATUS(0xC0000000 | 0x014f)
+#define NT_STATUS_SERIAL_NO_DEVICE_INITED NT_STATUS(0xC0000000 | 0x0150)
+#define NT_STATUS_NO_SUCH_ALIAS NT_STATUS(0xC0000000 | 0x0151)
+#define NT_STATUS_MEMBER_NOT_IN_ALIAS NT_STATUS(0xC0000000 | 0x0152)
+#define NT_STATUS_MEMBER_IN_ALIAS NT_STATUS(0xC0000000 | 0x0153)
+#define NT_STATUS_ALIAS_EXISTS NT_STATUS(0xC0000000 | 0x0154)
+#define NT_STATUS_LOGON_NOT_GRANTED NT_STATUS(0xC0000000 | 0x0155)
+#define NT_STATUS_TOO_MANY_SECRETS NT_STATUS(0xC0000000 | 0x0156)
+#define NT_STATUS_SECRET_TOO_LONG NT_STATUS(0xC0000000 | 0x0157)
+#define NT_STATUS_INTERNAL_DB_ERROR NT_STATUS(0xC0000000 | 0x0158)
+#define NT_STATUS_FULLSCREEN_MODE NT_STATUS(0xC0000000 | 0x0159)
+#define NT_STATUS_TOO_MANY_CONTEXT_IDS NT_STATUS(0xC0000000 | 0x015a)
+#define NT_STATUS_LOGON_TYPE_NOT_GRANTED NT_STATUS(0xC0000000 | 0x015b)
+#define NT_STATUS_NOT_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x015c)
+#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x015d)
+#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR NT_STATUS(0xC0000000 | 0x015e)
+#define NT_STATUS_FT_MISSING_MEMBER NT_STATUS(0xC0000000 | 0x015f)
+#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY NT_STATUS(0xC0000000 | 0x0160)
+#define NT_STATUS_ILLEGAL_CHARACTER NT_STATUS(0xC0000000 | 0x0161)
+#define NT_STATUS_UNMAPPABLE_CHARACTER NT_STATUS(0xC0000000 | 0x0162)
+#define NT_STATUS_UNDEFINED_CHARACTER NT_STATUS(0xC0000000 | 0x0163)
+#define NT_STATUS_FLOPPY_VOLUME NT_STATUS(0xC0000000 | 0x0164)
+#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND NT_STATUS(0xC0000000 | 0x0165)
+#define NT_STATUS_FLOPPY_WRONG_CYLINDER NT_STATUS(0xC0000000 | 0x0166)
+#define NT_STATUS_FLOPPY_UNKNOWN_ERROR NT_STATUS(0xC0000000 | 0x0167)
+#define NT_STATUS_FLOPPY_BAD_REGISTERS NT_STATUS(0xC0000000 | 0x0168)
+#define NT_STATUS_DISK_RECALIBRATE_FAILED NT_STATUS(0xC0000000 | 0x0169)
+#define NT_STATUS_DISK_OPERATION_FAILED NT_STATUS(0xC0000000 | 0x016a)
+#define NT_STATUS_DISK_RESET_FAILED NT_STATUS(0xC0000000 | 0x016b)
+#define NT_STATUS_SHARED_IRQ_BUSY NT_STATUS(0xC0000000 | 0x016c)
+#define NT_STATUS_FT_ORPHANING NT_STATUS(0xC0000000 | 0x016d)
+#define NT_STATUS_PARTITION_FAILURE NT_STATUS(0xC0000000 | 0x0172)
+#define NT_STATUS_INVALID_BLOCK_LENGTH NT_STATUS(0xC0000000 | 0x0173)
+#define NT_STATUS_DEVICE_NOT_PARTITIONED NT_STATUS(0xC0000000 | 0x0174)
+#define NT_STATUS_UNABLE_TO_LOCK_MEDIA NT_STATUS(0xC0000000 | 0x0175)
+#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA NT_STATUS(0xC0000000 | 0x0176)
+#define NT_STATUS_EOM_OVERFLOW NT_STATUS(0xC0000000 | 0x0177)
+#define NT_STATUS_NO_MEDIA NT_STATUS(0xC0000000 | 0x0178)
+#define NT_STATUS_NO_SUCH_MEMBER NT_STATUS(0xC0000000 | 0x017a)
+#define NT_STATUS_INVALID_MEMBER NT_STATUS(0xC0000000 | 0x017b)
+#define NT_STATUS_KEY_DELETED NT_STATUS(0xC0000000 | 0x017c)
+#define NT_STATUS_NO_LOG_SPACE NT_STATUS(0xC0000000 | 0x017d)
+#define NT_STATUS_TOO_MANY_SIDS NT_STATUS(0xC0000000 | 0x017e)
+#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED NT_STATUS(0xC0000000 | 0x017f)
+#define NT_STATUS_KEY_HAS_CHILDREN NT_STATUS(0xC0000000 | 0x0180)
+#define NT_STATUS_CHILD_MUST_BE_VOLATILE NT_STATUS(0xC0000000 | 0x0181)
+#define NT_STATUS_DEVICE_CONFIGURATION_ERROR NT_STATUS(0xC0000000 | 0x0182)
+#define NT_STATUS_DRIVER_INTERNAL_ERROR NT_STATUS(0xC0000000 | 0x0183)
+#define NT_STATUS_INVALID_DEVICE_STATE NT_STATUS(0xC0000000 | 0x0184)
+#define NT_STATUS_IO_DEVICE_ERROR NT_STATUS(0xC0000000 | 0x0185)
+#define NT_STATUS_DEVICE_PROTOCOL_ERROR NT_STATUS(0xC0000000 | 0x0186)
+#define NT_STATUS_BACKUP_CONTROLLER NT_STATUS(0xC0000000 | 0x0187)
+#define NT_STATUS_LOG_FILE_FULL NT_STATUS(0xC0000000 | 0x0188)
+#define NT_STATUS_TOO_LATE NT_STATUS(0xC0000000 | 0x0189)
+#define NT_STATUS_NO_TRUST_LSA_SECRET NT_STATUS(0xC0000000 | 0x018a)
+#define NT_STATUS_NO_TRUST_SAM_ACCOUNT NT_STATUS(0xC0000000 | 0x018b)
+#define NT_STATUS_TRUSTED_DOMAIN_FAILURE NT_STATUS(0xC0000000 | 0x018c)
+#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE NT_STATUS(0xC0000000 | 0x018d)
+#define NT_STATUS_EVENTLOG_FILE_CORRUPT NT_STATUS(0xC0000000 | 0x018e)
+#define NT_STATUS_EVENTLOG_CANT_START NT_STATUS(0xC0000000 | 0x018f)
+#define NT_STATUS_TRUST_FAILURE NT_STATUS(0xC0000000 | 0x0190)
+#define NT_STATUS_MUTANT_LIMIT_EXCEEDED NT_STATUS(0xC0000000 | 0x0191)
+#define NT_STATUS_NETLOGON_NOT_STARTED NT_STATUS(0xC0000000 | 0x0192)
+#define NT_STATUS_ACCOUNT_EXPIRED NT_STATUS(0xC0000000 | 0x0193)
+#define NT_STATUS_POSSIBLE_DEADLOCK NT_STATUS(0xC0000000 | 0x0194)
+#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT NT_STATUS(0xC0000000 | 0x0195)
+#define NT_STATUS_REMOTE_SESSION_LIMIT NT_STATUS(0xC0000000 | 0x0196)
+#define NT_STATUS_EVENTLOG_FILE_CHANGED NT_STATUS(0xC0000000 | 0x0197)
+#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0198)
+#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x0199)
+#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT NT_STATUS(0xC0000000 | 0x019a)
+#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT NT_STATUS(0xC0000000 | 0x019b)
+#define NT_STATUS_FS_DRIVER_REQUIRED NT_STATUS(0xC0000000 | 0x019c)
+#define NT_STATUS_NO_USER_SESSION_KEY NT_STATUS(0xC0000000 | 0x0202)
+#define NT_STATUS_USER_SESSION_DELETED NT_STATUS(0xC0000000 | 0x0203)
+#define NT_STATUS_RESOURCE_LANG_NOT_FOUND NT_STATUS(0xC0000000 | 0x0204)
+#define NT_STATUS_INSUFF_SERVER_RESOURCES NT_STATUS(0xC0000000 | 0x0205)
+#define NT_STATUS_INVALID_BUFFER_SIZE NT_STATUS(0xC0000000 | 0x0206)
+#define NT_STATUS_INVALID_ADDRESS_COMPONENT NT_STATUS(0xC0000000 | 0x0207)
+#define NT_STATUS_INVALID_ADDRESS_WILDCARD NT_STATUS(0xC0000000 | 0x0208)
+#define NT_STATUS_TOO_MANY_ADDRESSES NT_STATUS(0xC0000000 | 0x0209)
+#define NT_STATUS_ADDRESS_ALREADY_EXISTS NT_STATUS(0xC0000000 | 0x020a)
+#define NT_STATUS_ADDRESS_CLOSED NT_STATUS(0xC0000000 | 0x020b)
+#define NT_STATUS_CONNECTION_DISCONNECTED NT_STATUS(0xC0000000 | 0x020c)
+#define NT_STATUS_CONNECTION_RESET NT_STATUS(0xC0000000 | 0x020d)
+#define NT_STATUS_TOO_MANY_NODES NT_STATUS(0xC0000000 | 0x020e)
+#define NT_STATUS_TRANSACTION_ABORTED NT_STATUS(0xC0000000 | 0x020f)
+#define NT_STATUS_TRANSACTION_TIMED_OUT NT_STATUS(0xC0000000 | 0x0210)
+#define NT_STATUS_TRANSACTION_NO_RELEASE NT_STATUS(0xC0000000 | 0x0211)
+#define NT_STATUS_TRANSACTION_NO_MATCH NT_STATUS(0xC0000000 | 0x0212)
+#define NT_STATUS_TRANSACTION_RESPONDED NT_STATUS(0xC0000000 | 0x0213)
+#define NT_STATUS_TRANSACTION_INVALID_ID NT_STATUS(0xC0000000 | 0x0214)
+#define NT_STATUS_TRANSACTION_INVALID_TYPE NT_STATUS(0xC0000000 | 0x0215)
+#define NT_STATUS_NOT_SERVER_SESSION NT_STATUS(0xC0000000 | 0x0216)
+#define NT_STATUS_NOT_CLIENT_SESSION NT_STATUS(0xC0000000 | 0x0217)
+#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE NT_STATUS(0xC0000000 | 0x0218)
+#define NT_STATUS_DEBUG_ATTACH_FAILED NT_STATUS(0xC0000000 | 0x0219)
+#define NT_STATUS_SYSTEM_PROCESS_TERMINATED NT_STATUS(0xC0000000 | 0x021a)
+#define NT_STATUS_DATA_NOT_ACCEPTED NT_STATUS(0xC0000000 | 0x021b)
+#define NT_STATUS_NO_BROWSER_SERVERS_FOUND NT_STATUS(0xC0000000 | 0x021c)
+#define NT_STATUS_VDM_HARD_ERROR NT_STATUS(0xC0000000 | 0x021d)
+#define NT_STATUS_DRIVER_CANCEL_TIMEOUT NT_STATUS(0xC0000000 | 0x021e)
+#define NT_STATUS_REPLY_MESSAGE_MISMATCH NT_STATUS(0xC0000000 | 0x021f)
+#define NT_STATUS_MAPPED_ALIGNMENT NT_STATUS(0xC0000000 | 0x0220)
+#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH NT_STATUS(0xC0000000 | 0x0221)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA NT_STATUS(0xC0000000 | 0x0222)
+#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID NT_STATUS(0xC0000000 | 0x0223)
+#define NT_STATUS_PASSWORD_MUST_CHANGE NT_STATUS(0xC0000000 | 0x0224)
+#define NT_STATUS_NOT_FOUND NT_STATUS(0xC0000000 | 0x0225)
+#define NT_STATUS_NOT_TINY_STREAM NT_STATUS(0xC0000000 | 0x0226)
+#define NT_STATUS_RECOVERY_FAILURE NT_STATUS(0xC0000000 | 0x0227)
+#define NT_STATUS_STACK_OVERFLOW_READ NT_STATUS(0xC0000000 | 0x0228)
+#define NT_STATUS_FAIL_CHECK NT_STATUS(0xC0000000 | 0x0229)
+#define NT_STATUS_DUPLICATE_OBJECTID NT_STATUS(0xC0000000 | 0x022a)
+#define NT_STATUS_OBJECTID_EXISTS NT_STATUS(0xC0000000 | 0x022b)
+#define NT_STATUS_CONVERT_TO_LARGE NT_STATUS(0xC0000000 | 0x022c)
+#define NT_STATUS_RETRY NT_STATUS(0xC0000000 | 0x022d)
+#define NT_STATUS_FOUND_OUT_OF_SCOPE NT_STATUS(0xC0000000 | 0x022e)
+#define NT_STATUS_ALLOCATE_BUCKET NT_STATUS(0xC0000000 | 0x022f)
+#define NT_STATUS_PROPSET_NOT_FOUND NT_STATUS(0xC0000000 | 0x0230)
+#define NT_STATUS_MARSHALL_OVERFLOW NT_STATUS(0xC0000000 | 0x0231)
+#define NT_STATUS_INVALID_VARIANT NT_STATUS(0xC0000000 | 0x0232)
+#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND NT_STATUS(0xC0000000 | 0x0233)
+#define NT_STATUS_ACCOUNT_LOCKED_OUT NT_STATUS(0xC0000000 | 0x0234)
+#define NT_STATUS_HANDLE_NOT_CLOSABLE NT_STATUS(0xC0000000 | 0x0235)
+#define NT_STATUS_CONNECTION_REFUSED NT_STATUS(0xC0000000 | 0x0236)
+#define NT_STATUS_GRACEFUL_DISCONNECT NT_STATUS(0xC0000000 | 0x0237)
+#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED NT_STATUS(0xC0000000 | 0x0238)
+#define NT_STATUS_ADDRESS_NOT_ASSOCIATED NT_STATUS(0xC0000000 | 0x0239)
+#define NT_STATUS_CONNECTION_INVALID NT_STATUS(0xC0000000 | 0x023a)
+#define NT_STATUS_CONNECTION_ACTIVE NT_STATUS(0xC0000000 | 0x023b)
+#define NT_STATUS_NETWORK_UNREACHABLE NT_STATUS(0xC0000000 | 0x023c)
+#define NT_STATUS_HOST_UNREACHABLE NT_STATUS(0xC0000000 | 0x023d)
+#define NT_STATUS_PROTOCOL_UNREACHABLE NT_STATUS(0xC0000000 | 0x023e)
+#define NT_STATUS_PORT_UNREACHABLE NT_STATUS(0xC0000000 | 0x023f)
+#define NT_STATUS_REQUEST_ABORTED NT_STATUS(0xC0000000 | 0x0240)
+#define NT_STATUS_CONNECTION_ABORTED NT_STATUS(0xC0000000 | 0x0241)
+#define NT_STATUS_BAD_COMPRESSION_BUFFER NT_STATUS(0xC0000000 | 0x0242)
+#define NT_STATUS_USER_MAPPED_FILE NT_STATUS(0xC0000000 | 0x0243)
+#define NT_STATUS_AUDIT_FAILED NT_STATUS(0xC0000000 | 0x0244)
+#define NT_STATUS_TIMER_RESOLUTION_NOT_SET NT_STATUS(0xC0000000 | 0x0245)
+#define NT_STATUS_CONNECTION_COUNT_LIMIT NT_STATUS(0xC0000000 | 0x0246)
+#define NT_STATUS_LOGIN_TIME_RESTRICTION NT_STATUS(0xC0000000 | 0x0247)
+#define NT_STATUS_LOGIN_WKSTA_RESTRICTION NT_STATUS(0xC0000000 | 0x0248)
+#define NT_STATUS_IMAGE_MP_UP_MISMATCH NT_STATUS(0xC0000000 | 0x0249)
+#define NT_STATUS_INSUFFICIENT_LOGON_INFO NT_STATUS(0xC0000000 | 0x0250)
+#define NT_STATUS_BAD_DLL_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0251)
+#define NT_STATUS_BAD_SERVICE_ENTRYPOINT NT_STATUS(0xC0000000 | 0x0252)
+#define NT_STATUS_LPC_REPLY_LOST NT_STATUS(0xC0000000 | 0x0253)
+#define NT_STATUS_IP_ADDRESS_CONFLICT1 NT_STATUS(0xC0000000 | 0x0254)
+#define NT_STATUS_IP_ADDRESS_CONFLICT2 NT_STATUS(0xC0000000 | 0x0255)
+#define NT_STATUS_REGISTRY_QUOTA_LIMIT NT_STATUS(0xC0000000 | 0x0256)
+#define NT_STATUS_PATH_NOT_COVERED NT_STATUS(0xC0000000 | 0x0257)
+#define NT_STATUS_NO_CALLBACK_ACTIVE NT_STATUS(0xC0000000 | 0x0258)
+#define NT_STATUS_LICENSE_QUOTA_EXCEEDED NT_STATUS(0xC0000000 | 0x0259)
+#define NT_STATUS_PWD_TOO_SHORT NT_STATUS(0xC0000000 | 0x025a)
+#define NT_STATUS_PWD_TOO_RECENT NT_STATUS(0xC0000000 | 0x025b)
+#define NT_STATUS_PWD_HISTORY_CONFLICT NT_STATUS(0xC0000000 | 0x025c)
+#define NT_STATUS_PLUGPLAY_NO_DEVICE NT_STATUS(0xC0000000 | 0x025e)
+#define NT_STATUS_UNSUPPORTED_COMPRESSION NT_STATUS(0xC0000000 | 0x025f)
+#define NT_STATUS_INVALID_HW_PROFILE NT_STATUS(0xC0000000 | 0x0260)
+#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH NT_STATUS(0xC0000000 | 0x0261)
+#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND NT_STATUS(0xC0000000 | 0x0262)
+#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND NT_STATUS(0xC0000000 | 0x0263)
+#define NT_STATUS_RESOURCE_NOT_OWNED NT_STATUS(0xC0000000 | 0x0264)
+#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265)
+#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266)
+#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267)
+#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */
#endif /* _NTERR_H */
diff --git a/source/include/profile.h b/source/include/profile.h
index fbd83d6e3e1..149c0a73157 100644
--- a/source/include/profile.h
+++ b/source/include/profile.h
@@ -35,7 +35,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 5
+#define PROF_SHM_VERSION 6
/* time values in the following structure are in microseconds */
@@ -100,6 +100,12 @@ struct profile_stats {
unsigned syscall_readlink_time;
unsigned syscall_symlink_count;
unsigned syscall_symlink_time;
+ unsigned syscall_link_count;
+ unsigned syscall_link_time;
+ unsigned syscall_mknod_count;
+ unsigned syscall_mknod_time;
+ unsigned syscall_realpath_count;
+ unsigned syscall_realpath_time;
/* stat cache counters */
unsigned statcache_lookups;
unsigned statcache_misses;
diff --git a/source/include/proto.h b/source/include/proto.h
index 285a0b79825..4d52cf9d370 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -66,7 +66,7 @@ BOOL dbghdr( int level, char *file, char *func, int line );
/*The following definitions come from lib/error.c */
-uint32 map_nt_error_from_unix(int unix_error);
+NTSTATUS map_nt_error_from_unix(int unix_error);
/*The following definitions come from lib/fault.c */
@@ -146,7 +146,7 @@ void pidfile_create(char *name);
/*The following definitions come from lib/readline.c */
char *smb_readline(char *prompt, void (*callback)(void),
- char **(completion_fn)(char *text, int start, int end));
+ char **(completion_fn)(const char *text, int start, int end));
void cmd_history(void);
/*The following definitions come from lib/replace.c */
@@ -156,8 +156,8 @@ char *rep_inet_ntoa(struct in_addr ip);
/*The following definitions come from lib/select.c */
void sys_select_signal(void);
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval);
-int sys_select_intr(int maxfd, fd_set *fds,struct timeval *tval);
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
/*The following definitions come from lib/signal.c */
@@ -166,10 +166,608 @@ void CatchSignal(int signum,void (*handler)(int ));
void CatchChild(void);
void CatchChildLeaveStatus(void);
+/*The following definitions come from libsmb/cliconnect.c */
+
+BOOL cli_session_setup(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *workgroup);
+BOOL cli_ulogoff(struct cli_state *cli);
+BOOL cli_send_tconX(struct cli_state *cli,
+ const char *share, const char *dev, const char *pass, int passlen);
+BOOL cli_tdis(struct cli_state *cli);
+void cli_negprot_send(struct cli_state *cli);
+BOOL cli_negprot(struct cli_state *cli);
+BOOL cli_session_request(struct cli_state *cli,
+ struct nmb_name *calling, struct nmb_name *called);
+BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
+BOOL cli_establish_connection(struct cli_state *cli,
+ char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ char *service, char *service_type,
+ BOOL do_shutdown, BOOL do_tcon);
+BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
+ struct in_addr *pdest_ip);
+
+/*The following definitions come from libsmb/cli_dfs.c */
+
+struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL *dfs_exists);
+NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ char *comment, uint32 flags);
+NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename);
+NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *entrypath, char *servername, char *sharename,
+ uint32 info_level, DFS_INFO_CTR *ctr);
+NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 info_level, DFS_INFO_CTR *ctr);
+
+/*The following definitions come from libsmb/clidgram.c */
+
+int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot,
+ char *buf, int len,
+ const char *srcname, int src_type,
+ const char *dstname, int dest_type,
+ struct in_addr dest_ip, struct in_addr src_ip,
+ int dest_port, int src_port);
+int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int bufsiz);
+int cli_get_backup_list(const char *myname, const char *send_to_name);
+int cli_get_backup_server(char *my_name, char *target, char *servername, int namesize);
+
+/*The following definitions come from libsmb/clientgen.c */
+
+int cli_set_port(struct cli_state *cli, int port);
+BOOL cli_receive_smb(struct cli_state *cli);
+BOOL cli_send_smb(struct cli_state *cli);
+void cli_setup_packet(struct cli_state *cli);
+void cli_setup_bcc(struct cli_state *cli, void *p);
+void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
+struct cli_state *cli_initialise(struct cli_state *cli);
+void cli_shutdown(struct cli_state *cli);
+void cli_sockopt(struct cli_state *cli, char *options);
+uint16 cli_setpid(struct cli_state *cli, uint16 pid);
+
+/*The following definitions come from libsmb/clierror.c */
+
+char *cli_errstr(struct cli_state *cli);
+NTSTATUS cli_nt_error(struct cli_state *cli);
+void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode);
+int cli_errno_from_dos(uint8 eclass, uint32 num);
+int cli_errno_from_nt(NTSTATUS status);
+int cli_errno(struct cli_state *cli);
+BOOL cli_is_error(struct cli_state *cli);
+BOOL cli_is_nt_error(struct cli_state *cli);
+BOOL cli_is_dos_error(struct cli_state *cli);
+
+/*The following definitions come from libsmb/clifile.c */
+
+uint32 unix_perms_to_wire(mode_t perms);
+BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
+BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid);
+BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst);
+BOOL cli_unlink(struct cli_state *cli, const char *fname);
+BOOL cli_mkdir(struct cli_state *cli, const char *dname);
+BOOL cli_rmdir(struct cli_state *cli, const char *dname);
+int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag);
+int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess,
+ uint32 FileAttributes, uint32 ShareAccess,
+ uint32 CreateDisposition, uint32 CreateOptions);
+int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess);
+int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode);
+BOOL cli_close(struct cli_state *cli, int fnum);
+BOOL cli_lock(struct cli_state *cli, int fnum,
+ uint32 offset, uint32 len, int timeout, enum brl_type lock_type);
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len);
+BOOL cli_lock64(struct cli_state *cli, int fnum,
+ SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type);
+BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len);
+BOOL cli_getattrE(struct cli_state *cli, int fd,
+ uint16 *attr, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time);
+BOOL cli_getatr(struct cli_state *cli, const char *fname,
+ uint16 *attr, size_t *size, time_t *t);
+BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t);
+BOOL cli_chkpath(struct cli_state *cli, const char *path);
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
+int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path);
+
+/*The following definitions come from libsmb/clilist.c */
+
+int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *, void *), void *state);
+
+/*The following definitions come from libsmb/cli_lsarpc.c */
+
+struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol);
+NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol);
+NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol);
+NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_sids, DOM_SID *sids,
+ char ***names, uint32 **types, int *num_names);
+NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_names, char **names,
+ DOM_SID **sids, uint32 **types, int *num_sids);
+NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid);
+NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx,
+ uint32 *num_domains, char ***domain_names,
+ DOM_SID **domain_sids);
+NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
+ uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low);
+NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys,
+ fstring description, uint16 *lang_id_desc);
+NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
+ uint32 *num_sids, DOM_SID **sids);
+BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid);
+
+/*The following definitions come from libsmb/climessage.c */
+
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
+ int *grp);
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
+BOOL cli_message_end(struct cli_state *cli, int grp);
+
+/*The following definitions come from libsmb/cli_netlogon.c */
+
+struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal);
+NTSTATUS new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal);
+NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli,
+ unsigned char mach_pwd[16]);
+NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 query_level);
+NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas);
+NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, UINT64_S seqnum,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas);
+NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *username, char *password,
+ int logon_type);
+
+/*The following definitions come from libsmb/clioplock.c */
+
+BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level);
+void cli_oplock_handler(struct cli_state *cli,
+ BOOL (*handler)(struct cli_state *, int, unsigned char));
+
+/*The following definitions come from libsmb/cli_pipe_util.c */
+
+struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name,
+ char *pipe_name,
+ struct ntuser_creds *creds);
+void cli_pipe_shutdown(struct cli_state *cli);
+
+/*The following definitions come from libsmb/cliprint.c */
+
+int cli_print_queue(struct cli_state *cli,
+ void (*fn)(struct print_job_info *));
+int cli_printjob_del(struct cli_state *cli, int job);
+
+/*The following definitions come from libsmb/clirap.c */
+
+BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+ char **rparam, uint32 *rparam_count,
+ char **rdata, uint32 *rdata_count);
+BOOL cli_api(struct cli_state *cli,
+ char *param, int prcnt, int mprcnt,
+ char *data, int drcnt, int mdrcnt,
+ char **rparam, int *rprcnt,
+ char **rdata, int *rdrcnt);
+BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state);
+BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
+ void (*fn)(const char *, uint32, const char *, void *),
+ void *state);
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password);
+BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ size_t *size, uint16 *mode);
+BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, size_t *size, uint16 *mode,
+ SMB_INO_T *ino);
+BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino);
+BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata);
+NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name);
+
+/*The following definitions come from libsmb/clireadwrite.c */
+
+ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+ssize_t cli_write(struct cli_state *cli,
+ int fnum, uint16 write_mode,
+ char *buf, off_t offset, size_t size);
+ssize_t cli_smbwrite(struct cli_state *cli,
+ int fnum, char *buf, off_t offset, size_t size1);
+
+/*The following definitions come from libsmb/cli_reg.c */
+
+struct cli_state *cli_winreg_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32 timeout, uint16 flags);
+NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx);
+
+/*The following definitions come from libsmb/cli_samr.c */
+
+struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 access_mask, POLICY_HND *connect_pol);
+NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol);
+NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol, uint32 access_mask,
+ DOM_SID *domain_sid, POLICY_HND *domain_pol);
+NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 user_rid, POLICY_HND *user_pol);
+NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol);
+NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ SAM_USERINFO_CTR **ctr);
+NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 info_level,
+ GROUP_INFO_CTR *ctr);
+NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint32 *num_groups,
+ DOM_GID **gid);
+NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups);
+NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint32 *num_mem,
+ DOM_SID **sids);
+NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 alias_rid, POLICY_HND *alias_pol);
+NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 *start_idx,
+ uint16 switch_value, uint32 *num_entries,
+ uint32 max_entries, SAM_DISPINFO_CTR *ctr);
+NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types);
+NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types);
+NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, char *acct_name,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid);
+NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol);
+
+/*The following definitions come from libsmb/clisecdesc.c */
+
+SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
+ TALLOC_CTX *mem_ctx);
+BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd);
+
+/*The following definitions come from libsmb/cli_spoolss.c */
+
+struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_spoolss_open_printer_ex(
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char *printername,
+ char *datatype,
+ uint32 access_required,
+ char *station,
+ char *username,
+ POLICY_HND *pol
+);
+NTSTATUS cli_spoolss_close_printer(
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol
+);
+NTSTATUS cli_spoolss_enum_printers(
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 flags,
+ uint32 level,
+ int *returned,
+ PRINTER_INFO_CTR *ctr
+);
+NTSTATUS cli_spoolss_enum_ports(
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ int *returned,
+ PORT_INFO_CTR *ctr
+);
+NTSTATUS cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr);
+NTSTATUS cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr,
+ uint32 command);
+NTSTATUS cli_spoolss_getprinterdriver (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, char* env,
+ PRINTER_DRIVER_CTR *ctr);
+NTSTATUS cli_spoolss_enumprinterdrivers (
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ char* env,
+ uint32 *returned,
+ PRINTER_DRIVER_CTR *ctr
+);
+NTSTATUS cli_spoolss_getprinterdriverdir (
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ char* env,
+ DRIVER_DIRECTORY_CTR *ctr
+);
+NTSTATUS cli_spoolss_addprinterdriver (
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ PRINTER_DRIVER_CTR *ctr
+);
+NTSTATUS cli_spoolss_addprinterex (
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ PRINTER_INFO_CTR *ctr
+);
+NTSTATUS cli_spoolss_deleteprinterdriver (
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char *arch,
+ char *driver
+);
+NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char *name,
+ char *environment,
+ fstring procdir);
+NTSTATUS cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char* valname, char* value);
+
+/*The following definitions come from libsmb/cli_srvsvc.c */
+
+struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
+ char *system_name,
+ struct ntuser_creds *creds);
+NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 switch_value, SRV_INFO_CTR *ctr);
+
+/*The following definitions come from libsmb/clistr.c */
+
+int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags);
+int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags);
+int clistr_align_out(struct cli_state *cli, const void *p, int flags);
+int clistr_align_in(struct cli_state *cli, const void *p, int flags);
+
+/*The following definitions come from libsmb/clitrans.c */
+
+BOOL cli_send_trans(struct cli_state *cli, int trans,
+ const char *pipe_name,
+ int fid, int flags,
+ uint16 *setup, int lsetup, int msetup,
+ char *param, int lparam, int mparam,
+ char *data, int ldata, int mdata);
+BOOL cli_receive_trans(struct cli_state *cli,int trans,
+ char **param, int *param_len,
+ char **data, int *data_len);
+BOOL cli_send_nt_trans(struct cli_state *cli,
+ int function,
+ int flags,
+ uint16 *setup, int lsetup, int msetup,
+ char *param, int lparam, int mparam,
+ char *data, int ldata, int mdata);
+BOOL cli_receive_nt_trans(struct cli_state *cli,
+ char **param, int *param_len,
+ char **data, int *data_len);
+
+/*The following definitions come from libsmb/credentials.c */
+
+char *credstr(uchar *cred);
+void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
+ uchar session_key[8]);
+void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
+ DOM_CHAL *cred);
+int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
+ UTIME timestamp);
+BOOL clnt_deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
+BOOL deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred,
+ DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
+
+/*The following definitions come from libsmb/errormap.c */
+
+NTSTATUS dos_to_ntstatus(int eclass, int ecode);
+void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode);
+NTSTATUS werror_to_ntstatus(WERROR error);
+WERROR ntstatus_to_werror(NTSTATUS error);
+
+/*The following definitions come from libsmb/namequery.c */
+
+struct node_status *node_status_query(int fd,struct nmb_name *name,
+ struct in_addr to_ip, int *num_names);
+BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name);
+BOOL name_register(int fd, const char *name, int name_type,
+ struct in_addr name_ip, int opcode,
+ BOOL bcast,
+ struct in_addr to_ip, int *count);
+struct in_addr *name_query(int fd,const char *name,int name_type,
+ BOOL bcast,BOOL recurse,
+ struct in_addr to_ip, int *count);
+FILE *startlmhosts(char *fname);
+BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
+void endlmhosts(FILE *fp);
+BOOL name_register_wins(const char *name, int name_type);
+BOOL name_resolve_bcast(const char *name, int name_type,
+ struct in_addr **return_ip_list, int *return_count);
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
+BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
+ struct in_addr *ip);
+BOOL find_master_ip(char *group, struct in_addr *master_ip);
+BOOL lookup_dc_name(const char *srcname, const char *domain,
+ struct in_addr *dc_ip, char *ret_name);
+BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count);
+BOOL get_lmb_list(struct in_addr **ip_list, int *count);
+
+/*The following definitions come from libsmb/nmblib.c */
+
+void debug_nmb_packet(struct packet_struct *p);
+char *nmb_namestr(struct nmb_name *n);
+struct packet_struct *copy_packet(struct packet_struct *packet);
+void free_packet(struct packet_struct *packet);
+struct packet_struct *parse_packet(char *buf,int length,
+ enum packet_type packet_type);
+struct packet_struct *read_packet(int fd,enum packet_type packet_type);
+void make_nmb_name( struct nmb_name *n, const char *name, int type);
+BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
+int build_packet(char *buf, struct packet_struct *p);
+BOOL send_packet(struct packet_struct *p);
+struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
+struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id);
+struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name);
+BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name);
+void sort_query_replies(char *data, int n, struct in_addr ip);
+char *dns_to_netbios_name(char *dns_name);
+int name_mangle( char *In, char *Out, char name_type );
+int name_extract(char *buf,int ofs,char *name);
+int name_len(char *s1);
+
+/*The following definitions come from libsmb/nterr.c */
+
+char *get_nt_error_msg(NTSTATUS nt_code);
+char *get_nt_error_c_code(NTSTATUS nt_code);
+
+/*The following definitions come from libsmb/passchange.c */
+
+BOOL remote_password_change(const char *remote_machine, const char *user_name,
+ const char *old_passwd, const char *new_passwd,
+ char *err_str, size_t err_str_len);
+
+/*The following definitions come from libsmb/pwd_cache.c */
+
+void pwd_init(struct pwd_info *pwd);
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
+BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2);
+void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
+void pwd_set_nullpwd(struct pwd_info *pwd);
+void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]);
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]);
+
/*The following definitions come from lib/smbrun.c */
int smbrun(char *cmd, int *outfd);
+/*The following definitions come from libsmb/smbdes.c */
+
+void E_P16(const unsigned char *p14,unsigned char *p16);
+void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24);
+void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out);
+void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out);
+void cred_hash1(unsigned char *out, const unsigned char *in,unsigned char *key);
+void cred_hash2(unsigned char *out, const unsigned char *in,unsigned char *key);
+void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
+void SamOEMhash( unsigned char *data, const unsigned char *key, int val);
+void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw);
+
+/*The following definitions come from libsmb/smbencrypt.c */
+
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
+void E_md4hash(uchar *passwd, uchar *p16);
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
+BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 *new_pw_len,
+ uchar nt_p16[16], uchar p16[16]);
+void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
+
+/*The following definitions come from libsmb/smberr.c */
+
+char *smb_dos_err_name(uint8 class, uint16 num);
+char *get_dos_error_msg(WERROR result);
+char *smb_dos_err_class(uint8 class);
+char *smb_dos_errstr(char *inbuf);
+char *werror_str(WERROR status);
+WERROR map_werror_from_unix(int error);
+
+/*The following definitions come from libsmb/unexpected.c */
+
+void unexpected_packet(struct packet_struct *p);
+void clear_unexpected(time_t t);
+struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
+ char *mailslot_name);
+
/*The following definitions come from lib/snprintf.c */
@@ -178,6 +776,7 @@ int smbrun(char *cmd, int *outfd);
void standard_sub_basic(char *str);
void standard_sub_advanced(int snum, char *user, char *connectpath, gid_t gid, char *str);
void standard_sub_conn(connection_struct *conn, char *str);
+void standard_sub_home(int snum, char *user, char *str);
void standard_sub_snum(int snum, char *str);
void standard_sub_vuser(char *str, user_struct *vuser);
void standard_sub_vsnum(char *str, user_struct *vuser, int snum);
@@ -268,6 +867,28 @@ int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
int sys_acl_valid(SMB_ACL_T acl_d);
int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
+int sys_acl_delete_def_file(const char *path);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T acl_d) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
+int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d);
+int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p);
+SMB_ACL_T sys_acl_init(int count);
+int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type);
+int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p);
+int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
+int sys_acl_valid(SMB_ACL_T acl_d);
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
+int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
int sys_acl_delete_def_file(const char *name);
int sys_acl_free_text(char *text);
int sys_acl_free_acl(SMB_ACL_T acl_d) ;
@@ -331,10 +952,13 @@ int sys_creat(const char *path, mode_t mode);
int sys_open(const char *path, int oflag, mode_t mode);
FILE *sys_fopen(const char *path, const char *type);
SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp);
+int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev);
+char *sys_realpath(const char *path, char *resolved_path);
int sys_waitpid(pid_t pid,int *status,int options);
char *sys_getwd(char *s);
int sys_symlink(const char *oldpath, const char *newpath);
int sys_readlink(const char *path, char *buf, size_t bufsiz);
+int sys_link(const char *oldpath, const char *newpath);
int sys_chown(const char *fname,uid_t uid,gid_t gid);
int sys_chroot(const char *dname);
struct hostent *sys_gethostbyname(const char *name);
@@ -365,6 +989,7 @@ int sys_pclose(int fd);
void *sys_dlopen(const char *name, int flags);
void *sys_dlsym(void *handle, char *symbol);
int sys_dlclose (void *handle);
+const char *sys_dlerror(void);
/*The following definitions come from lib/talloc.c */
@@ -384,11 +1009,14 @@ time_t get_time_t_min(void);
time_t get_time_t_max(void);
void GetTimeOfDay(struct timeval *tval);
void TimeInit(void);
+void get_process_uptime(struct timeval *ret_time);
int TimeDiff(time_t t);
struct tm *LocalTime(time_t *t);
time_t nt_time_to_unix(NTTIME *nt);
+time_t nt_time_to_unix_abs(NTTIME *nt);
time_t interpret_long_date(char *p);
void unix_to_nt_time(NTTIME *nt, time_t t);
+void unix_to_nt_time_abs(NTTIME *nt, time_t t);
void put_long_date(char *p,time_t t);
BOOL null_mtime(time_t mtime);
void put_dos_date(char *buf,int offset,time_t unixdate);
@@ -400,6 +1028,7 @@ time_t make_unix_date3(void *date_ptr);
char *http_timestring(time_t t);
char *timestring(BOOL hires);
time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
+void init_nt_time(NTTIME *nt);
/*The following definitions come from lib/ufc.c */
@@ -407,7 +1036,9 @@ char *ufc_crypt(const char *key,const char *salt);
/*The following definitions come from lib/username.c */
+BOOL name_is_local(const char *name);
char *get_user_home_dir(char *user);
+char *get_user_service_home_dir(char *user);
BOOL map_username(char *user);
struct passwd *Get_Pwnam(char *user,BOOL allow_change);
BOOL user_in_group_list(char *user,char *gname);
@@ -428,8 +1059,8 @@ char *attrib_string(uint16 mode);
void show_msg(char *buf);
void smb_setlen(char *buf,int len);
int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
-void set_message_bcc(char *buf,int num_bytes);
-void set_message_end(void *outbuf,void *end_ptr);
+int set_message_bcc(char *buf,int num_bytes);
+int set_message_end(void *outbuf,void *end_ptr);
void dos_clean_name(char *s);
void unix_clean_name(char *s);
void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date);
@@ -446,8 +1077,8 @@ void safe_free(void *p);
BOOL get_myname(char *my_name);
int interpret_protocol(char *str,int def);
BOOL is_ipaddress(const char *str);
-uint32 interpret_addr(char *str);
-struct in_addr *interpret_addr2(char *str);
+uint32 interpret_addr(const char *str);
+struct in_addr *interpret_addr2(const char *str);
BOOL zero_ip(struct in_addr ip);
char *automount_lookup(char *user_name);
char *automount_lookup(char *user_name);
@@ -464,6 +1095,7 @@ void set_namearray(name_compare_entry **ppname_array, char *namelist);
void free_namearray(name_compare_entry *name_array);
BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
BOOL is_myname(char *s);
+BOOL is_myname_or_ipaddr(char *s);
void set_remote_arch(enum remote_arch_types type);
enum remote_arch_types get_remote_arch(void);
void out_ascii(FILE *f, unsigned char *buf,int len);
@@ -476,6 +1108,9 @@ void zero_free(void *p, size_t size);
int set_maxfiles(int requested_max);
BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name);
int smb_mkstemp(char *template);
+void *smb_xmalloc(size_t size);
+void *xmemdup(const void *p, size_t size);
+char *xstrdup(const char *s);
void *memdup(void *p, size_t size);
char *myhostname(void);
char *lock_path(char *name);
@@ -485,23 +1120,6 @@ BOOL mask_match(char *string, char *pattern, BOOL is_case_sensitive);
BOOL unix_wild_match(char *pattern, char *string);
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6);
-/*The following definitions come from lib/util_array.c */
-
-void free_void_array(uint32 num_entries, void **entries,
- void(free_item)(void*));
-void* add_copy_to_array(uint32 *len, void ***array, const void *item,
- void*(item_dup)(const void*), BOOL alloc_anyway);
-void* add_item_to_array(uint32 *len, void ***array, void *item);
-void free_use_info_array(uint32 num_entries, struct use_info **entries);
-struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
- const struct use_info *name);
-void free_char_array(uint32 num_entries, char **entries);
-char* add_chars_to_array(uint32 *len, char ***array, const char *name);
-void free_uint32_array(uint32 num_entries, uint32 **entries);
-uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name);
-void free_sid_array(uint32 num_entries, DOM_SID **entries);
-DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
-
/*The following definitions come from lib/util_file.c */
BOOL do_file_lock(int fd, int waitsecs, int type);
@@ -529,28 +1147,23 @@ struct sys_grent * getgrent_list(void);
void grent_free (struct sys_grent *glist);
struct sys_pwent * getpwent_list(void);
void pwent_free (struct sys_pwent *plist);
-
-/*The following definitions come from lib/util_list.c */
-
-BOOL copy_policy_hnd (POLICY_HND *dest, const POLICY_HND *src);
-BOOL compare_rpc_hnd_node(const RPC_HND_NODE *x,
- const RPC_HND_NODE *y);
-BOOL RpcHndList_set_connection(const POLICY_HND *hnd,
- struct cli_connection *con);
-BOOL RpcHndList_del_connection(const POLICY_HND *hnd);
-struct cli_connection* RpcHndList_get_connection(const POLICY_HND *hnd);
+struct sys_userlist *get_users_in_group(const char *gname);
+void free_userlist(struct sys_userlist *list_head);
/*The following definitions come from lib/util_seaccess.c */
void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping);
BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
- uint32 acc_desired, uint32 *acc_granted, uint32 *status);
+ uint32 acc_desired, uint32 *acc_granted,
+ NTSTATUS *status);
SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
BOOL child_container);
/*The following definitions come from lib/util_sec.c */
void sec_init(void);
+uid_t sec_initial_uid(void);
+gid_t sec_initial_gid(void);
BOOL non_root_mode(void);
void gain_root_privilege(void);
void gain_root_group_privilege(void);
@@ -560,6 +1173,7 @@ void save_re_uid(void);
void restore_re_uid(void);
int set_re_uid(void);
void become_user_permanently(uid_t uid, gid_t gid);
+BOOL is_setuid_root(void) ;
/*The following definitions come from lib/util_sid.c */
@@ -569,7 +1183,7 @@ BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *p
BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain);
void split_domain_name(const char *fullname, char *domain, char *name);
char *sid_to_string(fstring sidstr_out, DOM_SID *sid);
-BOOL string_to_sid(DOM_SID *sidout, char *sidstr);
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr);
BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid);
@@ -605,8 +1219,6 @@ char *client_addr(void);
char *get_socket_name(int fd);
char *get_socket_addr(int fd);
int open_pipe_sock(char *path);
-int create_pipe_socket(char *dir, int dir_perms,
- char *path, int path_perms);
int sock_exec(const char *prog);
/*The following definitions come from lib/util_str.c */
@@ -651,6 +1263,7 @@ char *string_truncate(char *s, int length);
/*The following definitions come from lib/util_unistr.c */
+size_t unix_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
size_t dos_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate);
void unistr_to_dos(char *dest, const char *src, size_t len);
char *skip_unibuf(char *src, size_t len);
@@ -669,11 +1282,12 @@ int unistrcpy(char *dst, char *src);
void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
BOOL load_dos_unicode_map(int codepage);
-BOOL load_unix_unicode_map(const char *unix_char_set);
+BOOL load_unix_unicode_map(const char *unix_char_set, BOOL override);
smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
size_t dst_len, smb_ucs2_t *cp_to_ucs2);
char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len);
smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
+size_t unicode_to_unix_char(char *dst, const smb_ucs2_t src);
char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len);
size_t unicode_to_dos_char(char *dst, const smb_ucs2_t src);
smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
@@ -731,6 +1345,7 @@ smb_ucs2_t *octal_string_w(int i);
smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length);
smb_ucs2_t doscp2ucs2(int w);
int ucs2doscp(smb_ucs2_t w);
+int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags);
/*The following definitions come from lib/wins_srv.c */
@@ -739,515 +1354,14 @@ struct in_addr wins_srv_ip( void );
void wins_srv_died( struct in_addr boothill_ip );
unsigned long wins_srv_count( void );
-/*The following definitions come from libsmb/cli_lsarpc.c */
-
-struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name,
- struct ntuser_creds *creds);
-void cli_lsa_shutdown(struct cli_state *cli);
-uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- BOOL sec_qos, uint32 des_access, POLICY_HND *pol);
-uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol);
-uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_sids, DOM_SID *sids,
- char ***names, uint32 **types, int *num_names);
-uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_names, char **names,
- DOM_SID **sids, uint32 **types, int *num_sids);
-uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid);
-uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *enum_ctx,
- uint32 *num_domains, char ***domain_names,
- DOM_SID **domain_sids);
-
-/*The following definitions come from libsmb/cli_netlogon.c */
-
-struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
- char *system_name,
- struct ntuser_creds *creds);
-void cli_netlogon_shutdown(struct cli_state *cli);
-uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 query_level);
-
-/*The following definitions come from libsmb/cli_samr.c */
-
-struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
- struct ntuser_creds *creds);
-void cli_samr_shutdown(struct cli_state *cli);
-uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol);
-uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol);
-uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol, uint32 access_mask,
- DOM_SID *domain_sid, POLICY_HND *domain_pol);
-uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 user_rid, POLICY_HND *user_pol);
-uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 group_rid, POLICY_HND *group_pol);
-uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR **ctr);
-uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 info_level,
- GROUP_INFO_CTR *ctr);
-uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint32 *num_groups,
- DOM_GID **gid);
-uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 *num_mem,
- uint32 **rid, uint32 **attr);
-uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_groups,
- uint32 *num_dom_groups);
-uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, uint32 *num_mem,
- DOM_SID **sids);
-uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 alias_rid, POLICY_HND *alias_pol);
-uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint16 switch_value,
- SAM_UNK_CTR *ctr);
-uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 *start_idx,
- uint16 switch_value, uint32 *num_entries,
- uint32 max_entries, SAM_DISPINFO_CTR *ctr);
-uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_rids, uint32 *rids,
- uint32 *num_names, char ***names,
- uint32 **name_types);
-uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_names, char **names,
- uint32 *num_rids, uint32 **rids,
- uint32 **rid_types);
-uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, char *acct_name,
- uint32 acb_info, uint32 unknown,
- POLICY_HND *user_pol, uint32 *rid);
-uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- uchar sess_key[16], SAM_USERINFO_CTR *ctr);
-uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- uchar sess_key[16], SAM_USERINFO_CTR *ctr);
-uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol);
-
-/*The following definitions come from libsmb/cli_spoolss.c */
-
-struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
- char *system_name,
- struct ntuser_creds *creds);
-void cli_spoolss_shutdown(struct cli_state *cli);
-uint32 cli_spoolss_open_printer_ex(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- char *printername,
- char *datatype,
- uint32 access_required,
- char *station,
- char *username,
- POLICY_HND *pol
-);
-uint32 cli_spoolss_close_printer(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol
-);
-uint32 cli_spoolss_enum_printers(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 flags,
- uint32 level,
- int *returned,
- PRINTER_INFO_CTR *ctr
-);
-uint32 cli_spoolss_enum_ports(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 level,
- int *returned,
- PORT_INFO_CTR *ctr
-);
-uint32 cli_spoolss_getprinter(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- PRINTER_INFO_CTR *ctr
-);
-uint32 cli_spoolss_setprinter(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- PRINTER_INFO_CTR *ctr,
- uint32 command
-);
-uint32 cli_spoolss_getprinterdriver (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- char* env,
- PRINTER_DRIVER_CTR *ctr
-);
-uint32 cli_spoolss_enumprinterdrivers (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 level,
- char* env,
- uint32 *returned,
- PRINTER_DRIVER_CTR *ctr
-);
-uint32 cli_spoolss_getprinterdriverdir (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 level,
- char* env,
- DRIVER_DIRECTORY_CTR *ctr
-);
-uint32 cli_spoolss_addprinterdriver (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 level,
- PRINTER_DRIVER_CTR *ctr
-);
-uint32 cli_spoolss_addprinterex (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- uint32 level,
- PRINTER_INFO_CTR *ctr
-);
-uint32 cli_spoolss_deleteprinterdriver (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- char *arch,
- char *driver
-);
-
-/*The following definitions come from libsmb/cli_srvsvc.c */
-
-struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
- char *system_name,
- struct ntuser_creds *creds);
-void cli_srvsvc_shutdown(struct cli_state *cli);
-uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 switch_value, SRV_INFO_CTR *ctr);
-
-/*The following definitions come from libsmb/cliconnect.c */
-
-BOOL cli_session_setup(struct cli_state *cli,
- char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *workgroup);
-BOOL cli_ulogoff(struct cli_state *cli);
-BOOL cli_send_tconX(struct cli_state *cli,
- char *share, char *dev, char *pass, int passlen);
-BOOL cli_tdis(struct cli_state *cli);
-void cli_negprot_send(struct cli_state *cli);
-BOOL cli_negprot(struct cli_state *cli);
-BOOL cli_session_request(struct cli_state *cli,
- struct nmb_name *calling, struct nmb_name *called);
-BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
-BOOL cli_reestablish_connection(struct cli_state *cli);
-BOOL cli_establish_connection(struct cli_state *cli,
- char *dest_host, struct in_addr *dest_ip,
- struct nmb_name *calling, struct nmb_name *called,
- char *service, char *service_type,
- BOOL do_shutdown, BOOL do_tcon);
-BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
- struct in_addr *pdest_ip);
-
-/*The following definitions come from libsmb/clientgen.c */
-
-int cli_set_port(struct cli_state *cli, int port);
-BOOL cli_receive_smb(struct cli_state *cli);
-BOOL cli_send_smb(struct cli_state *cli);
-void cli_setup_packet(struct cli_state *cli);
-void cli_setup_bcc(struct cli_state *cli, void *p);
-void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
-struct cli_state *cli_initialise(struct cli_state *cli);
-void cli_shutdown(struct cli_state *cli);
-void cli_sockopt(struct cli_state *cli, char *options);
-uint16 cli_setpid(struct cli_state *cli, uint16 pid);
-
-/*The following definitions come from libsmb/clierror.c */
-
-char *cli_errstr(struct cli_state *cli);
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error);
-
-/*The following definitions come from libsmb/clifile.c */
-
-BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst);
-BOOL cli_unlink(struct cli_state *cli, char *fname);
-BOOL cli_mkdir(struct cli_state *cli, char *dname);
-BOOL cli_rmdir(struct cli_state *cli, char *dname);
-int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag);
-int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
- uint32 FileAttributes, uint32 ShareAccess,
- uint32 CreateDisposition, uint32 CreateOptions);
-int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess);
-int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode);
-BOOL cli_close(struct cli_state *cli, int fnum);
-BOOL cli_lock(struct cli_state *cli, int fnum,
- uint32 offset, uint32 len, int timeout, enum brl_type lock_type);
-BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len);
-BOOL cli_lock64(struct cli_state *cli, int fnum,
- SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type);
-BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len);
-BOOL cli_getattrE(struct cli_state *cli, int fd,
- uint16 *attr, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time);
-BOOL cli_getatr(struct cli_state *cli, char *fname,
- uint16 *attr, size_t *size, time_t *t);
-BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t);
-BOOL cli_chkpath(struct cli_state *cli, char *path);
-BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
-int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path);
-
-/*The following definitions come from libsmb/clilist.c */
-
-int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
- void (*fn)(file_info *, const char *, void *), void *state);
-int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
- void (*fn)(file_info *, const char *, void *), void *state);
-int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
- void (*fn)(file_info *, const char *, void *), void *state);
-
-/*The following definitions come from libsmb/climessage.c */
-
-BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
- int *grp);
-BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
-BOOL cli_message_end(struct cli_state *cli, int grp);
-
-/*The following definitions come from libsmb/cliprint.c */
-
-int cli_print_queue(struct cli_state *cli,
- void (*fn)(struct print_job_info *));
-int cli_printjob_del(struct cli_state *cli, int job);
-
-/*The following definitions come from libsmb/clirap.c */
-
-BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name,
- uint16 *setup, uint32 setup_count, uint32 max_setup_count,
- char *params, uint32 param_count, uint32 max_param_count,
- char *data, uint32 data_count, uint32 max_data_count,
- char **rparam, uint32 *rparam_count,
- char **rdata, uint32 *rdata_count);
-BOOL cli_api(struct cli_state *cli,
- char *param, int prcnt, int mprcnt,
- char *data, int drcnt, int mdrcnt,
- char **rparam, int *rprcnt,
- char **rdata, int *rdrcnt);
-BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
-int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state);
-BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
- void (*fn)(const char *, uint32, const char *, void *),
- void *state);
-BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
- const char *old_password);
-BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
- time_t *c_time, time_t *a_time, time_t *m_time,
- size_t *size, uint16 *mode);
-BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
- time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, size_t *size, uint16 *mode,
- SMB_INO_T *ino);
-BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
- uint16 *mode, size_t *size,
- time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, SMB_INO_T *ino);
-BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata);
-
-/*The following definitions come from libsmb/clireadwrite.c */
-
-ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
-ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
-ssize_t cli_write(struct cli_state *cli,
- int fnum, uint16 write_mode,
- char *buf, off_t offset, size_t size);
-ssize_t cli_smbwrite(struct cli_state *cli,
- int fnum, char *buf, off_t offset, size_t size1);
-
-/*The following definitions come from libsmb/clisecdesc.c */
-
-SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx);
-BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd);
-
-/*The following definitions come from libsmb/clistr.c */
-
-int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags);
-int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags);
-int clistr_align_out(struct cli_state *cli, const void *p, int flags);
-int clistr_align_in(struct cli_state *cli, const void *p, int flags);
-
-/*The following definitions come from libsmb/clitrans.c */
-
-BOOL cli_send_trans(struct cli_state *cli, int trans,
- char *pipe_name,
- int fid, int flags,
- uint16 *setup, int lsetup, int msetup,
- char *param, int lparam, int mparam,
- char *data, int ldata, int mdata);
-BOOL cli_receive_trans(struct cli_state *cli,int trans,
- char **param, int *param_len,
- char **data, int *data_len);
-BOOL cli_send_nt_trans(struct cli_state *cli,
- int function,
- int flags,
- uint16 *setup, int lsetup, int msetup,
- char *param, int lparam, int mparam,
- char *data, int ldata, int mdata);
-BOOL cli_receive_nt_trans(struct cli_state *cli,
- char **param, int *param_len,
- char **data, int *data_len);
-
-/*The following definitions come from libsmb/credentials.c */
-
-char *credstr(uchar *cred);
-void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
- uchar session_key[8]);
-void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
- DOM_CHAL *cred);
-int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
- UTIME timestamp);
-BOOL clnt_deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
-BOOL deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred,
- DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
-
-/*The following definitions come from libsmb/namequery.c */
-
-struct node_status *name_status_query(int fd,struct nmb_name *name,
- struct in_addr to_ip, int *num_names);
-BOOL name_status_find(int type, struct in_addr to_ip, char *name);
-BOOL name_register(int fd, const char *name, int name_type,
- struct in_addr name_ip, int opcode,
- BOOL bcast,
- struct in_addr to_ip, int *count);
-struct in_addr *name_query(int fd,const char *name,int name_type,
- BOOL bcast,BOOL recurse,
- struct in_addr to_ip, int *count);
-FILE *startlmhosts(char *fname);
-BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
-void endlmhosts(FILE *fp);
-BOOL name_register_wins(const char *name, int name_type);
-BOOL name_resolve_bcast(const char *name, int name_type,
- struct in_addr **return_ip_list, int *return_count);
-BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
-BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
- struct in_addr *ip);
-BOOL find_master_ip(char *group, struct in_addr *master_ip);
-BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name);
-BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count);
-
-/*The following definitions come from libsmb/nmblib.c */
-
-void debug_nmb_packet(struct packet_struct *p);
-char *nmb_namestr(struct nmb_name *n);
-struct packet_struct *copy_packet(struct packet_struct *packet);
-void free_packet(struct packet_struct *packet);
-struct packet_struct *parse_packet(char *buf,int length,
- enum packet_type packet_type);
-struct packet_struct *read_packet(int fd,enum packet_type packet_type);
-void make_nmb_name( struct nmb_name *n, const char *name, int type);
-BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
-int build_packet(char *buf, struct packet_struct *p);
-BOOL send_packet(struct packet_struct *p);
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id);
-struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name);
-BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name);
-void sort_query_replies(char *data, int n, struct in_addr ip);
-char *dns_to_netbios_name(char *dns_name);
-int name_mangle( char *In, char *Out, char name_type );
-int name_extract(char *buf,int ofs,char *name);
-int name_len(char *s1);
-
-/*The following definitions come from libsmb/nterr.c */
-
-BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len);
-char *get_nt_error_msg(uint32 nt_code);
-
-/*The following definitions come from libsmb/passchange.c */
-
-BOOL remote_password_change(const char *remote_machine, const char *user_name,
- const char *old_passwd, const char *new_passwd,
- char *err_str, size_t err_str_len);
-
-/*The following definitions come from libsmb/pwd_cache.c */
-
-void pwd_init(struct pwd_info *pwd);
-BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2);
-void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
-void pwd_set_nullpwd(struct pwd_info *pwd);
-void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
-void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
-void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
-void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]);
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]);
-
-/*The following definitions come from libsmb/smbdes.c */
-
-void E_P16(unsigned char *p14,unsigned char *p16);
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
-void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
-void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
-void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
-void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
-void SamOEMhash( unsigned char *data, unsigned char *key, int val);
-
-/*The following definitions come from libsmb/smbencrypt.c */
-
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
-void E_md4hash(uchar *passwd, uchar *p16);
-void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
-void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
-void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
-BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
- int new_pw_len, BOOL nt_pass_set);
-BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32 *new_pw_len,
- uchar nt_p16[16], uchar p16[16]);
-void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
-
-/*The following definitions come from libsmb/smberr.c */
-
-char *smb_errstr(char *inbuf);
-
-/*The following definitions come from libsmb/unexpected.c */
-
-void unexpected_packet(struct packet_struct *p);
-void clear_unexpected(time_t t);
-struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
- char *mailslot_name);
-
/*The following definitions come from locking/brlock.c */
void brl_init(int read_only);
void brl_shutdown(int read_only);
-BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
- br_off start, br_off size,
- enum brl_type lock_type);
+NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type);
BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size);
@@ -1263,12 +1377,10 @@ int brl_forall(BRLOCK_FN(fn));
BOOL is_locked(files_struct *fsp,connection_struct *conn,
SMB_BIG_UINT count,SMB_BIG_UINT offset,
enum brl_type lock_type, BOOL check_self);
-BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type,
- int *eclass,uint32 *ecode);
-BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,
- int *eclass,uint32 *ecode);
+NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type);
+NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset);
void locking_close_file(files_struct *fsp);
BOOL locking_init(int read_only);
BOOL locking_end(void);
@@ -1280,7 +1392,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp);
void unlock_share_entry_fsp(files_struct *fsp);
int get_share_modes(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry **shares);
+ share_mode_entry **pp_shares);
BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2);
ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
share_mode_entry *entry, share_mode_entry **ppse);
@@ -1328,9 +1440,6 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
struct name_record **n);
void kill_async_dns_child(void);
-/*The following definitions come from nmbd/nmbd.c */
-
-
/*The following definitions come from nmbd/nmbd_become_dmb.c */
void add_domain_names(time_t t);
@@ -1361,6 +1470,9 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
void collect_all_workgroup_names_from_wins_server(time_t t);
void sync_all_dmbs(time_t t);
+/*The following definitions come from nmbd/nmbd.c */
+
+
/*The following definitions come from nmbd/nmbd_elections.c */
void check_master_browser_exists(time_t t);
@@ -1603,6 +1715,8 @@ struct server_record *create_server_on_workgroup(struct work_record *work,
int ttl,char *comment);
void update_server_ttl(struct server_record *servrec, int ttl);
void expire_servers(struct work_record *work, time_t t);
+void write_browse_list_entry(FILE *fp, fstring name, uint32 rec_type,
+ fstring local_master_browser_name, fstring description);
void write_browse_list(time_t t, BOOL force_write);
/*The following definitions come from nmbd/nmbd_subnetdb.c */
@@ -1659,65 +1773,31 @@ void expire_workgroups_and_servers(time_t t);
/*The following definitions come from nsswitch/wb_client.c */
-BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name_type);
-BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
+BOOL winbind_lookup_name(const char *name, DOM_SID *sid,
+ enum SID_NAME_USE *name_type);
+BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
+ enum SID_NAME_USE *name_type);
BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid);
BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid);
BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
int winbind_initgroups(char *user, gid_t gid);
-int winbind_getgroups(char *user, int size, gid_t *list);
+int winbind_getgroups(const char *user, int size, gid_t *list);
BOOL winbind_uidtoname(fstring name, uid_t uid);
BOOL winbind_gidtoname(fstring name, gid_t gid);
-BOOL winbind_nametouid(uid_t *puid, char *name);
-BOOL winbind_nametogid(gid_t *pgid, char *gname);
+BOOL winbind_nametouid(uid_t *puid, const char *name);
+BOOL winbind_nametogid(gid_t *pgid, const char *gname);
/*The following definitions come from nsswitch/wb_common.c */
+void free_response(struct winbindd_response *response);
void winbind_exclude_domain(const char *domain);
void init_request(struct winbindd_request *request, int request_type);
void init_response(struct winbindd_response *response);
void close_sock(void);
+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);
-
-/*The following definitions come from nsswitch/winbindd_glue.c */
-
-BOOL wb_lsa_open_policy(char *server, BOOL sec_qos, uint32 des_access,
- CLI_POLICY_HND *pol);
-BOOL wb_lsa_enum_trust_dom(CLI_POLICY_HND *hnd, uint32 *enum_ctx,
- uint32 * num_doms, char ***names, DOM_SID **sids);
-BOOL wb_lsa_query_info_pol(CLI_POLICY_HND *hnd, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid);
-BOOL wb_lsa_lookup_names(CLI_POLICY_HND *hnd, int num_names, char **names,
- DOM_SID **sids, uint32 **types, int *num_sids);
-BOOL wb_lsa_lookup_sids(CLI_POLICY_HND *hnd, int num_sids, DOM_SID *sids,
- char ***names, uint32 **types, int *num_names);
-BOOL wb_lsa_close(CLI_POLICY_HND *hnd);
-BOOL wb_samr_close(CLI_POLICY_HND *hnd);
-BOOL wb_samr_connect(char *server, uint32 access_mask, CLI_POLICY_HND *pol);
-BOOL wb_samr_open_domain(CLI_POLICY_HND *connect_pol, uint32 ace_perms,
- DOM_SID *sid, CLI_POLICY_HND *domain_pol);
-uint32 wb_samr_enum_dom_groups(CLI_POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **sam,
- uint32 *num_sam_groups);
-BOOL wb_get_samr_query_userinfo(CLI_POLICY_HND *pol, uint32 info_level,
- uint32 user_rid, SAM_USERINFO_CTR **ctr);
-BOOL wb_samr_open_user(CLI_POLICY_HND *pol, uint32 access_mask, uint32 rid,
- POLICY_HND *user_pol);
-BOOL wb_samr_query_usergroups(CLI_POLICY_HND *pol, uint32 *num_groups,
- DOM_GID **gid);
-BOOL wb_get_samr_query_groupinfo(CLI_POLICY_HND *pol, uint32 info_level,
- uint32 group_rid, GROUP_INFO_CTR *ctr);
-BOOL wb_sam_query_groupmem(CLI_POLICY_HND *pol, uint32 group_rid,
- uint32 *num_names, uint32 **rid_mem,
- char ***names, uint32 **name_types);
-BOOL wb_samr_query_dom_info(CLI_POLICY_HND *pol, uint16 switch_value,
- SAM_UNK_CTR *ctr);
-uint32 wb_samr_query_dispinfo(CLI_POLICY_HND *pol, uint32 *start_ndx,
- uint16 info_level, uint32 *num_entries,
- SAM_DISPINFO_CTR *ctr);
/*The following definitions come from param/loadparm.c */
@@ -1767,8 +1847,6 @@ char *lp_deluser_script(void);
char *lp_wins_hook(void);
char *lp_domain_admin_group(void);
char *lp_domain_guest_group(void);
-char *lp_winbind_uid(void);
-char *lp_winbind_gid(void);
char *lp_template_homedir(void);
char *lp_template_shell(void);
char *lp_winbind_separator(void);
@@ -1841,6 +1919,7 @@ BOOL lp_host_msdfs(void);
BOOL lp_kernel_oplocks(void);
BOOL lp_enhanced_browsing(void);
BOOL lp_use_mmap(void);
+BOOL lp_unix_extensions(void);
int lp_os_level(void);
int lp_max_ttl(void);
int lp_max_wins_ttl(void);
@@ -1931,6 +2010,7 @@ BOOL lp_map_hidden(int );
BOOL lp_map_archive(int );
BOOL lp_locking(int );
BOOL lp_strict_locking(int );
+BOOL lp_share_modes(int );
BOOL lp_posix_locking(int );
BOOL lp_oplocks(int );
BOOL lp_level2_oplocks(int );
@@ -1952,6 +2032,7 @@ BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
BOOL lp_inherit_perms(int );
BOOL lp_use_client_driver(int );
+BOOL lp_default_devmode(int );
BOOL lp_nt_acl_support(int );
int lp_create_mask(int );
int lp_force_create_mode(int );
@@ -1975,6 +2056,8 @@ BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
int lp_add_service(char *pszService, int iDefaultService);
BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
BOOL lp_file_list_changed(void);
+BOOL lp_winbind_uid(uid_t *low, uid_t *high);
+BOOL lp_winbind_gid(gid_t *low, gid_t *high);
void *lp_local_ptr(int snum, void *ptr);
BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue);
void init_locals(void);
@@ -2004,6 +2087,8 @@ int lp_minor_announce_version(void);
void lp_set_name_resolve_order(char *new_order);
char *lp_printername(int snum);
void get_private_directory(pstring priv_dir);
+void lp_set_logfile(const char *name);
+const char *get_called_name(void);
/*The following definitions come from param/params.c */
@@ -2019,9 +2104,12 @@ BOOL pdb_generate_sam_sid(void);
BOOL smb_pam_claim_session(char *user, char *tty, char *rhost);
BOOL smb_pam_close_session(char *user, char *tty, char *rhost);
-uint32 smb_pam_accountcheck(char * user);
-uint32 smb_pam_passcheck(char * user, char * password);
-BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword);
+NTSTATUS smb_pam_accountcheck(const char * user);
+NTSTATUS smb_pam_passcheck(char * user, char * password);
+BOOL smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword);
+NTSTATUS smb_pam_accountcheck(const char * user);
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost);
+BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost);
/*The following definitions come from passdb/pass_check.c */
@@ -2098,7 +2186,8 @@ BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime);
BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime);
BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime);
BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len);
-BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours);
+BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours);
+BOOL pdb_set_init_flag (SAM_ACCOUNT *sampass, uint32 flag);
BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid);
BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid);
BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid);
@@ -2107,10 +2196,10 @@ BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username);
BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain);
BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username);
BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname);
-BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script);
-BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path);
-BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive);
-BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir);
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script, BOOL store);
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path, BOOL store);
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive, BOOL store);
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir, BOOL store);
BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc);
BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations);
BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial);
@@ -2121,6 +2210,7 @@ BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn);
BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn);
BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn);
BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours);
+BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid);
/*The following definitions come from passdb/pdb_ldap.c */
@@ -2129,7 +2219,6 @@ void pdb_endsampwent(void);
BOOL pdb_getsampwent(SAM_ACCOUNT * user);
BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname);
BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
-BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid);
BOOL pdb_delete_sam_account(char *sname);
BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
@@ -2141,7 +2230,6 @@ void pdb_endsampwent(void);
BOOL pdb_getsampwent(SAM_ACCOUNT *user);
BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname);
BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
-BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid);
BOOL pdb_delete_sam_account(char *sname);
BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
@@ -2152,7 +2240,6 @@ BOOL pdb_setsampwent (BOOL update);
void pdb_endsampwent (void);
BOOL pdb_getsampwent(SAM_ACCOUNT *user);
BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, char *username);
-BOOL pdb_getsampwuid (SAM_ACCOUNT *sam_acct, uid_t uid);
BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid);
BOOL pdb_add_sam_account(SAM_ACCOUNT *sampass);
BOOL pdb_update_sam_account(SAM_ACCOUNT *sampass, BOOL override);
@@ -2164,7 +2251,6 @@ BOOL pdb_setsampwent(BOOL update);
void pdb_endsampwent(void);
BOOL pdb_getsampwent(SAM_ACCOUNT *user);
BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname);
-BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid);
BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid);
BOOL pdb_delete_sam_account(char *sname);
BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override);
@@ -2205,18 +2291,21 @@ BOOL parse_lpq_entry(int snum,char *line,
/*The following definitions come from printing/nt_printing.c */
BOOL nt_printing_init(void);
+uint32 update_c_setprinter(BOOL initialize);
+uint32 get_c_setprinter(void);
int get_builtin_ntforms(nt_forms_struct **list);
BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form);
int get_ntforms(nt_forms_struct **list);
int write_ntforms(nt_forms_struct **list, int number);
BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count);
-BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret);
+BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret);
void update_a_form(nt_forms_struct **list, const FORM *form, int count);
int get_ntdrivers(fstring **list, char *architecture, uint32 version);
BOOL get_short_archi(char *short_archi, char *long_archi);
-uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
uint32 level, struct current_user *user);
-BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr);
+BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
+ struct current_user *user, WERROR *perr);
uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model);
uint32 del_a_printer(char *sharename);
void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param);
@@ -2226,28 +2315,28 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename);
NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode);
void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr);
void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname);
-uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
-uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level);
-uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param);
-uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename);
+uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param);
+WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename);
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level);
uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
-uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
fstring printername, fstring architecture, uint32 version);
uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
BOOL printer_driver_in_use (char *arch, char *driver);
-uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i);
+WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i);
BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
fstring value, uint8 **data, uint32 *type, uint32 *len);
BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
fstring value, uint8 **data, uint32 *type, uint32 *len);
-uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr);
+WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr);
BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr);
void map_printer_permissions(SEC_DESC *sd);
BOOL print_access_check(struct current_user *user, int snum, int access_type);
BOOL print_time_access_check(int snum);
-uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default);
+WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default);
/*The following definitions come from printing/pcap.c */
@@ -2257,19 +2346,14 @@ void pcap_printer_fn(void (*fn)(char *, char *));
/*The following definitions come from printing/print_cups.c */
-/*The following definitions come from printing/print_generic.c */
-
-
-/*The following definitions come from printing/print_svid.c */
-
-void sysv_printer_fn(void (*fn)(char *, char *));
-int sysv_printername_ok(char *name);
-
/*The following definitions come from printing/printfsp.c */
-files_struct *print_fsp_open(connection_struct *conn);
+files_struct *print_fsp_open(connection_struct *conn, char *fname);
void print_fsp_end(files_struct *fsp, BOOL normal_close);
+/*The following definitions come from printing/print_generic.c */
+
+
/*The following definitions come from printing/printing.c */
BOOL print_backend_init(void);
@@ -2279,19 +2363,25 @@ int print_job_fd(int jobid);
char *print_job_fname(int jobid);
BOOL print_job_set_place(int jobid, int place);
BOOL print_job_set_name(int jobid, char *name);
-BOOL print_job_delete(struct current_user *user, int jobid, int *errcode);
-BOOL print_job_pause(struct current_user *user, int jobid, int *errcode);
-BOOL print_job_resume(struct current_user *user, int jobid, int *errcode);
+BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode);
+BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode);
+BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode);
int print_job_write(int jobid, const char *buf, int size);
+int print_queue_length(int snum, print_status_struct *pstatus);
int print_job_start(struct current_user *user, int snum, char *jobname);
BOOL print_job_end(int jobid, BOOL normal_close);
int print_queue_status(int snum,
print_queue_struct **queue,
print_status_struct *status);
int print_queue_snum(char *qname);
-BOOL print_queue_pause(struct current_user *user, int snum, int *errcode);
-BOOL print_queue_resume(struct current_user *user, int snum, int *errcode);
-BOOL print_queue_purge(struct current_user *user, int snum, int *errcode);
+BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode);
+BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode);
+BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode);
+
+/*The following definitions come from printing/print_svid.c */
+
+void sysv_printer_fn(void (*fn)(char *, char *));
+int sysv_printername_ok(char *name);
/*The following definitions come from profile/profile.c */
@@ -2299,171 +2389,105 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len);
void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len);
BOOL profile_setup(BOOL rdonly);
-/*The following definitions come from rpc_client/cli_connect.c */
-
-void init_connections(void);
-void free_connections(void);
-void cli_connection_free(struct cli_connection *con);
-void cli_connection_unlink(struct cli_connection *con);
-BOOL cli_connection_init(const char *srv_name, char *pipe_name,
- struct cli_connection **con);
-BOOL cli_connection_init_auth(const char *srv_name, char *pipe_name,
- struct cli_connection **con,
- cli_auth_fns * auth, void *auth_creds);
-struct _cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
-void *cli_conn_get_auth_creds(struct cli_connection *con);
-BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
- prs_struct * data, prs_struct * rdata);
-BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
- prs_struct * data, prs_struct * rdata);
-BOOL rpc_con_ok(struct cli_connection *con);
-
/*The following definitions come from rpc_client/cli_login.c */
-BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
+NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
-BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
+NTSTATUS cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
uint32 smb_userid_low, char *password,
NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
-BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char lm_chal[8],
- char *lm_chal_resp, char *nt_chal_resp,
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+NTSTATUS cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
+ uint32 smb_userid_low, const char lm_chal[8],
+ const char *lm_chal_resp, const char *nt_chal_resp,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
-/*The following definitions come from rpc_client/cli_lsarpc.c */
-
-BOOL do_lsa_open_policy(struct cli_state *cli,
- char *system_name, POLICY_HND *hnd,
- BOOL sec_qos);
-BOOL do_lsa_query_info_pol(struct cli_state *cli,
- POLICY_HND *hnd, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid);
-BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd);
-BOOL cli_lsa_get_domain_sid(struct cli_state *cli, char *server);
-uint32 lsa_open_policy(const char *system_name, POLICY_HND *hnd,
- BOOL sec_qos, uint32 des_access);
-uint32 lsa_close(POLICY_HND *hnd);
-uint32 lsa_lookup_sids(POLICY_HND *hnd, int num_sids, DOM_SID *sids,
- char ***names, uint32 **types, int *num_names);
-uint32 lsa_lookup_names(POLICY_HND *hnd, int num_names, char **names,
- DOM_SID **sids, uint32 **types, int *num_sids);
-
/*The following definitions come from rpc_client/cli_netlogon.c */
-BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
-BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, NTSTATUS status_level);
+NTSTATUS cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
uint32 neg_flags, DOM_CHAL *srv_chal);
BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
-BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
+NTSTATUS cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3);
BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
/*The following definitions come from rpc_client/cli_pipe.c */
BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
prs_struct *data, prs_struct *rdata);
-BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name);
+BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name);
void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
-BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name);
void cli_nt_session_close(struct cli_state *cli);
/*The following definitions come from rpc_client/cli_spoolss_notify.c */
BOOL spoolss_disconnect_from_client( struct cli_state *cli);
BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine);
-BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, uint32 *status, POLICY_HND *handle);
+BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, WERROR *status, POLICY_HND *handle);
BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle,
- uint32 change_low, uint32 change_high, uint32 *status);
-BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle, uint32 *status);
+ uint32 change_low, uint32 change_high, WERROR *status);
+BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle,
+ WERROR *status);
/*The following definitions come from rpc_client/cli_trust.c */
BOOL change_trust_account_password( char *domain, char *remote_machine_list);
-/*The following definitions come from rpc_client/cli_use.c */
-
-void init_cli_use(void);
-void free_cli_use(void);
-struct cli_state *cli_net_use_add(const char *srv_name,
- const struct ntuser_creds *usr_creds,
- BOOL reuse, BOOL *is_new);
-BOOL cli_net_use_del(const char *srv_name,
- const struct ntuser_creds *usr_creds,
- BOOL force_close, BOOL *connection_closed);
-void cli_net_use_enum(uint32 *num_cons, struct use_info ***use);
-void cli_use_wait_keyboard(void);
-
-/*The following definitions come from rpc_client/ncacn_np_use.c */
-
-BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
- const vuser_key * key,
- BOOL force_close, BOOL *connection_closed);
-struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
- const vuser_key * key);
-struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
- const vuser_key * key,
- const char *srv_name,
- const struct ntuser_creds *ntc,
- BOOL reuse, BOOL *is_new_connection);
-
-/*The following definitions come from rpc_parse/parse_creds.c */
-
-BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
- const char* requested_name,
- const char* real_name,
- BOOL guest);
-BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth);
-void creds_free_unix(CREDS_UNIX *r_u);
-BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
- uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
-BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
-void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
-BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
- DOM_SID *sid, uint32 num_grps, uint32 *grps);
-BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth);
-void creds_free_nt_sec(CREDS_NT_SEC *r_u);
-BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
-BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
-void creds_free_nt(CREDS_NT *r_u);
-BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
-void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
-void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from);
-void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
-void create_ntc_from_cli_state (CREDS_NT *to, const struct cli_state *cli_from);
-void copy_nt_creds(struct ntuser_creds *to,
- const struct ntuser_creds *from);
-void copy_user_creds(struct user_creds *to,
- const struct user_creds *from);
-void free_user_creds(struct user_creds *creds);
-BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
-BOOL create_ntuser_creds( prs_struct *ps,
- const char* name,
- uint16 version, uint16 command,
- uint32 pid,
- const struct ntuser_creds *ntu,
- BOOL reuse);
-BOOL create_user_creds( prs_struct *ps,
- const char* name,
- uint16 version, uint16 command,
- uint32 pid,
- struct user_creds *usr);
+/*The following definitions come from rpcclient/cmd_dfs.c */
+
+
+/*The following definitions come from rpcclient/cmd_lsarpc.c */
+
+
+/*The following definitions come from rpcclient/cmd_netlogon.c */
+
+
+/*The following definitions come from rpcclient/cmd_reg.c */
+
+
+/*The following definitions come from rpcclient/cmd_samr.c */
+
+void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1);
+void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4);
+
+/*The following definitions come from rpcclient/cmd_spoolss.c */
+
+BOOL get_short_archi(char *short_archi, char *long_archi);
+void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch);
+
+/*The following definitions come from rpcclient/cmd_srvsvc.c */
+
+
+/*The following definitions come from rpcclient/rpcclient.c */
+
+void fetch_machine_sid(struct cli_state *cli);
+void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
+ char* domain, char* password);
+struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
+ struct ntuser_creds *creds);
/*The following definitions come from rpc_parse/parse_dfs.c */
+void init_dfs_q_dfs_exist(DFS_Q_DFS_EXIST *q_d);
BOOL dfs_io_q_dfs_exist(char *desc, DFS_Q_DFS_EXIST *q_d, prs_struct *ps, int depth);
BOOL dfs_io_r_dfs_exist(char *desc, DFS_R_DFS_EXIST *q_d, prs_struct *ps, int depth);
-BOOL make_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, char *entrypath,
+BOOL init_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, char *entrypath,
char *servername, char *sharename);
BOOL dfs_io_q_dfs_remove(char *desc, DFS_Q_DFS_REMOVE *q_d, prs_struct *ps, int depth);
BOOL dfs_io_r_dfs_remove(char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps, int depth);
-BOOL make_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, char *entrypath, char *servername,
+BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, char *entrypath, char *servername,
char *sharename, char *comment, uint32 flags);
BOOL dfs_io_q_dfs_add(char *desc, DFS_Q_DFS_ADD *q_d, prs_struct *ps, int depth);
BOOL dfs_io_r_dfs_add(char *desc, DFS_R_DFS_ADD *r_d, prs_struct *ps, int depth);
+BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, char *entrypath,
+ char *servername, char *sharename,
+ uint32 info_level);
BOOL dfs_io_q_dfs_get_info(char* desc, DFS_Q_DFS_GET_INFO* q_i, prs_struct* ps, int depth);
BOOL dfs_io_r_dfs_get_info(char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps, int depth);
-BOOL make_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr);
+BOOL init_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr);
BOOL dfs_io_q_dfs_enum(char *desc, DFS_Q_DFS_ENUM *q_d, prs_struct *ps, int depth);
BOOL dfs_io_dfs_info_ctr(char* desc, DFS_INFO_CTR* ctr, uint32 num_entries, uint32 level, prs_struct* ps, int depth);
BOOL dfs_io_r_dfs_enum(char *desc, DFS_R_DFS_ENUM *q_d, prs_struct *ps, int depth);
@@ -2505,7 +2529,7 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
prs_struct *ps, int depth);
void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
char *domain_name, DOM_SID *domain_sid,
- uint32 status);
+ NTSTATUS status);
BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
prs_struct *ps, int depth);
BOOL lsa_io_dom_query_5(char *desc, DOM_QUERY_5 *d_q, prs_struct *ps, int depth);
@@ -2531,8 +2555,30 @@ BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_c, prs_struct *ps, int depth);
BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, int depth);
+void init_q_enum_privs(LSA_Q_ENUM_PRIVS *q_q, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length);
+BOOL lsa_io_q_enum_privs(char *desc, LSA_Q_ENUM_PRIVS *q_q, prs_struct *ps, int depth);
+void init_lsa_r_enum_privs(LSA_R_ENUM_PRIVS *r_u, uint32 enum_context,
+ uint32 count, LSA_PRIV_ENTRY *entries);
+BOOL lsa_io_r_enum_privs(char *desc, LSA_R_ENUM_PRIVS *r_q, prs_struct *ps, int depth);
+void init_lsa_priv_get_dispname(LSA_Q_PRIV_GET_DISPNAME *trn, POLICY_HND *hnd, char *name, uint16 lang_id, uint16 lang_id_sys);
+BOOL lsa_io_q_priv_get_dispname(char *desc, LSA_Q_PRIV_GET_DISPNAME *q_q, prs_struct *ps, int depth);
+BOOL lsa_io_r_priv_get_dispname(char *desc, LSA_R_PRIV_GET_DISPNAME *r_q, prs_struct *ps, int depth);
+void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length);
+BOOL lsa_io_q_enum_accounts(char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_struct *ps, int depth);
+void init_lsa_r_enum_accounts(LSA_R_ENUM_ACCOUNTS *r_u, uint32 enum_context);
+BOOL lsa_io_r_enum_accounts(char *desc, LSA_R_ENUM_ACCOUNTS *r_q, prs_struct *ps, int depth);
BOOL lsa_io_q_unk_get_connuser(char *desc, LSA_Q_UNK_GET_CONNUSER *q_c, prs_struct *ps, int depth);
BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_open_account(char *desc, LSA_Q_OPENACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_open_account(char *desc, LSA_R_OPENACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_enum_privsaccount(char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_luid_attr(char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_privilege_set(char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth);
+void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control);
+BOOL lsa_io_r_enum_privsaccount(char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_q_getsystemaccount(char *desc, LSA_Q_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
+BOOL lsa_io_r_getsystemaccount(char *desc, LSA_R_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_misc.c */
@@ -2548,7 +2594,7 @@ void init_enum_hnd(ENUM_HND *enh, uint32 hnd);
BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
void init_dom_sid(DOM_SID *sid, char *str_sid);
-void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid);
+void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
@@ -2572,8 +2618,8 @@ BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
void init_buffer2(BUFFER2 *str, uint8 *buf, int len);
BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
-void copy_unistr2(UNISTR2 *str, UNISTR2 *from);
-void init_string2(STRING2 *str, char *buf, int len);
+void copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
+void init_string2(STRING2 *str, const char *buf, int max_len, int str_len);
BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
void init_unistr2(UNISTR2 *str, const char *buf, size_t len);
void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from);
@@ -2606,6 +2652,10 @@ BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
void init_unistr3(UNISTR3 *str, const char *buf);
BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
BOOL prs_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64);
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_uni_hdr(UNIHDR *hdr, int len);
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
/*The following definitions come from rpc_parse/parse_net.c */
@@ -2650,12 +2700,13 @@ void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
char *user_name, char *wksta_name,
char *sess_key,
unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
-void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- unsigned char lm_challenge[8],
- unsigned char *lm_chal_resp,
- unsigned char *nt_chal_resp);
+void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar * lm_chal_resp, int lm_chal_resp_len,
+ const uchar * nt_chal_resp, int nt_chal_resp_len);
void init_sam_info(DOM_SAM_INFO *sam,
char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
DOM_CRED *rtn_cred, uint16 logon_level,
@@ -2663,13 +2714,39 @@ void init_sam_info(DOM_SAM_INFO *sam,
void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
uint16 logon_count, uint16 bad_pw_count,
uint32 num_groups, DOM_GID *gids,
- uint32 user_flgs, char *sess_key,
+ uint32 user_flgs, uchar *sess_key,
char *logon_srv, char *logon_dom,
DOM_SID *dom_sid, char *other_sids);
BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
+ const char *cli_name, DOM_CRED * cli_creds,
+ uint32 database_id);
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
+ int depth);
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial);
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth);
+BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name,
+ const char *cli_name, DOM_CRED *cli_creds,
+ uint32 database_id, UINT64_S dom_mod_count);
+BOOL net_io_q_sam_deltas(char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
+ int depth);
+BOOL net_io_r_sam_deltas(char *desc, uint8 sess_key[16],
+ NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_prs.c */
@@ -2678,6 +2755,7 @@ void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name);
BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io);
BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout);
void prs_mem_free(prs_struct *ps);
+void prs_mem_clear(prs_struct *ps);
char *prs_alloc_mem(prs_struct *ps, size_t size);
TALLOC_CTX *prs_get_mem_context(prs_struct *ps);
void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic);
@@ -2701,6 +2779,8 @@ void prs_force_dynamic(prs_struct *ps);
BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL prs_ntstatus(char *name, prs_struct *ps, int depth, NTSTATUS *status);
+BOOL prs_werror(char *name, prs_struct *ps, int depth, WERROR *status);
BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
BOOL prs_uint16uni(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
@@ -2720,13 +2800,20 @@ BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
uint32 ptr_uint32, uint32 data_size);
int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps);
int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *mem_ctx);
+BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
/*The following definitions come from rpc_parse/parse_reg.c */
-void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+void init_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth);
+void init_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+ uint16 unknown_0, uint32 access_mask);
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+ int depth);
void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
@@ -2767,7 +2854,7 @@ BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, i
BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name);
BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- BUFFER2* buf, uint32 type, uint32 status);
+ BUFFER2* buf, uint32 type, NTSTATUS status);
BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
uint32 val_idx, uint32 max_val_len,
@@ -2786,8 +2873,19 @@ void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
char *key_name, uint32 unk);
BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
- POLICY_HND *pol, uint32 status);
+ POLICY_HND *pol, NTSTATUS status);
BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
+void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s,
+ const char *msg, uint32 timeout, uint16 flags);
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
+ int depth);
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
+ int depth);
+void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN * q_s);
+BOOL reg_io_q_abort_shutdown(char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
+ prs_struct *ps, int depth);
+BOOL reg_io_r_abort_shutdown(char *desc, REG_R_ABORT_SHUTDOWN * r_s,
+ prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_rpc.c */
@@ -2855,7 +2953,7 @@ void init_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN * q_u,
BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN * q_u,
prs_struct *ps, int depth);
void init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
- DOM_SID *dom_sid, uint32 status);
+ DOM_SID *dom_sid, NTSTATUS status);
BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
prs_struct *ps, int depth);
void init_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D * q_u, POLICY_HND *dom_pol, DOM_SID *sid);
@@ -2865,7 +2963,7 @@ BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
prs_struct *ps, int depth);
void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
POLICY_HND *pol, uint32 flags,
- DOM_SID *sid);
+ const DOM_SID *sid);
BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN * q_u,
prs_struct *ps, int depth);
BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
@@ -2874,7 +2972,7 @@ void init_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO * q_u,
POLICY_HND *user_pol);
BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
prs_struct *ps, int depth);
-void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, uint32 status);
+void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, NTSTATUS status);
BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ * q_u,
@@ -2885,17 +2983,19 @@ void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO * q_u,
POLICY_HND *domain_pol, uint16 switch_value);
BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
prs_struct *ps, int depth);
-void init_unk_info3(SAM_UNK_INFO_3 * u_3);
+void init_unk_info3(SAM_UNK_INFO_3 *u_3, NTTIME nt_logout);
void init_unk_info6(SAM_UNK_INFO_6 * u_6);
void init_unk_info7(SAM_UNK_INFO_7 * u_7);
-void init_unk_info12(SAM_UNK_INFO_12 * u_12);
+void init_unk_info12(SAM_UNK_INFO_12 * u_12, NTTIME nt_lock_duration, NTTIME nt_reset_time, uint16 lockout);
+void init_unk_info5(SAM_UNK_INFO_5 * u_5,char *server);
void init_unk_info2(SAM_UNK_INFO_2 * u_2,
char *domain, char *server,
- uint32 seq_num);
-void init_unk_info1(SAM_UNK_INFO_1 * u_1);
+ uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias);
+void init_unk_info1(SAM_UNK_INFO_1 *u_1, uint16 min_pass_len, uint16 pass_hist,
+ uint32 flag, NTTIME nt_expire, NTTIME nt_min_age);
void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
uint16 switch_value, SAM_UNK_CTR * ctr,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
prs_struct *ps, int depth);
BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
@@ -2915,25 +3015,20 @@ void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO * q_e, POLICY_HND *pol,
uint32 max_entries);
BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
prs_struct *ps, int depth);
-uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- DOMAIN_GRP * grp);
-uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- DOMAIN_GRP * grp);
+NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info);
+NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info);
+NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info);
void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
- uint32 num_entries, uint32 data_size,
+ uint32 num_entries, uint32 total_size, uint32 data_size,
uint16 switch_level, SAM_DISPINFO_CTR * ctr,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
@@ -2948,6 +3043,8 @@ void init_samr_group_info1(GROUP_INFO1 * gr1,
uint32 num_members);
BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
prs_struct *ps, int depth);
+void init_samr_group_info3(GROUP_INFO3 *gr3);
+BOOL samr_io_group_info3(char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int depth);
void init_samr_group_info4(GROUP_INFO4 * gr4, char *acct_desc);
BOOL samr_io_group_info4(char *desc, GROUP_INFO4 * gr4,
prs_struct *ps, int depth);
@@ -2969,7 +3066,7 @@ void init_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM * q_e,
BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM * q_e,
prs_struct *ps, int depth);
void init_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
prs_struct *ps, int depth);
void init_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
@@ -2977,14 +3074,14 @@ void init_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM * q_e,
BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM * q_e,
prs_struct *ps, int depth);
void init_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
prs_struct *ps, int depth);
void init_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO * q_e,
POLICY_HND *pol, GROUP_INFO_CTR * ctr);
BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
prs_struct *ps, int depth);
-void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status);
+void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, NTSTATUS status);
BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
@@ -2992,7 +3089,7 @@ void init_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO * q_e,
BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO * q_e,
prs_struct *ps, int depth);
void init_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
- GROUP_INFO_CTR * ctr, uint32 status);
+ GROUP_INFO_CTR * ctr, NTSTATUS status);
BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM * q_c, POLICY_HND *hnd);
@@ -3000,7 +3097,7 @@ BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM * q_u,
prs_struct *ps, int depth);
void init_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
uint32 num_entries, uint32 *rid,
- uint32 *attr, uint32 status);
+ uint32 *attr, NTSTATUS status);
BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
prs_struct *ps, int depth);
void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS * q_u,
@@ -3009,7 +3106,7 @@ BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS * q_u,
prs_struct *ps, int depth);
void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
uint32 num_gids, DOM_GID * gid,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID ** gid,
prs_struct *ps, int depth);
BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
@@ -3040,6 +3137,9 @@ BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES * q_e,
void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u, uint32 next_idx, uint32 num_sam_entries);
BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
prs_struct *ps, int depth);
+void init_samr_alias_info1(ALIAS_INFO1 * al1, char *acct_name, uint32 num_member, char *acct_desc);
+BOOL samr_io_alias_info1(char *desc, ALIAS_INFO1 * al1,
+ prs_struct *ps, int depth);
void init_samr_alias_info3(ALIAS_INFO3 * al3, char *acct_desc);
BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 * al3,
prs_struct *ps, int depth);
@@ -3050,7 +3150,7 @@ void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO * q_e,
BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO * q_e,
prs_struct *ps, int depth);
void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
- ALIAS_INFO_CTR * ctr, uint32 status);
+ ALIAS_INFO_CTR * ctr, NTSTATUS status);
BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO * q_u,
@@ -3067,7 +3167,7 @@ BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES * q_u,
prs_struct *ps, int depth);
void init_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
uint32 num_rids, uint32 *rid,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid,
prs_struct *ps, int depth);
BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
@@ -3116,7 +3216,7 @@ void init_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS * q_c,
BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS * q_u,
prs_struct *ps, int depth);
void init_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
prs_struct *ps, int depth);
void init_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM * q_c,
@@ -3125,18 +3225,18 @@ BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM * q_u,
prs_struct *ps, int depth);
void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
uint32 num_sids, DOM_SID2 * sid,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
prs_struct *ps, int depth);
-uint32 init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
+NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
POLICY_HND *pol, uint32 flags,
uint32 num_names, char **name);
BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
prs_struct *ps, int depth);
-uint32 init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
+NTSTATUS init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
uint32 num_rids,
uint32 *rid, uint32 *type,
- uint32 status);
+ NTSTATUS status);
BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
prs_struct *ps, int depth);
void init_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER * q_c,
@@ -3154,7 +3254,7 @@ BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
prs_struct *ps, int depth);
void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
POLICY_HND *pol,
- char *name,
+ const char *name,
uint32 acb_info, uint32 access_mask);
BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER * q_u,
prs_struct *ps, int depth);
@@ -3165,7 +3265,7 @@ void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u,
BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u,
prs_struct *ps, int depth);
void init_sam_user_info12(SAM_USER_INFO_12 * usr,
- uint8 lm_pwd[16], uint8 nt_pwd[16]);
+ const uint8 lm_pwd[16], const uint8 nt_pwd[16]);
void init_sam_user_info10(SAM_USER_INFO_10 * usr, uint32 acb_info);
void init_sam_user_info11(SAM_USER_INFO_11 * usr,
NTTIME * expiry,
@@ -3238,13 +3338,14 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
LOGON_HRS * hrs,
uint32 unknown_5, uint32 unknown_6);
void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw);
-uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
+void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw);
+NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
uint16 switch_value,
SAM_USER_INFO_21 * usr);
void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
uint16 switch_value, void *info);
void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
- SAM_USERINFO_CTR * ctr, uint32 status);
+ SAM_USERINFO_CTR * ctr, NTSTATUS status);
BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
@@ -3252,7 +3353,7 @@ void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
uint16 switch_value, void *info);
BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
prs_struct *ps, int depth);
-void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status);
+void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, NTSTATUS status);
BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
prs_struct *ps, int depth);
void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
@@ -3260,7 +3361,7 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
uint16 switch_value, SAM_USERINFO_CTR * ctr);
BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
prs_struct *ps, int depth);
-void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status);
+void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, NTSTATUS status);
BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
prs_struct *ps, int depth);
void init_samr_q_connect(SAMR_Q_CONNECT * q_u,
@@ -3294,9 +3395,25 @@ void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
uchar lm_oldhash[16]);
BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
prs_struct *ps, int depth);
-void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status);
+void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, NTSTATUS status);
BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
prs_struct *ps, int depth);
+void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL samr_io_q_unknown_2e(char *desc, SAMR_Q_UNKNOWN_2E *q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u,
+ uint16 switch_value, SAM_UNK_CTR * ctr,
+ NTSTATUS status);
+BOOL samr_io_r_samr_unknown_2e(char *desc, SAMR_R_UNKNOWN_2E * r_u,
+ prs_struct *ps, int depth);
+void init_samr_q_set_domain_info(SAMR_Q_SET_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value, SAM_UNK_CTR *ctr);
+BOOL samr_io_q_set_domain_info(char *desc, SAMR_Q_SET_DOMAIN_INFO *q_u,
+ prs_struct *ps, int depth);
+void init_samr_r_set_domain_info(SAMR_R_SET_DOMAIN_INFO * r_u, NTSTATUS status);
+BOOL samr_io_r_set_domain_info(char *desc, SAMR_R_SET_DOMAIN_INFO * r_u,
+ prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_sec.c */
@@ -3343,11 +3460,8 @@ BOOL make_spoolss_q_addprinterex(
const char* user_name,
uint32 level,
PRINTER_INFO_CTR *ctr);
-BOOL make_spoolss_printer_info_2(
- TALLOC_CTX *mem_ctx,
- SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
- PRINTER_INFO_2 *info
-);
+BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
+ PRINTER_INFO_2 *info);
BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
BOOL make_spoolss_q_deleteprinterdriver(
TALLOC_CTX *mem_ctx,
@@ -3391,6 +3505,8 @@ BOOL smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info,
BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
BOOL smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth);
+BOOL smb_io_printer_info_4(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth);
+BOOL smb_io_printer_info_5(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth);
BOOL smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth);
BOOL smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth);
BOOL smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
@@ -3412,6 +3528,8 @@ BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *
uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info);
uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info);
uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info);
+uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info);
+uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info);
uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info);
uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info);
@@ -3423,9 +3541,11 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
uint32 spoolss_size_form_1(FORM_1 *info);
uint32 spoolss_size_port_info_1(PORT_INFO_1 *info);
uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info);
+uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info);
uint32 spoolss_size_port_info_2(PORT_INFO_2 *info);
uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
+uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p);
uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
@@ -3458,14 +3578,9 @@ BOOL make_spoolss_q_getprinter(
NEW_BUFFER *buffer,
uint32 offered
);
-BOOL make_spoolss_q_setprinter(
- TALLOC_CTX *mem_ctx,
- SPOOL_Q_SETPRINTER *q_u,
- const POLICY_HND *hnd,
- uint32 level,
- PRINTER_INFO_CTR *info,
- uint32 command
-);
+BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
+ const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
+ uint32 command);
BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
@@ -3521,12 +3636,7 @@ BOOL make_spoolss_driver_info_3(
SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
DRIVER_INFO_3 *info3
);
-BOOL make_spoolss_buffer5(
- TALLOC_CTX *mem_ctx,
- BUFFER5 *buf5,
- uint32 len,
- uint16 *src
-);
+BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src);
BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
@@ -3553,6 +3663,8 @@ BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_
BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
const POLICY_HND *hnd,
uint32 idx, uint32 valuelen, uint32 datalen);
+BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
+ char* value, char* data);
BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
@@ -3569,6 +3681,8 @@ void free_devmode(DEVICEMODE *devmode);
void free_printer_info_1(PRINTER_INFO_1 *printer);
void free_printer_info_2(PRINTER_INFO_2 *printer);
void free_printer_info_3(PRINTER_INFO_3 *printer);
+void free_printer_info_4(PRINTER_INFO_4 *printer);
+void free_printer_info_5(PRINTER_INFO_5 *printer);
void free_job_info_2(JOB_INFO_2 *job);
BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u,
const fstring string, uint32 printer, uint32 type);
@@ -3581,6 +3695,18 @@ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
uint32 change_low, uint32 change_high);
BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth);
BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getprinterdataex(char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setprinterdataex(char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setprinterdataex(char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterkey(char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterdataex(char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered);
+BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth);
+BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth);
/*The following definitions come from rpc_parse/parse_srv.c */
@@ -3665,9 +3791,9 @@ void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
char *server_name, uint32 switch_value);
BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
- uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
+ uint32 switch_value, SRV_INFO_CTR *ctr, NTSTATUS status);
void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
- uint32 switch_value, uint32 status);
+ uint32 switch_value, NTSTATUS status);
BOOL srv_io_q_net_srv_set_info(char *desc, SRV_Q_NET_SRV_SET_INFO *q_n,
prs_struct *ps, int depth);
BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
@@ -3697,8 +3823,8 @@ void init_wks_info_100(WKS_INFO_100 *inf,
uint32 platform_id, uint32 ver_major, uint32 ver_minor,
char *my_name, char *domain_name);
void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
- uint32 switch_value, WKS_INFO_100 *wks100,
- int status) ;
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ NTSTATUS status) ;
BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
/*The following definitions come from rpc_server/srv_dfs.c */
@@ -3708,10 +3834,12 @@ BOOL api_netdfs_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_dfs_nt.c */
uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u);
-uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u);
-uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u);
-uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
-uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u);
+WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u);
+WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
+ DFS_R_DFS_REMOVE *r_u);
+WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
+WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
+ DFS_R_DFS_GET_INFO *r_u);
/*The following definitions come from rpc_server/srv_lsa.c */
@@ -3727,15 +3855,19 @@ void close_policy_by_pipe(pipes_struct *p);
/*The following definitions come from rpc_server/srv_lsa_nt.c */
-uint32 _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u);
-uint32 _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u);
-uint32 _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u);
-uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u);
-uint32 _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u);
-uint32 _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u);
-uint32 _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u);
-uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u);
-uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u);
+NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u);
+NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u);
+NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u);
+NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u);
+NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u);
+NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u);
+NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u);
+NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u);
+NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u);
+NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u);
+NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u);
+NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u);
+NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u);
/*The following definitions come from rpc_server/srv_netlog.c */
@@ -3743,20 +3875,22 @@ BOOL api_netlog_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_netlog_nt.c */
-uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u);
-uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u);
-uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u);
-uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u);
-uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u);
-uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u);
-uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u);
-uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u);
+NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u,
+ NET_R_LOGON_CTRL *r_u);
+NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u);
+NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u);
+NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u);
+NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u);
+NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u);
+NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u);
+NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u);
+NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u);
/*The following definitions come from rpc_server/srv_pipe.c */
BOOL create_next_pdu(pipes_struct *p);
BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p);
-BOOL setup_fault_pdu(pipes_struct *p, uint32 status);
+BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status);
BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
RPC_IFACE* transfer);
BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p);
@@ -3790,10 +3924,10 @@ BOOL api_reg_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_reg_nt.c */
-uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u);
-uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u);
-uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u);
-uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u);
+NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u);
+NTSTATUS _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u);
+NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u);
+NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u);
/*The following definitions come from rpc_server/srv_samr.c */
@@ -3801,47 +3935,47 @@ BOOL api_samr_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_samr_nt.c */
-uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u);
-uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u);
-uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u);
-uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u);
-uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u);
-uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u);
-uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u);
-uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u);
-uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u);
-uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u);
-uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u);
-uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u);
-uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u);
-uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u);
-uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u);
-uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u);
-uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u);
-uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u);
-uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u);
-uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u);
-uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u);
-uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u);
-uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u);
-uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u);
-uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u);
-uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u);
-uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u);
-uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u);
-uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u);
-uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u);
-uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u);
-uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u );
-uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u);
-uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u);
-uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u);
-uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u);
-uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u);
-uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u);
-uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u);
-uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u);
-uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u);
+NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u);
+NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u);
+NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u);
+NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u);
+NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u);
+NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u);
+NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u);
+NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u);
+NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u);
+NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u);
+NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u);
+NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u);
+NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u);
+NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u);
+NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u);
+NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u);
+NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u);
+NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u);
+NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u);
+NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u);
+NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u);
+NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u);
+NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u);
+NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u);
+NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u);
+NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u);
+NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u);
+NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u);
+NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u);
+NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u);
+NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u);
+NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u );
+NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u);
+NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u);
+NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u);
+NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u);
+NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u);
+NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u);
+NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u);
+NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u);
+NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u);
/*The following definitions come from rpc_server/srv_spoolss.c */
@@ -3849,48 +3983,53 @@ BOOL api_spoolss_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_spoolss_nt.c */
-uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u);
+WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u);
BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
NT_DEVICEMODE **pp_nt_devmode);
-uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u);
-uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u);
-uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u);
+WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u);
+WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
SPOOL_R_DELETEPRINTERDRIVER *r_u);
-uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u);
-uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u);
-uint32 _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u);
-uint32 _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
-uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
-uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u);
-uint32 _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u);
-uint32 _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u);
-uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u);
-uint32 _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u);
-uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u);
-uint32 _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u);
-uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u);
-uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u);
-uint32 _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u);
-uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u);
-uint32 _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u);
-uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u);
-uint32 _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u);
-uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u);
-uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u);
-uint32 _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u);
-uint32 _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u);
-uint32 _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u);
-uint32 _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u);
-uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u);
-uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u);
-uint32 _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u);
-uint32 _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u);
-uint32 _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u);
-uint32 _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u);
-uint32 _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u);
-uint32 _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u);
-uint32 _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u);
-uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u);
+WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u);
+WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u);
+WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u);
+WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u);
+WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u);
+WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u);
+WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u);
+WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u);
+WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u);
+WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u);
+WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u);
+WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u);
+WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u);
+WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u);
+WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u);
+WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u);
+WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u);
+WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u);
+WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u);
+WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u);
+WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u);
+WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u);
+WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u);
+WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u);
+WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u);
+WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u);
+WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u);
+WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u);
+WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u);
+WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u);
+WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u);
+WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u);
+WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u);
+WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u);
+WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u);
+WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u);
+WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u);
+WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u);
+WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u);
+WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u);
/*The following definitions come from rpc_server/srv_srvsvc.c */
@@ -3901,35 +4040,35 @@ BOOL api_srvsvc_rpc(pipes_struct *p);
BOOL share_info_db_init(void);
void map_generic_share_sd_bits(SEC_DESC *psd);
BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access);
-uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u);
-uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u);
-uint32 _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u);
-uint32 _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u);
-uint32 _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u);
-uint32 _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
-uint32 _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
-uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u);
-uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u);
-uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u);
-uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u);
-uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u);
-uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
+NTSTATUS _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u);
+NTSTATUS _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u);
+NTSTATUS _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u);
+NTSTATUS _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u);
+NTSTATUS _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u);
+NTSTATUS _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
+NTSTATUS _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u);
+NTSTATUS _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u);
+NTSTATUS _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u);
+NTSTATUS _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u);
+NTSTATUS _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u);
+NTSTATUS _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u);
+NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
SRV_R_NET_FILE_QUERY_SECDESC *r_u);
-uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
+NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
SRV_R_NET_FILE_SET_SECDESC *r_u);
-uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u);
-uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u);
+NTSTATUS _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u);
+NTSTATUS _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u);
/*The following definitions come from rpc_server/srv_util.c */
int make_dom_gids(TALLOC_CTX *ctx, char *gids_str, DOM_GID **ppgids);
void get_domain_user_groups(char *domain_groups, char *user);
-uint32 local_lookup_group_name(uint32 rid, char *group_name, uint32 *type);
-uint32 local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
-uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type);
-uint32 local_lookup_group_rid(char *group_name, uint32 *rid);
-uint32 local_lookup_alias_rid(char *alias_name, uint32 *rid);
-uint32 local_lookup_user_rid(char *user_name, uint32 *rid);
+NTSTATUS local_lookup_group_name(uint32 rid, char *group_name, uint32 *type);
+NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
+NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type);
+NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid);
+NTSTATUS local_lookup_alias_rid(char *alias_name, uint32 *rid);
+NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid);
/*The following definitions come from rpc_server/srv_wkssvc.c */
@@ -3937,34 +4076,7 @@ BOOL api_wkssvc_rpc(pipes_struct *p);
/*The following definitions come from rpc_server/srv_wkssvc_nt.c */
-uint32 _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO *r_u);
-
-/*The following definitions come from rpcclient/cmd_lsarpc.c */
-
-
-/*The following definitions come from rpcclient/cmd_netlogon.c */
-
-
-/*The following definitions come from rpcclient/cmd_samr.c */
-
-void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1);
-
-/*The following definitions come from rpcclient/cmd_spoolss.c */
-
-BOOL get_short_archi(char *short_archi, char *long_archi);
-void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch);
-
-/*The following definitions come from rpcclient/cmd_srvsvc.c */
-
-
-/*The following definitions come from rpcclient/rpcclient.c */
-
-void fetch_domain_sid(struct cli_state *cli);
-void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
- char* domain, char* password);
-void add_command_set(struct cmd_set *cmd_set);
-struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
- struct ntuser_creds *creds);
+NTSTATUS _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO *r_u);
/*The following definitions come from smbd/blocking.c */
@@ -4014,7 +4126,7 @@ void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len);
/*The following definitions come from smbd/connection.c */
TDB_CONTEXT *conn_tdb_ctx(void);
-BOOL yield_connection(connection_struct *conn,char *name,int max_connections);
+BOOL yield_connection(connection_struct *conn,char *name);
BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear);
/*The following definitions come from smbd/dfree.c */
@@ -4060,8 +4172,11 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime);
/*The following definitions come from smbd/error.c */
-int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line, const char *file);
-int error_packet(char *outbuf,uint32 nt_err, int error_class,uint32 error_code,int line, const char *file);
+int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file);
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
+ int line, const char *file);
+int error_packet(char *outbuf,NTSTATUS ntstatus,
+ uint8 eclass,uint32 ecode,int line, const char *file);
/*The following definitions come from smbd/fileio.c */
@@ -4086,7 +4201,8 @@ files_struct *file_new(connection_struct *conn);
void file_close_conn(connection_struct *conn);
void file_init(void);
void file_close_user(int vuid);
-files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
+files_struct *file_find_fd(int fd);
+files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id);
files_struct *file_find_fsp(files_struct *orig_fsp);
files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode);
files_struct *file_find_di_next(files_struct *start_fsp);
@@ -4139,7 +4255,7 @@ int reply_negprot(connection_struct *conn,
/*The following definitions come from smbd/noquotas.c */
-BOOL disk_quotas(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
+BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
/*The following definitions come from smbd/notify.c */
@@ -4180,7 +4296,7 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
files_struct *open_file_fchmod(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf);
int close_file_fchmod(files_struct *fsp);
files_struct *open_directory(connection_struct *conn, char *fname,
- SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action);
+ SMB_STRUCT_STAT *psbuf, int share_mode, int smb_ofun, mode_t unixmode, int *action);
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
/*The following definitions come from smbd/oplock.c */
@@ -4194,8 +4310,7 @@ BOOL remove_oplock(files_struct *fsp, BOOL break_to_none);
int setup_oplock_select_set( fd_set *fds);
BOOL process_local_message(char *buffer, int buf_size);
BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token);
-BOOL request_oplock_break(share_mode_entry *share_entry,
- SMB_DEV_T dev, SMB_INO_T inode);
+BOOL request_oplock_break(share_mode_entry *share_entry);
BOOL attempt_close_oplocked_file(files_struct *fsp);
void release_level_2_oplocks_on_change(files_struct *fsp);
BOOL init_oplocks(void);
@@ -4217,9 +4332,9 @@ void invalidate_vuid(uint16 vuid);
void invalidate_all_vuids(void);
char *validated_username(uint16 vuid);
char *validated_domain(uint16 vuid);
-NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest);
+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);
int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
- char *domain,BOOL guest);
+ char *domain,BOOL guest, NT_USER_TOKEN **pptok);
void add_session_user(char *user);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
@@ -4239,7 +4354,7 @@ BOOL server_validate(char *user, char *domain,
BOOL domain_client_validate( char *user, char *domain,
char *smb_apasswd, int smb_apasslen,
char *smb_ntpasswd, int smb_ntpasslen,
- BOOL *user_exists);
+ BOOL *user_exists, NT_USER_TOKEN **pptoken);
/*The following definitions come from smbd/pipes.c */
@@ -4254,7 +4369,7 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc);
BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd);
-int chmod_acl(char *name, mode_t mode);
+int chmod_acl(const char *name, mode_t mode);
int fchmod_acl(int fd, mode_t mode);
/*The following definitions come from smbd/process.c */
@@ -4291,8 +4406,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf,
- int dirtype, char *name);
+NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name);
int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
void fail_readraw(void);
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
@@ -4301,7 +4415,6 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int allocate_space_error(char *inbuf,char *outbuf, int errno_val);
int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize);
int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
@@ -4326,13 +4439,11 @@ int reply_printclose(connection_struct *conn,
int reply_printqueue(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory);
+NTSTATUS mkdir_internal(connection_struct *conn, pstring directory);
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
BOOL rmdir_internals(connection_struct *conn, char *directory);
int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-int rename_internals(connection_struct *conn,
- char *inbuf, char *outbuf, char *name,
- char *newname, BOOL replace_if_exists);
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists);
int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
@@ -4340,7 +4451,10 @@ uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format);
SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format);
SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err);
int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
/*The following definitions come from smbd/sec_ctx.c */
@@ -4364,7 +4478,7 @@ void exit_server(char *reason);
/*The following definitions come from smbd/service.c */
-BOOL become_service(connection_struct *conn,BOOL do_chdir);
+BOOL set_current_service(connection_struct *conn,BOOL do_chdir);
int add_home_service(char *service, char *homedir);
int find_service(char *service);
connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
@@ -4393,24 +4507,26 @@ BOOL reset_stat_cache( void );
/*The following definitions come from smbd/trans2.c */
-int reply_findclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize);
-int reply_findnclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize);
-int reply_transs2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize);
-int reply_trans2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize);
+void set_bad_path_error(int err, BOOL bad_path);
+NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close);
+int reply_findclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_findnclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_transs2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
+int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
/*The following definitions come from smbd/uid.c */
-BOOL become_guest(void);
-BOOL become_user(connection_struct *conn, uint16 vuid);
-BOOL unbecome_user(void );
+BOOL change_to_guest(void);
+BOOL change_to_user(connection_struct *conn, uint16 vuid);
+BOOL change_to_root_user(void);
BOOL become_authenticated_pipe_user(pipes_struct *p);
-BOOL unbecome_authenticated_pipe_user(pipes_struct *p);
+BOOL unbecome_authenticated_pipe_user(void);
+void init_conn_ctx(void);
void become_root(void);
void unbecome_root(void);
+BOOL become_user(connection_struct *conn, uint16 vuid);
+BOOL unbecome_user(void);
+void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok);
BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type);
BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type);
DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
@@ -4425,6 +4541,24 @@ void sys_utmp_yield(const char *username, const char *hostname,
void sys_utmp_claim(const char *username, const char *hostname,
const char *id_str, int id_num);
+/*The following definitions come from smbd/vfs.c */
+
+BOOL vfs_init(connection_struct *conn);
+BOOL vfs_directory_exist(connection_struct *conn, char *dname, SMB_STRUCT_STAT *st);
+int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode);
+char *vfs_getwd(connection_struct *conn, char *unix_path);
+BOOL vfs_object_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
+BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
+ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count);
+ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
+int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len);
+int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
+SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
+char *vfs_readdirname(connection_struct *conn, void *p);
+int vfs_ChDir(connection_struct *conn, char *path);
+char *vfs_GetWd(connection_struct *conn, char *path);
+BOOL reduce_name(connection_struct *conn, char *s,char *dir,BOOL widelinks);
+
/*The following definitions come from smbd/vfs-wrap.c */
int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user);
@@ -4458,6 +4592,9 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len);
BOOL vfswrap_lock(files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
int vfswrap_symlink(connection_struct *conn, const char *oldpath, const char *newpath);
int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_t bufsiz);
+int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath);
+int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev);
+char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path);
size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc);
size_t vfswrap_get_nt_acl(files_struct *fsp, char *name, SEC_DESC **ppdesc);
BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd);
@@ -4465,23 +4602,6 @@ BOOL vfswrap_set_nt_acl(files_struct *fsp, char *name, uint32 security_info_sent
int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode);
int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode);
-/*The following definitions come from smbd/vfs.c */
-
-BOOL vfs_init(connection_struct *conn);
-BOOL vfs_directory_exist(connection_struct *conn, char *dname, SMB_STRUCT_STAT *st);
-int vfs_mkdir(connection_struct *conn, char *fname, mode_t mode);
-char *vfs_getwd(connection_struct *conn, char *unix_path);
-BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
-ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count);
-ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
-int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len);
-int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
-SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
-char *vfs_readdirname(connection_struct *conn, void *p);
-int vfs_ChDir(connection_struct *conn, char *path);
-char *vfs_GetWd(connection_struct *conn, char *path);
-BOOL reduce_name(connection_struct *conn, char *s,char *dir,BOOL widelinks);
-
/*The following definitions come from smbwrapper/realcalls.c */
int real_utime(const char *name, struct utimbuf *buf);
@@ -4583,8 +4703,11 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey);
int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
-TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn);
int tdb_close(TDB_CONTEXT *tdb);
int tdb_lockall(TDB_CONTEXT *tdb);
void tdb_unlockall(TDB_CONTEXT *tdb);
@@ -4604,13 +4727,20 @@ int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len);
int tdb_fetch_int(TDB_CONTEXT *tdb, char *keystr);
int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v);
int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v);
+int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len);
+int32 tdb_fetch_int32(TDB_CONTEXT *tdb, char *keystr);
+int tdb_store_int32_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int32 v);
+int tdb_store_int32(TDB_CONTEXT *tdb, char *keystr, int32 v);
int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len);
TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr);
int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val);
+int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int32 change_val);
size_t tdb_pack(char *buf, int bufsize, char *fmt, ...);
int tdb_unpack(char *buf, int bufsize, char *fmt, ...);
TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
+int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+ void *state);
/*The following definitions come from utils/nbio.c */
diff --git a/source/include/rpc_brs.h b/source/include/rpc_brs.h
index 36d89ec151c..99ba8f2dd07 100644
--- a/source/include/rpc_brs.h
+++ b/source/include/rpc_brs.h
@@ -73,7 +73,7 @@ typedef struct r_brs_query_info_info
} info;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} BRS_R_QUERY_INFO;
diff --git a/source/include/rpc_client.h b/source/include/rpc_client.h
index 1d7bee41055..270545c2a3f 100644
--- a/source/include/rpc_client.h
+++ b/source/include/rpc_client.h
@@ -22,6 +22,8 @@
#ifndef _RPC_CLIENT_H
#define _RPC_CLIENT_H
+#if 0 /* JERRY */
#include "rpc_client_proto.h"
+#endif
#endif /* _RPC_CLIENT_H */
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index 96704b33610..f9ebaae0b81 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -161,7 +161,7 @@ typedef struct rpc_hdr_resp_info
/* RPC_HDR_FAULT - fault rpc header */
typedef struct rpc_hdr_fault_info
{
- uint32 status;
+ NTSTATUS status;
uint32 reserved; /* 0x0000 0000 */
} RPC_HDR_FAULT;
diff --git a/source/include/rpc_dfs.h b/source/include/rpc_dfs.h
index 193075f754d..5222d6b3565 100644
--- a/source/include/rpc_dfs.h
+++ b/source/include/rpc_dfs.h
@@ -35,16 +35,6 @@
#define DFSFLAG_ADD_VOLUME 0x00000001
#define DFSFLAG_RESTORE_VOLUME 0x00000002
-#ifndef NERR_BASE
-#define NERR_BASE (2100)
-#endif
-
-#define NERR_DfsNoSuchVolume (NERR_BASE+562)
-#define NERR_DfsNoSuchShare (NERR_BASE+565)
-#define NERR_DfsNoSuchServer (NERR_BASE+573)
-#define NERR_DfsInternalError (NERR_BASE+590)
-#define NERR_DfsCantCreateJunctionPoint (NERR_BASE+569)
-
typedef struct dfs_q_dfs_exist
{
uint32 dummy;
@@ -54,7 +44,7 @@ DFS_Q_DFS_EXIST;
/* status == 1 if dfs exists. */
typedef struct dfs_r_dfs_exist
{
- uint32 status;
+ uint32 status; /* Not a WERROR or NTSTATUS code */
}
DFS_R_DFS_EXIST;
@@ -74,7 +64,7 @@ DFS_Q_DFS_ADD;
typedef struct dfs_r_dfs_add
{
- uint32 status;
+ WERROR status;
}
DFS_R_DFS_ADD;
@@ -91,7 +81,7 @@ DFS_Q_DFS_REMOVE;
typedef struct dfs_r_dfs_remove
{
- uint32 status;
+ WERROR status;
}
DFS_R_DFS_REMOVE;
@@ -172,7 +162,7 @@ typedef struct dfs_r_dfs_get_info
uint32 level;
uint32 ptr_ctr;
DFS_INFO_CTR ctr;
- uint32 status;
+ WERROR status;
}
DFS_R_DFS_GET_INFO;
@@ -201,7 +191,7 @@ typedef struct dfs_r_dfs_enum
uint32 ptr_num_entries2;
uint32 num_entries2;
ENUM_HND reshnd;
- uint32 status;
+ WERROR status;
}
DFS_R_DFS_ENUM;
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index 1a6e178068a..a9a28a63ac3 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -39,15 +39,53 @@ enum SID_NAME_USE
SID_NAME_UNKNOWN = 8 /* oops. */
};
-/* ntlsa pipe */
+/* Opcodes available on this pipe */
+
#define LSA_CLOSE 0x00
+#define LSA_DELETE 0x01
+#define LSA_ENUM_PRIVS 0x02
+#define LSA_QUERYSECOBJ 0x03
+#define LSA_SETSECOBJ 0x04
+#define LSA_CHANGEPASSWORD 0x05
+#define LSA_OPENPOLICY 0x06
#define LSA_QUERYINFOPOLICY 0x07
+#define LSA_SETINFOPOLICY 0x08
+#define LSA_CLEARAUDITLOG 0x09
+#define LSA_CREATEACCOUNT 0x0a
+#define LSA_ENUM_ACCOUNTS 0x0b
+#define LSA_CREATETRUSTDOM 0x0c
#define LSA_ENUMTRUSTDOM 0x0d
#define LSA_LOOKUPNAMES 0x0e
#define LSA_LOOKUPSIDS 0x0f
-#define LSA_OPENPOLICY 0x06
+#define LSA_CREATESECRET 0x10
+#define LSA_OPENACCOUNT 0x11
+#define LSA_ENUMPRIVSACCOUNT 0x12
+#define LSA_ADDPRIVS 0x13
+#define LSA_REMOVEPRIVS 0x14
+#define LSA_GETQUOTAS 0x15
+#define LSA_SETQUOTAS 0x16
+#define LSA_GETSYSTEMACCOUNT 0x17
+#define LSA_SETSYSTEMACCOUNT 0x18
+#define LSA_OPENTRUSTDOM 0x19
+#define LSA_QUERYTRUSTDOM 0x1a
+#define LSA_SETINFOTRUSTDOM 0x1b
+#define LSA_OPENSECRET 0x1c
+#define LSA_SETSECRET 0x1d
+#define LSA_QUERYSECRET 0x1e
+#define LSA_LOOKUPPRIVVALUE 0x1f
+#define LSA_LOOKUPPRIVNAME 0x20
+#define LSA_PRIV_GET_DISPNAME 0x21
+#define LSA_DELETEOBJECT 0x22
+#define LSA_ENUMACCTWITHRIGHT 0x23
+#define LSA_ENUMACCTRIGHTS 0x24
+#define LSA_ADDACCTRIGHTS 0x25
+#define LSA_REMOVEACCTRIGHTS 0x26
+#define LSA_QUERYTRUSTDOMINFO 0x27
+#define LSA_SETTRUSTDOMINFO 0x28
+#define LSA_DELETETRUSTDOM 0x29
+#define LSA_STOREPRIVDATA 0x2a
+#define LSA_RETRPRIVDATA 0x2b
#define LSA_OPENPOLICY2 0x2c
-#define LSA_OPENSECRET 0x1C
#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */
/* XXXX these are here to get a compile! */
@@ -124,7 +162,7 @@ typedef struct lsa_q_open_pol_info
typedef struct lsa_r_open_pol_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_OPEN_POL;
@@ -143,7 +181,7 @@ typedef struct lsa_q_open_pol2_info
typedef struct lsa_r_open_pol2_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_OPEN_POL2;
@@ -161,7 +199,7 @@ typedef struct r_lsa_query_sec_obj_info
uint32 ptr;
SEC_DESC_BUF *buf;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} LSA_R_QUERY_SEC_OBJ;
@@ -190,7 +228,7 @@ typedef struct lsa_r_query_info
LSA_INFO_UNION dom;
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_QUERY_INFO;
@@ -216,7 +254,7 @@ typedef struct lsa_r_enum_trust_dom_info
UNISTR2 *uni_domain_name;
DOM_SID2 *domain_sid;
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_ENUM_TRUST_DOM;
@@ -232,7 +270,7 @@ typedef struct lsa_r_close_info
{
POLICY_HND pol; /* policy handle. should be all zeros. */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_CLOSE;
@@ -325,7 +363,7 @@ typedef struct lsa_r_lookup_sids
LSA_TRANS_NAME_ENUM *names;
uint32 mapped_count;
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} LSA_R_LOOKUP_SIDS;
@@ -358,8 +396,7 @@ typedef struct lsa_r_lookup_names
uint32 mapped_count;
- uint32 status; /* return code */
-
+ NTSTATUS status; /* return code */
} LSA_R_LOOKUP_NAMES;
/* This is probably a policy handle but at the moment we
@@ -378,9 +415,75 @@ typedef struct lsa_r_open_secret
uint32 dummy2;
uint32 dummy3;
uint32 dummy4;
- uint32 status;
+ NTSTATUS status;
} LSA_R_OPEN_SECRET;
+typedef struct lsa_enum_priv_entry
+{
+ UNIHDR hdr_name;
+ uint32 luid_low;
+ uint32 luid_high;
+ UNISTR2 name;
+
+} LSA_PRIV_ENTRY;
+
+/* LSA_Q_ENUM_PRIVS - LSA enum privileges */
+typedef struct lsa_q_enum_privs
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 enum_context;
+ uint32 pref_max_length;
+} LSA_Q_ENUM_PRIVS;
+
+typedef struct lsa_r_enum_privs
+{
+ uint32 enum_context;
+ uint32 count;
+ uint32 ptr;
+ uint32 count1;
+
+ LSA_PRIV_ENTRY *privs;
+
+ NTSTATUS status;
+} LSA_R_ENUM_PRIVS;
+
+/* LSA_Q_PRIV_GET_DISPNAME - LSA get privilege display name */
+typedef struct lsa_q_priv_get_dispname
+{
+ POLICY_HND pol; /* policy handle */
+ UNIHDR hdr_name;
+ UNISTR2 name;
+ uint16 lang_id;
+ uint16 lang_id_sys;
+} LSA_Q_PRIV_GET_DISPNAME;
+
+typedef struct lsa_r_priv_get_dispname
+{
+ uint32 ptr_info;
+ UNIHDR hdr_desc;
+ UNISTR2 desc;
+ /* Don't align ! */
+ uint16 lang_id;
+ /* align */
+ NTSTATUS status;
+} LSA_R_PRIV_GET_DISPNAME;
+
+/* LSA_Q_ENUM_ACCOUNTS */
+typedef struct lsa_q_enum_accounts
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 enum_context;
+ uint32 pref_max_length;
+} LSA_Q_ENUM_ACCOUNTS;
+
+/* LSA_R_ENUM_ACCOUNTS */
+typedef struct lsa_r_enum_accounts
+{
+ uint32 enum_context;
+ LSA_SID_ENUM sids;
+ NTSTATUS status;
+} LSA_R_ENUM_ACCOUNTS;
+
/* LSA_Q_UNK_GET_CONNUSER - gets username\domain of connected user
called when "Take Ownership" is clicked -SK */
typedef struct lsa_q_unk_get_connuser
@@ -405,7 +508,83 @@ typedef struct lsa_r_unk_get_connuser
UNIHDR hdr_dom_name;
UNISTR2 uni2_dom_name;
- uint32 status;
+ NTSTATUS status;
} LSA_R_UNK_GET_CONNUSER;
+
+typedef struct lsa_q_openaccount
+{
+ POLICY_HND pol; /* policy handle */
+ DOM_SID2 sid;
+ uint32 access; /* desired access */
+} LSA_Q_OPENACCOUNT;
+
+typedef struct lsa_r_openaccount
+{
+ POLICY_HND pol; /* policy handle */
+ NTSTATUS status;
+} LSA_R_OPENACCOUNT;
+
+typedef struct lsa_q_enumprivsaccount
+{
+ POLICY_HND pol; /* policy handle */
+} LSA_Q_ENUMPRIVSACCOUNT;
+
+
+typedef struct LUID
+{
+ uint32 low;
+ uint32 high;
+} LUID;
+
+typedef struct LUID_ATTR
+{
+ LUID luid;
+ uint32 attr;
+} LUID_ATTR ;
+
+typedef struct privilege_set
+{
+ uint32 count;
+ uint32 control;
+ LUID_ATTR *set;
+} PRIVILEGE_SET;
+
+typedef struct lsa_r_enumprivsaccount
+{
+ uint32 ptr;
+ uint32 count;
+ PRIVILEGE_SET set;
+ NTSTATUS status;
+} LSA_R_ENUMPRIVSACCOUNT;
+
+typedef struct lsa_q_getsystemaccount
+{
+ POLICY_HND pol; /* policy handle */
+} LSA_Q_GETSYSTEMACCOUNT;
+
+typedef struct lsa_r_getsystemaccount
+{
+ uint32 access;
+ NTSTATUS status;
+} LSA_R_GETSYSTEMACCOUNT;
+
+
#endif /* _RPC_LSA_H */
+/*
+
+opnum 11: opensid: query: handle du domaine, sid du user
+reply: handle, status
+
+opnum 12: getlistofprivs: query: handle du user
+reply: ptr, nombre, nombre, tableau de 3 uint32: flag+priv.low+priv.high
+uint32 0, status
+
+opnum 17: ?? query: handle
+reply: uint32 + status
+
+
+*/
+
+
+
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index 428db938ded..558c28459e3 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -348,5 +348,24 @@ typedef struct uint64_s
uint32 high;
} UINT64_S;
+/* BUFHDR2 - another buffer header, with info level */
+typedef struct bufhdr2_info
+{
+ uint32 info_level;
+ uint32 length; /* uint8 chars */
+ uint32 buffer;
+
+}
+BUFHDR2;
+
+/* BUFFER4 - simple length and buffer */
+typedef struct buffer4_info
+{
+ uint32 buf_len;
+ uint8 buffer[MAX_BUFFERLEN];
+
+}
+BUFFER4;
+
#endif /* _RPC_MISC_H */
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index f15cec3ca9a..e86c5230ed1 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -43,6 +43,22 @@
#define SEC_CHAN_DOMAIN 4
#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_UNKNOWN 0x0D /* Privilige stuff */
+#define SAM_DELTA_UNKNOWN2 0x10 /* Privilige stuff */
+#define SAM_DELTA_SAM_STAMP 0x16 /* Some kind of journal record? */
+
+/* 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? */
+
#if 0
/* I think this is correct - it's what gets parsed on the wire. JRA. */
/* NET_USER_INFO_2 */
@@ -125,8 +141,9 @@ typedef struct net_user_info_3
uint16 logon_count; /* logon count */
uint16 bad_pw_count; /* bad password count */
- uint32 user_id; /* User ID */
- uint32 group_id; /* Group ID */
+ uint32 user_rid; /* User RID */
+ uint32 group_rid; /* Group RID */
+
uint32 num_groups; /* num groups */
uint32 buffer_groups; /* undocumented buffer pointer to groups. */
uint32 user_flgs; /* user flags */
@@ -226,7 +243,7 @@ typedef struct net_r_logon_ctrl_info
NETLOGON_INFO_1 info1;
} logon;
- uint32 status;
+ NTSTATUS status;
} NET_R_LOGON_CTRL;
/********************************************************
@@ -269,7 +286,7 @@ typedef struct net_r_logon_ctrl2_info
} logon;
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_LOGON_CTRL2;
@@ -288,7 +305,7 @@ typedef struct net_r_trust_dom_info
{
UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_TRUST_DOM_LIST;
@@ -315,10 +332,8 @@ typedef struct net_q_req_chal_info
/* NET_R_REQ_CHAL */
typedef struct net_r_req_chal_info
{
- DOM_CHAL srv_chal; /* server challenge */
-
- uint32 status; /* return code */
-
+ DOM_CHAL srv_chal; /* server challenge */
+ NTSTATUS status; /* return code */
} NET_R_REQ_CHAL;
/* NET_Q_AUTH */
@@ -332,7 +347,7 @@ typedef struct net_q_auth_info
typedef struct net_r_auth_info
{
DOM_CHAL srv_chal; /* server-calculated credentials */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_AUTH;
/* NET_Q_AUTH_2 */
@@ -349,11 +364,9 @@ typedef struct net_q_auth2_info
/* NET_R_AUTH_2 */
typedef struct net_r_auth2_info
{
- DOM_CHAL srv_chal; /* server-calculated credentials */
- NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
-
- uint32 status; /* return code */
-
+ DOM_CHAL srv_chal; /* server-calculated credentials */
+ NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
+ NTSTATUS status; /* return code */
} NET_R_AUTH_2;
@@ -370,7 +383,7 @@ typedef struct net_r_srv_pwset_info
{
DOM_CRED srv_cred; /* server-calculated credentials */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_SRV_PWSET;
@@ -459,7 +472,7 @@ typedef struct net_r_sam_logon_info
uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_SAM_LOGON;
@@ -477,8 +490,273 @@ typedef struct net_r_sam_logoff_info
uint32 buffer_creds; /* undocumented buffer pointer */
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} NET_R_SAM_LOGOFF;
+/* NET_Q_SAM_SYNC */
+typedef struct net_q_sam_sync_info
+{
+ UNISTR2 uni_srv_name; /* \\PDC */
+ UNISTR2 uni_cli_name; /* BDC */
+ DOM_CRED cli_creds;
+ DOM_CRED ret_creds;
+
+ uint32 database_id;
+ uint32 restart_state;
+ uint32 sync_context;
+
+ uint32 max_size; /* preferred maximum length */
+
+} NET_Q_SAM_SYNC;
+
+/* SAM_DELTA_HDR */
+typedef struct sam_delta_hdr_info
+{
+ uint16 type; /* type of structure attached */
+ uint16 type2;
+ uint32 target_rid;
+
+ uint32 type3;
+ uint32 ptr_delta;
+
+} SAM_DELTA_HDR;
+
+/* SAM_DOMAIN_INFO (0x1) */
+typedef struct sam_domain_info_info
+{
+ UNIHDR hdr_dom_name;
+ UNIHDR hdr_oem_info;
+
+ UINT64_S force_logoff;
+ uint16 min_pwd_len;
+ uint16 pwd_history_len;
+ UINT64_S max_pwd_age;
+ UINT64_S min_pwd_age;
+ UINT64_S dom_mod_count;
+ NTTIME creation_time;
+
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ UNIHDR hdr_unknown;
+ uint8 reserved[40];
+
+ UNISTR2 uni_dom_name;
+ UNISTR2 buf_oem_info; /* never seen */
+
+ BUFFER4 buf_sec_desc;
+ UNISTR2 buf_unknown;
+
+} SAM_DOMAIN_INFO;
+
+/* SAM_GROUP_INFO (0x2) */
+typedef struct sam_group_info_info
+{
+ UNIHDR hdr_grp_name;
+ DOM_GID gid;
+ UNIHDR hdr_grp_desc;
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ uint8 reserved[48];
+
+ UNISTR2 uni_grp_name;
+ UNISTR2 uni_grp_desc;
+ BUFFER4 buf_sec_desc;
+
+} SAM_GROUP_INFO;
+
+/* SAM_PWD */
+typedef struct sam_passwd_info
+{
+ /* this structure probably contains password history */
+ /* this is probably a count of lm/nt pairs */
+ uint32 unk_0; /* 0x0000 0002 */
+
+ UNIHDR hdr_lm_pwd;
+ uint8 buf_lm_pwd[16];
+
+ UNIHDR hdr_nt_pwd;
+ uint8 buf_nt_pwd[16];
+
+ UNIHDR hdr_empty_lm;
+ UNIHDR hdr_empty_nt;
+
+} SAM_PWD;
+
+/* SAM_ACCOUNT_INFO (0x5) */
+typedef struct sam_account_info_info
+{
+ UNIHDR hdr_acct_name;
+ UNIHDR hdr_full_name;
+
+ uint32 user_rid;
+ uint32 group_rid;
+
+ UNIHDR hdr_home_dir;
+ UNIHDR hdr_dir_drive;
+ UNIHDR hdr_logon_script;
+ UNIHDR hdr_acct_desc;
+ UNIHDR hdr_workstations;
+
+ NTTIME logon_time;
+ NTTIME logoff_time;
+
+ uint32 logon_divs; /* 0xA8 */
+ uint32 ptr_logon_hrs;
+
+ uint16 bad_pwd_count;
+ uint16 logon_count;
+ NTTIME pwd_last_set_time;
+ NTTIME acct_expiry_time;
+
+ uint32 acb_info;
+ uint8 nt_pwd[16];
+ uint8 lm_pwd[16];
+ uint8 nt_pwd_present;
+ uint8 lm_pwd_present;
+ uint8 pwd_expired;
+
+ UNIHDR hdr_comment;
+ UNIHDR hdr_parameters;
+ uint16 country;
+ uint16 codepage;
+
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+
+ UNIHDR hdr_profile;
+ UNIHDR hdr_reserved[3]; /* space for more strings */
+ uint32 dw_reserved[4]; /* space for more data - first two seem to
+ be an NTTIME */
+
+ UNISTR2 uni_acct_name;
+ UNISTR2 uni_full_name;
+ UNISTR2 uni_home_dir;
+ UNISTR2 uni_dir_drive;
+ UNISTR2 uni_logon_script;
+ UNISTR2 uni_acct_desc;
+ UNISTR2 uni_workstations;
+
+ uint32 unknown1; /* 0x4EC */
+ uint32 unknown2; /* 0 */
+
+ BUFFER4 buf_logon_hrs;
+ UNISTR2 uni_comment;
+ UNISTR2 uni_parameters;
+ SAM_PWD pass;
+ BUFFER4 buf_sec_desc;
+ UNISTR2 uni_profile;
+
+} SAM_ACCOUNT_INFO;
+
+/* SAM_GROUP_MEM_INFO (0x8) */
+typedef struct sam_group_mem_info_info
+{
+ uint32 ptr_rids;
+ uint32 ptr_attribs;
+ uint32 num_members;
+ uint8 unknown[16];
+
+ uint32 num_members2;
+ uint32 *rids;
+
+ uint32 num_members3;
+ uint32 *attribs;
+
+} SAM_GROUP_MEM_INFO;
+
+/* SAM_ALIAS_INFO (0x9) */
+typedef struct sam_alias_info_info
+{
+ UNIHDR hdr_als_name;
+ uint32 als_rid;
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ UNIHDR hdr_als_desc;
+ uint8 reserved[40];
+
+ UNISTR2 uni_als_name;
+ BUFFER4 buf_sec_desc;
+ UNISTR2 uni_als_desc;
+
+} SAM_ALIAS_INFO;
+
+/* SAM_ALIAS_MEM_INFO (0xC) */
+typedef struct sam_alias_mem_info_info
+{
+ uint32 num_members;
+ uint32 ptr_members;
+ uint8 unknown[16];
+
+ uint32 num_sids;
+ uint32 *ptr_sids;
+ DOM_SID2 *sids;
+
+} SAM_ALIAS_MEM_INFO;
+
+/* SAM_DELTA_STAMP (0x16) */
+typedef struct
+{
+ uint32 seqnum;
+ uint32 dom_mod_count_ptr;
+ UINT64_S dom_mod_count; /* domain mod count at last sync */
+} SAM_DELTA_STAMP;
+
+typedef union sam_delta_ctr_info
+{
+ SAM_DOMAIN_INFO domain_info ;
+ SAM_GROUP_INFO group_info ;
+ SAM_ACCOUNT_INFO account_info;
+ SAM_GROUP_MEM_INFO grp_mem_info;
+ SAM_ALIAS_INFO alias_info ;
+ SAM_ALIAS_MEM_INFO als_mem_info;
+ SAM_DELTA_STAMP stamp;
+} SAM_DELTA_CTR;
+
+/* NET_R_SAM_SYNC */
+typedef struct net_r_sam_sync_info
+{
+ DOM_CRED srv_creds;
+
+ uint32 sync_context;
+
+ uint32 ptr_deltas;
+ uint32 num_deltas;
+ uint32 ptr_deltas2;
+ uint32 num_deltas2;
+
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+
+ NTSTATUS status;
+} NET_R_SAM_SYNC;
+
+/* NET_Q_SAM_DELTAS */
+typedef struct net_q_sam_deltas_info
+{
+ UNISTR2 uni_srv_name;
+ UNISTR2 uni_cli_name;
+ DOM_CRED cli_creds;
+ DOM_CRED ret_creds;
+
+ uint32 database_id;
+ UINT64_S dom_mod_count; /* domain mod count at last sync */
+
+ uint32 max_size; /* preferred maximum length */
+
+} NET_Q_SAM_DELTAS;
+
+/* NET_R_SAM_DELTAS */
+typedef struct net_r_sam_deltas_info
+{
+ DOM_CRED srv_creds;
+
+ UINT64_S dom_mod_count; /* new domain mod count */
+
+ uint32 ptr_deltas;
+ uint32 num_deltas;
+ uint32 num_deltas2;
+
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+
+ NTSTATUS status;
+} NET_R_SAM_DELTAS;
+
#endif /* _RPC_NETLOGON_H */
diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h
index 103a7492cd0..8fe40be6f7f 100644
--- a/source/include/rpc_reg.h
+++ b/source/include/rpc_reg.h
@@ -26,47 +26,86 @@
/* winreg pipe defines */
-#define REG_OPEN_HKLM 0x02
-#define REG_OPEN_HKU 0x04
-#define REG_FLUSH_KEY 0x0B
-#define REG_UNK_1A 0x1a
-#define REG_QUERY_KEY 0x10
-#define REG_ENUM_KEY 0x09
-#define REG_CREATE_KEY 0x06
-#define REG_DELETE_KEY 0x07
-#define REG_DELETE_VALUE 0x08
-#define REG_CREATE_VALUE 0x16
-#define REG_GET_KEY_SEC 0x0c
-#define REG_SET_KEY_SEC 0x15
-#define REG_ENUM_VALUE 0x0a
-#define REG_OPEN_ENTRY 0x0f
-#define REG_INFO 0x11
-#define REG_CLOSE 0x05
-
-#define HKEY_LOCAL_MACHINE 0x80000000
-#define HKEY_USERS 0x80000003
-
-/* REG_Q_OPEN_HKLM */
-typedef struct q_reg_open_policy_info
+#define REG_OPEN_HKCR 0x00
+#define _REG_UNK_01 0x01
+#define REG_OPEN_HKLM 0x02
+#define _REG_UNK_03 0x03
+#define REG_OPEN_HKU 0x04
+#define REG_CLOSE 0x05
+#define REG_CREATE_KEY 0x06
+#define REG_DELETE_KEY 0x07
+#define REG_DELETE_VALUE 0x08
+#define REG_ENUM_KEY 0x09
+#define REG_ENUM_VALUE 0x0a
+#define REG_FLUSH_KEY 0x0b
+#define REG_GET_KEY_SEC 0x0c
+#define _REG_UNK_0D 0x0d
+#define _REG_UNK_0E 0x0e
+#define REG_OPEN_ENTRY 0x0f
+#define REG_QUERY_KEY 0x10
+#define REG_INFO 0x11
+#define _REG_UNK_12 0x12
+#define _REG_UNK_13 0x13
+#define _REG_UNK_14 0x14
+#define REG_SET_KEY_SEC 0x15
+#define REG_CREATE_VALUE 0x16
+#define _REG_UNK_17 0x17
+#define REG_SHUTDOWN 0x18
+#define REG_ABORT_SHUTDOWN 0x19
+#define REG_UNK_1A 0x1a
+
+#define HKEY_CLASSES_ROOT 0x80000000
+#define HKEY_CURRENT_USER 0x80000001
+#define HKEY_LOCAL_MACHINE 0x80000002
+#define HKEY_USERS 0x80000003
+
+#define REG_SZ 1
+#define REG_BINARY 3
+#define REG_DWORD 4
+#define REG_MULTI_SZ 7
+
+/* REG_Q_OPEN_HKCR */
+typedef struct q_reg_open_hkcr_info
{
uint32 ptr;
- uint16 unknown_0; /* 0xE084 - 16 bit unknown */
+ uint16 unknown_0; /* 0x5428 - 16 bit unknown */
uint16 unknown_1; /* random. changes */
uint32 level; /* 0x0000 0002 - 32 bit unknown */
-} REG_Q_OPEN_HKLM ;
+} REG_Q_OPEN_HKCR ;
-/* REG_R_OPEN_HKLM */
-typedef struct r_reg_open_policy_info
+/* REG_R_OPEN_HKCR */
+typedef struct r_reg_open_hkcr_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
-} REG_R_OPEN_HKLM;
+} REG_R_OPEN_HKCR;
+
+
+/* REG_Q_OPEN_HKLM */
+typedef struct q_reg_open_hklm_info
+{
+ uint32 ptr;
+ uint16 unknown_0; /* 0xE084 - 16 bit unknown */
+ uint16 unknown_1; /* random. changes */
+ uint32 access_mask; /* 0x0000 0002 - 32 bit unknown */
+
+}
+REG_Q_OPEN_HKLM;
+
+/* REG_R_OPEN_HKLM */
+typedef struct r_reg_open_hklm_info
+{
+ POLICY_HND pol; /* policy handle */
+ NTSTATUS status; /* return status */
+
+}
+REG_R_OPEN_HKLM;
/* REG_Q_OPEN_HKU */
-typedef struct q_reg_open_unk4_info
+typedef struct q_reg_open_hku_info
{
uint32 ptr;
uint16 unknown_0; /* 0xE084 - 16 bit unknown */
@@ -76,10 +115,10 @@ typedef struct q_reg_open_unk4_info
} REG_Q_OPEN_HKU;
/* REG_R_OPEN_HKU */
-typedef struct r_reg_open_unk4_info
+typedef struct r_reg_open_hku_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_OPEN_HKU;
@@ -94,7 +133,7 @@ typedef struct q_reg_open_flush_key_info
/* REG_R_FLUSH_KEY */
typedef struct r_reg_open_flush_key_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_FLUSH_KEY;
@@ -115,7 +154,7 @@ typedef struct q_reg_set_key_sec_info
/* REG_R_SET_KEY_SEC */
typedef struct r_reg_set_key_sec_info
{
- uint32 status;
+ NTSTATUS status;
} REG_R_SET_KEY_SEC;
@@ -142,7 +181,7 @@ typedef struct r_reg_get_key_sec_info
BUFHDR hdr_sec; /* header for security data */
SEC_DESC_BUF *data; /* security data */
- uint32 status;
+ NTSTATUS status;
} REG_R_GET_KEY_SEC;
@@ -163,7 +202,7 @@ typedef struct q_reg_create_value_info
/* REG_R_CREATE_VALUE */
typedef struct r_reg_create_value_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_CREATE_VALUE;
@@ -209,7 +248,7 @@ typedef struct r_reg_enum_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_ENUM_VALUE;
@@ -245,7 +284,7 @@ typedef struct r_reg_create_key_info
POLICY_HND key_pol; /* policy handle */
uint32 unknown; /* 0x0000 0000 */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_CREATE_KEY;
@@ -263,7 +302,7 @@ typedef struct r_reg_delete_key_info
{
POLICY_HND key_pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_DELETE_KEY;
@@ -282,7 +321,7 @@ typedef struct r_reg_delete_val_info
{
POLICY_HND key_pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_DELETE_VALUE;
@@ -310,7 +349,7 @@ typedef struct r_reg_query_key_info
uint32 sec_desc; /* 0x0000 0078 */
NTTIME mod_time; /* modified time */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_QUERY_KEY;
@@ -326,7 +365,7 @@ typedef struct q_reg_unk_1a_info
typedef struct r_reg_unk_1a_info
{
uint32 unknown; /* 0x0500 0000 */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_UNK_1A;
@@ -343,7 +382,7 @@ typedef struct reg_r_close_info
{
POLICY_HND pol; /* policy handle. should be all zeros. */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} REG_R_CLOSE;
@@ -388,7 +427,7 @@ typedef struct r_reg_enum_key_info
uint32 ptr3; /* pointer */
NTTIME time; /* current time? */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_ENUM_KEY;
@@ -396,43 +435,43 @@ typedef struct r_reg_enum_key_info
/* REG_Q_INFO */
typedef struct q_reg_info_info
{
- POLICY_HND pol; /* policy handle */
+ POLICY_HND pol; /* policy handle */
- UNIHDR hdr_type; /* unicode product type header */
- UNISTR2 uni_type; /* unicode product type - "ProductType" */
+ UNIHDR hdr_type; /* unicode product type header */
+ UNISTR2 uni_type; /* unicode product type - "ProductType" */
- uint32 ptr_reserved;
+ uint32 ptr_reserved; /* pointer */
- uint32 ptr_buf; /* the next three fields follow if ptr_buf != 0 */
- uint32 ptr_bufsize;
- uint32 bufsize;
- uint32 buf_unk;
-
- uint32 unk1;
- uint32 ptr_buflen;
- uint32 buflen;
+ uint32 ptr_buf; /* the next three fields follow if ptr_buf != 0 */
+ uint32 ptr_bufsize;
+ uint32 bufsize;
+ uint32 buf_unk;
+
+ uint32 unk1;
+ uint32 ptr_buflen;
+ uint32 buflen;
- uint32 ptr_buflen2;
- uint32 buflen2;
+ uint32 ptr_buflen2;
+ uint32 buflen2;
} REG_Q_INFO;
/* REG_R_INFO */
typedef struct r_reg_info_info
{
- uint32 ptr_type; /* keyvalue pointer */
- uint32 type; /* keyvalue datatype */
-
- uint32 ptr_uni_val; /* pointer to o/s type */
- BUFFER2 *uni_val; /* unicode string o/s type - "LanmanNT" */
+ uint32 ptr_type; /* key type pointer */
+ uint32 type; /* key datatype */
- uint32 ptr_max_len; /* pointer to unknown_0 */
- uint32 buf_max_len; /* 0x12 */
+ uint32 ptr_uni_val; /* key value pointer */
+ BUFFER2 *uni_val; /* key value */
- uint32 ptr_len; /* pointer to unknown_1 */
- uint32 buf_len; /* 0x12 */
+ uint32 ptr_max_len;
+ uint32 buf_max_len;
- uint32 status; /* return status */
+ uint32 ptr_len;
+ uint32 buf_len;
+
+ NTSTATUS status; /* return status */
} REG_R_INFO;
@@ -456,10 +495,44 @@ typedef struct q_reg_open_entry_info
typedef struct r_reg_open_entry_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} REG_R_OPEN_ENTRY;
+/* REG_Q_SHUTDOWN */
+typedef struct q_reg_shutdown_info
+{
+ uint32 ptr_0;
+ uint32 ptr_1;
+ uint32 ptr_2;
+ UNIHDR hdr_msg; /* shutdown message */
+ UNISTR2 uni_msg; /* seconds */
+ uint32 timeout; /* seconds */
+ uint16 flags;
+
+} REG_Q_SHUTDOWN;
+
+/* REG_R_SHUTDOWN */
+typedef struct r_reg_shutdown_info
+{
+ NTSTATUS status; /* return status */
+
+} REG_R_SHUTDOWN;
+
+/* REG_Q_ABORT_SHUTDOWN */
+typedef struct q_reg_abort_shutdown_info
+{
+ uint32 ptr_server;
+ uint16 server;
+
+} REG_Q_ABORT_SHUTDOWN;
+
+/* REG_R_ABORT_SHUTDOWN */
+typedef struct r_reg_abort_shutdown_info
+{
+ NTSTATUS status; /* return status */
+
+} REG_R_ABORT_SHUTDOWN;
#endif /* _RPC_REG_H */
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index c3bd20921dd..59325ca88d4 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -5,6 +5,7 @@
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Paul Ashton 1997-2000
+ Copyright (C) Jean François Micouleau 1998-2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -87,6 +88,7 @@ SamrTestPrivateFunctionsUser
#define SAMR_ENUM_DOMAINS 0x06
#define SAMR_OPEN_DOMAIN 0x07
#define SAMR_QUERY_DOMAIN_INFO 0x08
+#define SAMR_SET_DOMAIN_INFO 0x09
#define SAMR_CREATE_DOM_GROUP 0x0a
#define SAMR_ENUM_DOM_GROUPS 0x0b
@@ -127,7 +129,7 @@ SamrTestPrivateFunctionsUser
#define SAMR_UNKNOWN_2b 0x2b
#define SAMR_GET_USRDOM_PWINFO 0x2c
#define SAMR_UNKNOWN_2D 0x2d
-#define SAMR_UNKNOWN_2e 0x2e
+#define SAMR_UNKNOWN_2E 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */
#define SAMR_UNKNOWN_2f 0x2f
#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO
with info level 3 */
@@ -145,6 +147,14 @@ SamrTestPrivateFunctionsUser
#define SAMR_SET_USERINFO 0x3A
+typedef struct _DISP_USER_INFO {
+ SAM_ACCOUNT *sam;
+} DISP_USER_INFO;
+
+typedef struct _DISP_GROUP_INFO {
+ DOMAIN_GRP *grp;
+} DISP_GROUP_INFO;
+
typedef struct logon_hours_info
{
@@ -331,6 +341,15 @@ typedef struct sam_user_info_21
} SAM_USER_INFO_21;
+/* SAM_USER_INFO_20 */
+typedef struct sam_user_info_20
+{
+ UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
+
+ UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel number */
+
+} SAM_USER_INFO_20;
+
/* SAM_USER_INFO_12 */
typedef struct sam_user_info_12
{
@@ -402,7 +421,7 @@ typedef struct q_samr_close_hnd_info
typedef struct r_samr_close_hnd_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_CLOSE_HND;
@@ -429,7 +448,7 @@ typedef struct r_samr_usrdom_pwinfo_info
uint16 unknown_0; /* 0000 */
uint16 unknown_1; /* 0x0016 or 0x0015 */
uint32 unknown_2; /* 0x0000 0000 */
- uint32 status;
+ NTSTATUS status;
} SAMR_R_GET_USRDOM_PWINFO;
@@ -452,7 +471,7 @@ typedef struct r_samr_query_sec_obj_info
uint32 ptr;
SEC_DESC_BUF *buf;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_QUERY_SEC_OBJ;
@@ -471,8 +490,10 @@ typedef struct q_samr_query_domain_info
typedef struct sam_unknown_info_3_info
{
- uint32 unknown_0; /* 0x0000 0000 */
- uint32 unknown_1; /* 0x8000 0000 */
+ NTTIME logout;
+ /* 0x8000 0000 */ /* DON'T forcibly disconnect remote users from server when logon hours expire*/
+
+ /* 0x0000 0000 */ /* forcibly disconnect remote users from server when logon hours expire*/
} SAM_UNK_INFO_3;
@@ -493,15 +514,19 @@ typedef struct sam_unknown_info_7_info
typedef struct sam_unknown_info_12_inf
{
- uint32 unknown_0; /* 0xcf1d cc00 */
- uint32 unknown_1; /* 0xffff fffb */
- uint32 unknown_2; /* 0xcf1d cc00 */
- uint32 unknown_3; /* 0xffff fffb */
-
- uint32 unknown_4; /* 0x8a88 0000 */
+ NTTIME duration;
+ NTTIME reset_count;
+ uint16 bad_attempt_lockout;
} SAM_UNK_INFO_12;
+typedef struct sam_unknown_info_5_inf
+{
+ UNIHDR hdr_server; /* server name unicode header */
+ UNISTR2 uni_server; /* server name unicode string */
+
+} SAM_UNK_INFO_5;
+
typedef struct sam_unknown_info_2_inf
{
uint32 unknown_0; /* 0x0000 0000 */
@@ -535,9 +560,11 @@ typedef struct sam_unknown_info_2_inf
typedef struct sam_unknown_info_1_inf
{
- uint8 padding[12]; /* 12 bytes zeros */
- uint32 unknown_1; /* 0x8000 0000 */
- uint32 unknown_2; /* 0x0000 0000 */
+ uint16 min_length_password;
+ uint16 password_history;
+ uint32 flag;
+ NTTIME expire;
+ NTTIME min_passwordage;
} SAM_UNK_INFO_1;
@@ -549,6 +576,7 @@ typedef struct sam_unknown_ctr_info
SAM_UNK_INFO_1 inf1;
SAM_UNK_INFO_2 inf2;
SAM_UNK_INFO_3 inf3;
+ SAM_UNK_INFO_5 inf5;
SAM_UNK_INFO_6 inf6;
SAM_UNK_INFO_7 inf7;
SAM_UNK_INFO_12 inf12;
@@ -566,7 +594,7 @@ typedef struct r_samr_query_domain_info
SAM_UNK_CTR *ctr;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_QUERY_DOMAIN_INFO;
@@ -588,7 +616,7 @@ typedef struct r_samr_lookup_domain_info
uint32 ptr_sid;
DOM_SID2 dom_sid;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_LOOKUP_DOMAIN;
@@ -614,11 +642,14 @@ typedef struct q_samr_open_domain_info
typedef struct r_samr_open_domain_info
{
POLICY_HND domain_pol; /* policy handle associated with the SID */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_OPEN_DOMAIN;
-#define MAX_SAM_ENTRIES 50
+#define MAX_SAM_ENTRIES_W2K 0x400
+#define MAX_SAM_ENTRIES_W95 50
+/* The following should be the greater of the preceeding two. */
+#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K
typedef struct samr_entry_info
{
@@ -654,7 +685,7 @@ typedef struct r_samr_enum_domains_info
uint32 num_entries4;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_ENUM_DOMAINS;
@@ -688,7 +719,7 @@ typedef struct r_samr_enum_dom_users_info
uint32 num_entries4;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_ENUM_DOM_USERS;
@@ -722,7 +753,7 @@ typedef struct r_samr_enum_dom_groups_info
uint32 num_entries4;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_ENUM_DOM_GROUPS;
@@ -756,7 +787,7 @@ typedef struct r_samr_enum_dom_aliases_info
uint32 num_entries4;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_ENUM_DOM_ALIASES;
@@ -769,7 +800,6 @@ typedef struct samr_entry_info1
uint32 rid_user;
uint16 acb_info;
- uint16 pad;
UNIHDR hdr_acct_name;
UNIHDR hdr_user_name;
@@ -801,7 +831,6 @@ typedef struct samr_entry_info2
uint32 rid_user;
uint16 acb_info;
- uint16 pad;
UNIHDR hdr_srv_name;
UNIHDR hdr_srv_desc;
@@ -947,7 +976,7 @@ typedef struct r_samr_query_dispinfo_info
SAM_DISPINFO_CTR *ctr;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_QUERY_DISPINFO;
@@ -964,7 +993,7 @@ typedef struct q_samr_delete_dom_group_info
typedef struct r_samr_delete_dom_group_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_DELETE_DOM_GROUP;
@@ -987,7 +1016,7 @@ typedef struct r_samr_create_dom_group_info
POLICY_HND pol; /* policy handle */
uint32 rid;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_CREATE_DOM_GROUP;
@@ -1014,6 +1043,12 @@ typedef struct samr_group_info1
} GROUP_INFO1;
+typedef struct samr_group_info3
+{
+ uint32 unknown_1; /* 0x0000 0003 - number of group members? */
+
+} GROUP_INFO3;
+
typedef struct samr_group_info4
{
UNIHDR hdr_acct_desc;
@@ -1025,12 +1060,12 @@ typedef struct samr_group_info4
typedef struct group_info_ctr
{
uint16 switch_value1;
- uint16 switch_value2;
union
{
- GROUP_INFO4 info4;
GROUP_INFO1 info1;
+ GROUP_INFO3 info3;
+ GROUP_INFO4 info4;
} group;
@@ -1042,7 +1077,7 @@ typedef struct r_samr_query_groupinfo_info
uint32 ptr;
GROUP_INFO_CTR *ctr;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_QUERY_GROUPINFO;
@@ -1058,7 +1093,7 @@ typedef struct q_samr_set_group_info
/* SAMR_R_SET_GROUPINFO - SAM Group Info */
typedef struct r_samr_set_group_info
{
- uint32 status;
+ NTSTATUS status;
} SAMR_R_SET_GROUPINFO;
@@ -1075,7 +1110,7 @@ typedef struct q_samr_delete_dom_alias_info
typedef struct r_samr_delete_dom_alias_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_DELETE_DOM_ALIAS;
@@ -1098,7 +1133,7 @@ typedef struct r_samr_create_dom_alias_info
POLICY_HND alias_pol; /* policy handle */
uint32 rid;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_CREATE_DOM_ALIAS;
@@ -1111,6 +1146,16 @@ typedef struct q_samr_query_alias_info
} SAMR_Q_QUERY_ALIASINFO;
+typedef struct samr_alias_info1
+{
+ UNIHDR hdr_acct_name;
+ UNIHDR hdr_acct_desc;
+ uint32 num_member;
+ UNISTR2 uni_acct_name;
+ UNISTR2 uni_acct_desc;
+
+} ALIAS_INFO1;
+
typedef struct samr_alias_info3
{
UNIHDR hdr_acct_desc;
@@ -1126,6 +1171,7 @@ typedef struct alias_info_ctr
union
{
+ ALIAS_INFO1 info1;
ALIAS_INFO3 info3;
} alias;
@@ -1138,7 +1184,7 @@ typedef struct r_samr_query_aliasinfo_info
uint32 ptr;
ALIAS_INFO_CTR ctr;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_QUERY_ALIASINFO;
@@ -1154,7 +1200,7 @@ typedef struct q_samr_set_alias_info
/* SAMR_R_SET_ALIASINFO - SAM alias info */
typedef struct r_samr_set_aliasinfo_info
{
- uint32 status;
+ NTSTATUS status;
} SAMR_R_SET_ALIASINFO;
@@ -1176,7 +1222,7 @@ typedef struct r_samr_query_usergroup_info
DOM_GID *gid; /* group info */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_QUERY_USERGROUPS;
@@ -1190,6 +1236,7 @@ typedef struct sam_userinfo_ctr_info
SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
SAM_USER_INFO_12 *id12; /* auth-level 0x12 */
+ SAM_USER_INFO_20 *id20; /* auth-level 20 */
SAM_USER_INFO_21 *id21; /* auth-level 21 */
SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
@@ -1214,7 +1261,7 @@ typedef struct q_samr_set_user_info2
/* SAMR_R_SET_USERINFO2 - set sam info */
typedef struct r_samr_set_user_info2
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_SET_USERINFO2;
@@ -1230,7 +1277,7 @@ typedef struct q_samr_set_user_info
/* SAMR_R_SET_USERINFO - set sam info */
typedef struct r_samr_set_user_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_SET_USERINFO;
@@ -1249,7 +1296,7 @@ typedef struct r_samr_query_user_info
uint32 ptr; /* pointer */
SAM_USERINFO_CTR *ctr;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_QUERY_USERINFO;
@@ -1285,7 +1332,7 @@ typedef struct r_samr_query_useraliases_info
uint32 num_entries2;
uint32 *rid; /* domain RIDs being looked up */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} SAMR_R_QUERY_USERALIASES;
@@ -1324,7 +1371,7 @@ typedef struct r_samr_lookup_names_info
uint32 *types; /* SID_ENUM type */
- uint32 status; /* return code */
+ NTSTATUS status; /* return code */
} SAMR_R_LOOKUP_NAMES;
@@ -1369,7 +1416,7 @@ typedef struct r_samr_lookup_rids_info
uint32 *type; /* SID_ENUM type */
- uint32 status;
+ NTSTATUS status;
} SAMR_R_LOOKUP_RIDS;
@@ -1388,7 +1435,7 @@ typedef struct q_samr_open_user_info
typedef struct r_samr_open_user_info
{
POLICY_HND user_pol; /* policy handle associated with unknown id */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_OPEN_USER;
@@ -1414,7 +1461,7 @@ typedef struct r_samr_create_user_info
uint32 unknown_0; /* 0x0007 03ff */
uint32 user_rid; /* user RID */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_CREATE_USER;
@@ -1431,7 +1478,7 @@ typedef struct q_samr_delete_dom_user_info
typedef struct r_samr_delete_dom_user_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_DELETE_DOM_USER;
@@ -1459,7 +1506,7 @@ typedef struct r_samr_query_groupmem_info
uint32 num_attrs;
uint32 *attr;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_QUERY_GROUPMEM;
@@ -1468,7 +1515,6 @@ typedef struct r_samr_query_groupmem_info
typedef struct q_samr_del_group_mem_info
{
POLICY_HND pol; /* policy handle */
-
uint32 rid; /* rid */
} SAMR_Q_DEL_GROUPMEM;
@@ -1477,7 +1523,7 @@ typedef struct q_samr_del_group_mem_info
/* SAMR_R_DEL_GROUPMEM - probably an del group member */
typedef struct r_samr_del_group_mem_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_DEL_GROUPMEM;
@@ -1496,7 +1542,7 @@ typedef struct q_samr_add_group_mem_info
/* SAMR_R_ADD_GROUPMEM - probably an add group member */
typedef struct r_samr_add_group_mem_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_ADD_GROUPMEM;
@@ -1515,7 +1561,7 @@ typedef struct q_samr_open_group_info
typedef struct r_samr_open_group_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_OPEN_GROUP;
@@ -1537,7 +1583,7 @@ typedef struct r_samr_query_aliasmem_info
DOM_SID2 *sid;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_QUERY_ALIASMEM;
@@ -1555,7 +1601,7 @@ typedef struct q_samr_add_alias_mem_info
/* SAMR_R_ADD_ALIASMEM - add alias member */
typedef struct r_samr_add_alias_mem_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_ADD_ALIASMEM;
@@ -1573,7 +1619,7 @@ typedef struct q_samr_del_alias_mem_info
/* SAMR_R_DEL_ALIASMEM - delete alias member */
typedef struct r_samr_del_alias_mem_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_DEL_ALIASMEM;
@@ -1594,7 +1640,7 @@ typedef struct q_samr_open_alias_info
typedef struct r_samr_open_alias_info
{
POLICY_HND pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_OPEN_ALIAS;
@@ -1613,7 +1659,7 @@ typedef struct q_samr_connect_anon_info
typedef struct r_samr_connect_anon_info
{
POLICY_HND connect_pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_CONNECT_ANON;
@@ -1632,7 +1678,7 @@ typedef struct q_samr_connect_info
typedef struct r_samr_connect_info
{
POLICY_HND connect_pol; /* policy handle */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_CONNECT;
@@ -1651,7 +1697,7 @@ typedef struct r_samr_get_dom_pwinfo
uint16 unk_0;
uint16 unk_1;
uint16 unk_2;
- uint32 status;
+ NTSTATUS status;
} SAMR_R_GET_DOM_PWINFO;
@@ -1695,7 +1741,7 @@ typedef struct q_samr_chgpasswd_user_info
/* SAMR_R_CHGPASSWD_USER */
typedef struct r_samr_chgpasswd_user_info
{
- uint32 status; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+ NTSTATUS status; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
} SAMR_R_CHGPASSWD_USER;
@@ -1712,7 +1758,7 @@ typedef struct q_samr_unknown_2d_info
/* SAMR_R_UNKNOWN_2D - probably an open */
typedef struct r_samr_unknown_2d_info
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SAMR_R_UNKNOWN_2D;
@@ -1732,5 +1778,41 @@ typedef struct sid_info_3
} DOM_SID3;
+/* SAMR_Q_UNKNOWN_2E */
+typedef struct q_samr_unknown_2e_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint16 switch_value;
+
+} SAMR_Q_UNKNOWN_2E;
+
+/* SAMR_R_UNKNOWN_2E */
+typedef struct r_samr_unknown_2e_info
+{
+ uint32 ptr_0;
+ uint16 switch_value;
+ SAM_UNK_CTR *ctr;
+ NTSTATUS status; /* return status */
+
+} SAMR_R_UNKNOWN_2E;
+
+/* SAMR_Q_SET_DOMAIN_INFO */
+typedef struct q_samr_set_domain_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint16 switch_value0;
+ uint16 switch_value;
+ SAM_UNK_CTR *ctr;
+
+} SAMR_Q_SET_DOMAIN_INFO;
+
+/* SAMR_R_SET_DOMAIN_INFO */
+typedef struct r_samr_set_domain_info
+{
+ NTSTATUS status; /* return status */
+
+} SAMR_R_SET_DOMAIN_INFO;
+
+
#endif /* _RPC_SAMR_H */
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index 5d8a1895a6e..259c1567675 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -95,7 +95,7 @@ typedef struct security_ace_info
uint16 size;
SEC_ACCESS info;
- DOM_SID sid;
+ DOM_SID trustee;
} SEC_ACE;
#define _SEC_ACE
diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h
index dd66982cd5c..9ed83b18d8a 100755
--- a/source/include/rpc_spoolss.h
+++ b/source/include/rpc_spoolss.h
@@ -30,7 +30,6 @@
/* spoolss pipe: this are the calls which are not implemented ...
#define SPOOLSS_OPENPRINTER 0x01
#define SPOOLSS_GETPRINTERDRIVER 0x0b
-#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10
#define SPOOLSS_READPRINTER 0x16
#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c
#define SPOOLSS_ADDPORT 0x25
@@ -57,7 +56,9 @@
#define SPOOLSS_SPOOLERINIT 0x3f
#define SPOOLSS_RESETPRINTEREX 0x40
#define SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION 0x42
-#define SPOOLSS_GETPRINTERDATAEX 0x4e
+#define SPOOLSS_DELETEPRINTERDATAEX 0x51
+#define SPOOLSS_DELETEPRINTERDRIVEREX 0x54
+#define SPOOLSS_ADDPRINTERDRIVEREX 0x59
*/
/* those are implemented */
@@ -75,6 +76,7 @@
#define SPOOLSS_DELETEPRINTERDRIVER 0x0d
#define SPOOLSS_ADDPRINTPROCESSOR 0x0e
#define SPOOLSS_ENUMPRINTPROCESSORS 0x0f
+#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10
#define SPOOLSS_STARTDOCPRINTER 0x11
#define SPOOLSS_STARTPAGEPRINTER 0x12
#define SPOOLSS_WRITEPRINTER 0x13
@@ -109,6 +111,11 @@
#define SPOOLSS_ADDPRINTEREX 0x46
#define SPOOLSS_ENUMPRINTERDATA 0x48
#define SPOOLSS_DELETEPRINTERDATA 0x49
+#define SPOOLSS_SETPRINTERDATAEX 0x4d
+#define SPOOLSS_GETPRINTERDATAEX 0x4e
+#define SPOOLSS_ENUMPRINTERDATAEX 0x4f
+#define SPOOLSS_ENUMPRINTERKEY 0x50
+
#define PRINTER_CONTROL_UNPAUSE 0x00000000
#define PRINTER_CONTROL_PAUSE 0x00000001
@@ -193,9 +200,9 @@
#define JOB_WRITE STANDARD_RIGHTS_WRITE_ACCESS|JOB_ACCESS_ADMINISTER
#define JOB_EXECUTE STANDARD_RIGHTS_EXECUTE_ACCESS|JOB_ACCESS_ADMINISTER
-#define ONE_VALUE 01
-#define TWO_VALUE 02
-#define POINTER 03
+#define ONE_VALUE 1
+#define TWO_VALUE 2
+#define POINTER 3
#define PRINTER_NOTIFY_TYPE 0x00
#define JOB_NOTIFY_TYPE 0x01
@@ -460,8 +467,7 @@ SPOOL_Q_OPEN_PRINTER_EX;
typedef struct spool_r_open_printer_ex
{
POLICY_HND handle; /* handle used along all transactions (20*uint8) */
- uint32 status;
-
+ WERROR status;
}
SPOOL_R_OPEN_PRINTER_EX;
@@ -523,7 +529,7 @@ typedef struct spool_r_getprinterdata
uint32 size;
uint8 *data;
uint32 needed;
- uint32 status;
+ WERROR status;
}
SPOOL_R_GETPRINTERDATA;
@@ -536,7 +542,7 @@ SPOOL_Q_DELETEPRINTERDATA;
typedef struct spool_r_deleteprinterdata
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_DELETEPRINTERDATA;
@@ -549,7 +555,7 @@ SPOOL_Q_CLOSEPRINTER;
typedef struct spool_r_closeprinter
{
POLICY_HND handle;
- uint32 status;
+ WERROR status;
}
SPOOL_R_CLOSEPRINTER;
@@ -561,7 +567,7 @@ SPOOL_Q_STARTPAGEPRINTER;
typedef struct spool_r_startpageprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_STARTPAGEPRINTER;
@@ -573,7 +579,7 @@ SPOOL_Q_ENDPAGEPRINTER;
typedef struct spool_r_endpageprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENDPAGEPRINTER;
@@ -589,7 +595,7 @@ SPOOL_Q_DELETEPRINTERDRIVER;
typedef struct spool_r_deleteprinterdriver
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_DELETEPRINTERDRIVER;
@@ -629,7 +635,7 @@ SPOOL_Q_STARTDOCPRINTER;
typedef struct spool_r_startdocprinter
{
uint32 jobid;
- uint32 status;
+ WERROR status;
}
SPOOL_R_STARTDOCPRINTER;
@@ -641,7 +647,7 @@ SPOOL_Q_ENDDOCPRINTER;
typedef struct spool_r_enddocprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENDDOCPRINTER;
@@ -657,7 +663,7 @@ SPOOL_Q_WRITEPRINTER;
typedef struct spool_r_writeprinter
{
uint32 buffer_written;
- uint32 status;
+ WERROR status;
}
SPOOL_R_WRITEPRINTER;
@@ -718,7 +724,7 @@ SPOOL_Q_RFFPCNEX;
typedef struct spool_r_rffpcnex
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_RFFPCNEX;
@@ -736,7 +742,7 @@ typedef struct spool_r_rfnpcnex
{
uint32 info_ptr;
SPOOL_NOTIFY_INFO info;
- uint32 status;
+ WERROR status;
}
SPOOL_R_RFNPCNEX;
@@ -749,7 +755,7 @@ SPOOL_Q_FCPN;
typedef struct spool_r_fcpn
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_FCPN;
@@ -845,6 +851,24 @@ typedef struct printer_info_3
}
PRINTER_INFO_3;
+typedef struct printer_info_4
+{
+ UNISTR printername;
+ UNISTR servername;
+ uint32 attributes;
+}
+PRINTER_INFO_4;
+
+typedef struct printer_info_5
+{
+ UNISTR printername;
+ UNISTR portname;
+ uint32 attributes;
+ uint32 device_not_selected_timeout;
+ uint32 transmission_retry_timeout;
+}
+PRINTER_INFO_5;
+
typedef struct spool_q_enumprinters
{
uint32 flags;
@@ -862,6 +886,8 @@ typedef struct printer_info_ctr_info
PRINTER_INFO_1 *printers_1;
PRINTER_INFO_2 *printers_2;
PRINTER_INFO_3 *printers_3;
+ PRINTER_INFO_4 *printers_4;
+ PRINTER_INFO_5 *printers_5;
}
PRINTER_INFO_CTR;
@@ -870,7 +896,7 @@ typedef struct spool_r_enumprinters
NEW_BUFFER *buffer;
uint32 needed; /* bytes needed */
uint32 returned; /* number of printers */
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTERS;
@@ -899,7 +925,7 @@ typedef struct spool_r_getprinter
{
NEW_BUFFER *buffer;
uint32 needed;
- uint32 status;
+ WERROR status;
} SPOOL_R_GETPRINTER;
typedef struct driver_info_1
@@ -984,7 +1010,7 @@ typedef struct spool_r_getprinterdriver2
uint32 needed;
uint32 servermajorversion;
uint32 serverminorversion;
- uint32 status;
+ WERROR status;
}
SPOOL_R_GETPRINTERDRIVER2;
@@ -1010,7 +1036,7 @@ typedef struct spool_r_addjob
{
NEW_BUFFER *buffer;
uint32 needed;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDJOB;
@@ -1106,7 +1132,7 @@ typedef struct spool_r_enumjobs
NEW_BUFFER *buffer;
uint32 needed;
uint32 returned;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMJOBS;
@@ -1119,7 +1145,7 @@ SPOOL_Q_SCHEDULEJOB;
typedef struct spool_r_schedulejob
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_SCHEDULEJOB;
@@ -1166,7 +1192,7 @@ typedef struct spool_r_enumports
NEW_BUFFER *buffer;
uint32 needed; /* bytes needed */
uint32 returned; /* number of printers */
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPORTS;
@@ -1201,7 +1227,7 @@ SPOOL_Q_SETJOB;
typedef struct spool_r_setjob
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_SETJOB;
@@ -1223,7 +1249,7 @@ typedef struct spool_r_enumprinterdrivers
NEW_BUFFER *buffer;
uint32 needed;
uint32 returned;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTERDRIVERS;
@@ -1254,7 +1280,7 @@ typedef struct spool_r_enumforms
NEW_BUFFER *buffer;
uint32 needed;
uint32 numofforms;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMFORMS;
@@ -1272,7 +1298,7 @@ typedef struct spool_r_getform
{
NEW_BUFFER *buffer;
uint32 needed;
- uint32 status;
+ WERROR status;
}
SPOOL_R_GETFORM;
@@ -1321,7 +1347,6 @@ typedef struct spool_printer_info_level_2
UNISTR2 printprocessor;
UNISTR2 datatype;
UNISTR2 parameters;
- SEC_DESC_BUF *secdesc;
}
SPOOL_PRINTER_INFO_LEVEL_2;
@@ -1454,7 +1479,7 @@ SPOOL_Q_SETPRINTER;
typedef struct spool_r_setprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_SETPRINTER;
@@ -1463,10 +1488,8 @@ typedef struct spool_q_addprinter
UNISTR2 server_name;
uint32 level;
SPOOL_PRINTER_INFO_LEVEL info;
- uint32 unk0;
- uint32 unk1;
- uint32 unk2;
- uint32 unk3;
+ DEVMODE_CTR devmode_ctr;
+ SEC_DESC_BUF *secdesc_ctr;
uint32 user_level;
SPOOL_USER_LEVEL user;
}
@@ -1474,7 +1497,7 @@ SPOOL_Q_ADDPRINTER;
typedef struct spool_r_addprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDPRINTER;
@@ -1487,7 +1510,7 @@ SPOOL_Q_DELETEPRINTER;
typedef struct spool_r_deleteprinter
{
POLICY_HND handle;
- uint32 status;
+ WERROR status;
}
SPOOL_R_DELETEPRINTER;
@@ -1499,7 +1522,7 @@ SPOOL_Q_ABORTPRINTER;
typedef struct spool_r_abortprinter
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ABORTPRINTER;
@@ -1510,10 +1533,8 @@ typedef struct spool_q_addprinterex
UNISTR2 server_name;
uint32 level;
SPOOL_PRINTER_INFO_LEVEL info;
- uint32 unk0;
- uint32 unk1;
- uint32 unk2;
- uint32 unk3;
+ DEVMODE_CTR devmode_ctr;
+ SEC_DESC_BUF *secdesc_ctr;
uint32 user_switch;
SPOOL_USER_CTR user_ctr;
}
@@ -1522,7 +1543,7 @@ SPOOL_Q_ADDPRINTEREX;
typedef struct spool_r_addprinterex
{
POLICY_HND handle;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDPRINTEREX;
@@ -1538,7 +1559,7 @@ SPOOL_Q_ADDPRINTERDRIVER;
typedef struct spool_r_addprinterdriver
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDPRINTERDRIVER;
@@ -1571,7 +1592,7 @@ typedef struct spool_r_getprinterdriverdirectory
{
NEW_BUFFER *buffer;
uint32 needed;
- uint32 status;
+ WERROR status;
}
SPOOL_R_GETPRINTERDRIVERDIR;
@@ -1587,7 +1608,7 @@ SPOOL_Q_ADDPRINTPROCESSOR;
typedef struct spool_r_addprintprocessor
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDPRINTPROCESSOR;
@@ -1615,7 +1636,7 @@ typedef struct spool_r_enumprintprocessors
NEW_BUFFER *buffer;
uint32 needed;
uint32 returned;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTPROCESSORS;
@@ -1642,7 +1663,7 @@ typedef struct spool_r_enumprintprocdatatypes
NEW_BUFFER *buffer;
uint32 needed;
uint32 returned;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTPROCDATATYPES;
@@ -1675,7 +1696,7 @@ typedef struct spool_r_enumprintmonitors
NEW_BUFFER *buffer;
uint32 needed;
uint32 returned;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTMONITORS;
@@ -1698,7 +1719,7 @@ typedef struct spool_r_enumprinterdata
uint32 datasize;
uint8 *data;
uint32 realdatasize;
- uint32 status;
+ WERROR status;
}
SPOOL_R_ENUMPRINTERDATA;
@@ -1716,7 +1737,7 @@ SPOOL_Q_SETPRINTERDATA;
typedef struct spool_r_setprinterdata
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_SETPRINTERDATA;
@@ -1745,7 +1766,7 @@ SPOOL_Q_ADDFORM;
typedef struct spool_r_addform
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_ADDFORM;
@@ -1761,7 +1782,7 @@ SPOOL_Q_SETFORM;
typedef struct spool_r_setform
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_SETFORM;
@@ -1774,7 +1795,7 @@ SPOOL_Q_DELETEFORM;
typedef struct spool_r_deleteform
{
- uint32 status;
+ WERROR status;
}
SPOOL_R_DELETEFORM;
@@ -1805,7 +1826,7 @@ typedef struct spool_r_getjob
{
NEW_BUFFER *buffer;
uint32 needed;
- uint32 status;
+ WERROR status;
}
SPOOL_R_GETJOB;
@@ -1822,7 +1843,7 @@ SPOOL_Q_REPLYOPENPRINTER;
typedef struct spool_r_replyopenprinter
{
POLICY_HND handle;
- uint32 status;
+ WERROR status;
}
SPOOL_R_REPLYOPENPRINTER;
@@ -1835,7 +1856,7 @@ SPOOL_Q_REPLYCLOSEPRINTER;
typedef struct spool_r_replycloseprinter
{
POLICY_HND handle;
- uint32 status;
+ WERROR status;
}
SPOOL_R_REPLYCLOSEPRINTER;
@@ -1854,11 +1875,127 @@ SPOOL_Q_REPLY_RRPCN;
typedef struct spool_r_rrpcn
{
uint32 unknown0;
- uint32 status;
+ WERROR status;
}
SPOOL_R_REPLY_RRPCN;
+typedef struct spool_q_getprinterdataex
+{
+ POLICY_HND handle;
+ UNISTR2 keyname;
+ UNISTR2 valuename;
+ uint32 size;
+}
+SPOOL_Q_GETPRINTERDATAEX;
+
+typedef struct spool_r_getprinterdataex
+{
+ uint32 type;
+ uint32 size;
+ uint8 *data;
+ uint32 needed;
+ WERROR status;
+}
+SPOOL_R_GETPRINTERDATAEX;
+
+typedef struct spool_q_setprinterdataex
+{
+ POLICY_HND handle;
+ UNISTR2 key;
+ UNISTR2 value;
+ uint32 type;
+ uint32 max_len;
+ uint8 *data;
+ uint32 real_len;
+ uint32 numeric_data;
+}
+SPOOL_Q_SETPRINTERDATAEX;
+
+typedef struct spool_r_setprinterdataex
+{
+ WERROR status;
+}
+SPOOL_R_SETPRINTERDATAEX;
+
+
+typedef struct spool_q_enumprinterkey
+{
+ POLICY_HND handle;
+ UNISTR2 key;
+ uint32 size;
+}
+SPOOL_Q_ENUMPRINTERKEY;
+
+typedef struct spool_r_enumprinterkey
+{
+ BUFFER5 keys;
+ uint32 needed; /* in bytes */
+ WERROR status;
+}
+SPOOL_R_ENUMPRINTERKEY;
+
+typedef struct printer_enum_values
+{
+ UNISTR valuename;
+ uint32 value_len;
+ uint32 type;
+ uint8 *data;
+ uint32 data_len;
+
+}
+PRINTER_ENUM_VALUES;
+
+typedef struct printer_enum_values_ctr
+{
+ uint32 size;
+ uint32 size_of_array;
+ PRINTER_ENUM_VALUES *values;
+}
+PRINTER_ENUM_VALUES_CTR;
+
+typedef struct spool_q_enumprinterdataex
+{
+ POLICY_HND handle;
+ UNISTR2 key;
+ uint32 size;
+}
+SPOOL_Q_ENUMPRINTERDATAEX;
+
+typedef struct spool_r_enumprinterdataex
+{
+ PRINTER_ENUM_VALUES_CTR ctr;
+ uint32 needed;
+ uint32 returned;
+ WERROR status;
+}
+SPOOL_R_ENUMPRINTERDATAEX;
+
+typedef struct printprocessor_directory_1
+{
+ UNISTR name;
+}
+PRINTPROCESSOR_DIRECTORY_1;
+
+typedef struct spool_q_getprintprocessordirectory
+{
+ UNISTR2 name;
+ UNISTR2 environment;
+ uint32 level;
+ NEW_BUFFER *buffer;
+ uint32 offered;
+}
+SPOOL_Q_GETPRINTPROCESSORDIRECTORY;
+
+typedef struct spool_r_getprintprocessordirectory
+{
+ NEW_BUFFER *buffer;
+ uint32 needed;
+ WERROR status;
+}
+SPOOL_R_GETPRINTPROCESSORDIRECTORY;
+
#define PRINTER_DRIVER_VERSION 2
#define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86"
#endif /* _RPC_SPOOLSS_H */
+
diff --git a/source/include/rpc_srvsvc.h b/source/include/rpc_srvsvc.h
index d6fe7617b25..651c0b97673 100644
--- a/source/include/rpc_srvsvc.h
+++ b/source/include/rpc_srvsvc.h
@@ -67,7 +67,7 @@ typedef struct net_srv_disk_enum {
uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_Q_NET_DISK_ENUM, SRV_R_NET_DISK_ENUM;
typedef struct net_name_validate {
@@ -76,7 +76,7 @@ typedef struct net_name_validate {
UNISTR2 uni_name; /*name to validate*/
uint32 type;
uint32 flags;
- uint32 status;
+ NTSTATUS status;
} SRV_Q_NET_NAME_VALIDATE, SRV_R_NET_NAME_VALIDATE;
/* SESS_INFO_0 (pointers to level 0 session info strings) */
@@ -185,7 +185,7 @@ typedef struct r_net_sess_enum_info
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SESS_ENUM;
@@ -288,7 +288,7 @@ typedef struct r_net_conn_enum_info
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_CONN_ENUM;
@@ -444,7 +444,7 @@ typedef struct r_net_share_enum_info
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SHARE_ENUM;
@@ -480,7 +480,7 @@ typedef struct srv_share_info {
typedef struct r_net_share_get_info_info
{
SRV_SHARE_INFO info;
- uint32 status;
+ NTSTATUS status;
} SRV_R_NET_SHARE_GET_INFO;
@@ -502,7 +502,7 @@ typedef struct r_net_share_set_info
{
uint32 switch_value; /* switch value */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SHARE_SET_INFO;
@@ -523,7 +523,7 @@ typedef struct r_net_share_add
{
uint32 switch_value; /* switch value */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SHARE_ADD;
@@ -539,7 +539,7 @@ typedef struct q_net_share_del
/* SRV_R_NET_SHARE_DEL */
typedef struct r_net_share_del
{
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SHARE_DEL;
@@ -622,7 +622,7 @@ typedef struct r_net_file_enum_info
uint32 total_entries; /* total number of files */
ENUM_HND enum_hnd;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_FILE_ENUM;
@@ -704,7 +704,7 @@ typedef struct r_net_srv_get_info
{
SRV_INFO_CTR *ctr;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SRV_GET_INFO;
@@ -725,7 +725,7 @@ typedef struct r_net_srv_set_info
{
uint32 switch_value; /* switch value */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_SRV_SET_INFO;
@@ -761,7 +761,7 @@ typedef struct r_net_remote_tod
uint32 ptr_srv_tod; /* pointer to TOD */
TIME_OF_DAY_INFO *tod;
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} SRV_R_NET_REMOTE_TOD;
@@ -786,7 +786,7 @@ typedef struct r_net_file_query_secdesc
uint32 ptr_secdesc;
uint32 size_secdesc;
SEC_DESC *sec_desc;
- uint32 status;
+ NTSTATUS status;
} SRV_R_NET_FILE_QUERY_SECDESC;
/* SRV_Q_NET_FILE_SET_SECDESC */
@@ -807,6 +807,6 @@ typedef struct q_net_file_set_secdesc
/* SRV_R_NET_FILE_SET_SECDESC */
typedef struct r_net_file_set_secdesc
{
- uint32 status;
+ NTSTATUS status;
} SRV_R_NET_FILE_SET_SECDESC;
#endif /* _RPC_SRVSVC_H */
diff --git a/source/include/rpc_wkssvc.h b/source/include/rpc_wkssvc.h
index 1483997acb3..57a70b4798e 100644
--- a/source/include/rpc_wkssvc.h
+++ b/source/include/rpc_wkssvc.h
@@ -64,7 +64,7 @@ typedef struct r_wks_query_info_info
uint32 ptr_1; /* pointer 1 */
WKS_INFO_100 *wks100; /* workstation info level 100 */
- uint32 status; /* return status */
+ NTSTATUS status; /* return status */
} WKS_R_QUERY_INFO;
diff --git a/source/include/smb.h b/source/include/smb.h
index ac76ff8f928..c701d460df1 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -108,7 +108,7 @@ implemented */
#define GET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
#define SET_OPEN_MODE(x) ((x) & OPEN_MODE_MASK)
#define GET_DENY_MODE(x) (((x)>>SHARE_MODE_SHIFT) & SHARE_MODE_MASK)
-#define SET_DENY_MODE(x) ((x)<<SHARE_MODE_SHIFT)
+#define SET_DENY_MODE(x) (((x) & SHARE_MODE_MASK) <<SHARE_MODE_SHIFT)
/* Sync on open file (not sure if used anymore... ?) */
#define FILE_SYNC_OPENMODE (1<<14)
@@ -199,6 +199,36 @@ typedef struct nttime_info
} NTTIME;
+/* 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 */
@@ -271,6 +301,9 @@ typedef struct sid_info
* token->user_sids[2-num_sids] = supplementary group SIDS.
*/
+#define PRIMARY_USER_SID_INDEX 0
+#define PRIMARY_GROUP_SID_INDEX 1
+
#ifndef _NT_USER_TOKEN
typedef struct _nt_user_token {
size_t num_sids;
@@ -369,6 +402,7 @@ typedef struct files_struct
time_t pending_modtime;
int oplock_type;
int sent_oplock_break;
+ unsigned long file_id;
BOOL can_lock;
BOOL can_read;
BOOL can_write;
@@ -518,13 +552,15 @@ struct interface
};
/* struct returned by get_share_modes */
-typedef struct
-{
- pid_t pid;
- uint16 op_port;
- uint16 op_type;
- int share_mode;
- struct timeval time;
+typedef struct {
+ pid_t pid;
+ uint16 op_port;
+ uint16 op_type;
+ int share_mode;
+ struct timeval time;
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ unsigned long share_file_id;
} share_mode_entry;
@@ -534,8 +570,29 @@ typedef struct
#define SHAREMODE_FN(fn) \
void (*fn)(share_mode_entry *, char*)
+/*
+ * bit flags representing initialized fields in SAM_ACCOUNT
+ */
+#define FLAG_SAM_UNINIT 0x00000000
+#define FLAG_SAM_UID 0x00000001
+#define FLAG_SAM_GID 0x00000002
+#define FLAG_SAM_SMBHOME 0x00000004
+#define FLAG_SAM_PROFILE 0x00000008
+#define FLAG_SAM_LOGONSCRIPT 0x00000010
+#define FLAG_SAM_DRIVE 0x00000020
+
+#define IS_SAM_UNIX_USER(x) \
+ (((x)->init_flag & SAM_ACCT_UNIX_UID) \
+ && ((x)->init_flag & SAM_ACCT_UNIX_GID))
+
+#define IS_SAM_SET(x, flag) ((x)->init_flag & (flag))
+
+
typedef struct sam_passwd
{
+ /* initiailization flags */
+ uint32 init_flag;
+
time_t logon_time; /* logon time */
time_t logoff_time; /* logoff time */
time_t kickoff_time; /* kickoff time */
@@ -967,11 +1024,11 @@ struct bitmap {
/* Generic access masks & rights. */
#define SPECIFIC_RIGHTS_MASK 0x00FFFFL
#define STANDARD_RIGHTS_MASK 0xFF0000L
-#define DELETE_ACCESS (1L<<16)
-#define READ_CONTROL_ACCESS (1L<<17)
-#define WRITE_DAC_ACCESS (1L<<18)
-#define WRITE_OWNER_ACCESS (1L<<19)
-#define SYNCHRONIZE_ACCESS (1L<<20)
+#define DELETE_ACCESS (1L<<16) /* 0x00010000 */
+#define READ_CONTROL_ACCESS (1L<<17) /* 0x00020000 */
+#define WRITE_DAC_ACCESS (1L<<18) /* 0x00040000 */
+#define WRITE_OWNER_ACCESS (1L<<19) /* 0x00080000 */
+#define SYNCHRONIZE_ACCESS (1L<<20) /* 0x00100000 */
/* Combinations of standard masks. */
#define STANDARD_RIGHTS_ALL_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)
@@ -980,12 +1037,12 @@ struct bitmap {
#define STANDARD_RIGHTS_REQUIRED_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS)
#define STANDARD_RIGHTS_WRITE_ACCESS (READ_CONTROL_ACCESS)
-#define SYSTEM_SECURITY_ACCESS (1L<<24)
-#define MAXIMUM_ALLOWED_ACCESS (1L<<25)
-#define GENERIC_ALL_ACCESS (1<<28)
-#define GENERIC_EXECUTE_ACCESS (1<<29)
-#define GENERIC_WRITE_ACCESS (1<<30)
-#define GENERIC_READ_ACCESS (((unsigned)1)<<31)
+#define SYSTEM_SECURITY_ACCESS (1L<<24) /* 0x01000000 */
+#define MAXIMUM_ALLOWED_ACCESS (1L<<25) /* 0x02000000 */
+#define GENERIC_ALL_ACCESS (1<<28) /* 0x10000000 */
+#define GENERIC_EXECUTE_ACCESS (1<<29) /* 0x20000000 */
+#define GENERIC_WRITE_ACCESS (1<<30) /* 0x40000000 */
+#define GENERIC_READ_ACCESS (((unsigned)1)<<31) /* 0x80000000 */
/* Mapping of generic access rights for files to specific rights. */
@@ -1042,7 +1099,9 @@ struct bitmap {
#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
/* Flags - combined with attributes. */
@@ -1096,9 +1155,10 @@ struct bitmap {
/* Acconding to testing, this actually sets the security attribute! */
#define FILE_PERSISTENT_ACLS 0x08
/* These entries added from cifs9f --tsb */
-#define FILE_FILE_COMPRESSION 0x08
-#define FILE_VOLUME_QUOTAS 0x10
-#define FILE_DEVICE_IS_MOUNTED 0x20
+#define FILE_FILE_COMPRESSION 0x10
+#define FILE_VOLUME_QUOTAS 0x20
+/* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */
+#define FILE_VOLUME_SPARSE_FILE 0x40
#define FILE_VOLUME_IS_COMPRESSED 0x8000
/* ChangeNotify flags. */
@@ -1237,6 +1297,7 @@ char *strdup(char *s);
#define CAP_W2K_SMBS 0x2000
#define CAP_LARGE_READX 0x4000
#define CAP_LARGE_WRITEX 0x8000
+#define CAP_UNIX 0x800000 /* Capabilities for UNIX extensions. Created by HP. */
#define CAP_EXTENDED_SECURITY 0x80000000
/* protocol types. It assumes that higher protocols include lower protocols
@@ -1397,19 +1458,18 @@ extern int chain_size;
*
* The form of this is :
*
- * 0 2 6 10 14 14+devsize 14+devsize+inodesize
- * +----+--------+--------+--------+-------+--------+
- * | cmd| pid | sec | usec | dev | inode |
- * +----+--------+--------+--------+-------+--------+
+ * 0 2 2+pid 2+pid+dev 2+pid+dev+ino
+ * +----+--------+-------+--------+---------+
+ * | cmd| pid | dev | inode | fileid |
+ * +----+--------+-------+--------+---------+
*/
#define OPLOCK_BREAK_CMD 0x1
#define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_SEC_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
-#define OPLOCK_BREAK_USEC_OFFSET (OPLOCK_BREAK_SEC_OFFSET + sizeof(time_t))
-#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_USEC_OFFSET + sizeof(long))
+#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
-#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
+#define OPLOCK_BREAK_FILEID_OFFSET (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
+#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
#define KERNEL_OPLOCK_BREAK_CMD 0x2
#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
@@ -1426,13 +1486,14 @@ extern int chain_size;
* Form of this is :
*
* 0 2 2+devsize 2+devsize+inodesize
- * +----+--------+--------+
- * | cmd| dev | inode |
- * +----+--------+--------+
+ * +----+--------+--------+----------+
+ * | cmd| dev | inode | fileid |
+ * +----+--------+--------+----------+
*/
#define KERNEL_OPLOCK_BREAK_DEV_OFFSET 2
#define KERNEL_OPLOCK_BREAK_INODE_OFFSET (KERNEL_OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
-#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
+#define KERNEL_OPLOCK_BREAK_FILEID_OFFSET (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
+#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
/* if a kernel does support oplocks then a structure of the following
@@ -1441,7 +1502,7 @@ struct kernel_oplocks {
BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len);
BOOL (*set_oplock)(files_struct *fsp, int oplock_type);
void (*release_oplock)(files_struct *fsp);
- BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev);
+ BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id);
BOOL (*msg_waiting)(fd_set *fds);
int notification_fd;
};
@@ -1542,10 +1603,16 @@ typedef struct user_struct
int session_id; /* used by utmp and pam session code */
} user_struct;
+struct unix_error_map {
+ int unix_error;
+ int dos_class;
+ int dos_code;
+ NTSTATUS nt_error;
+};
+
#include "ntdomain.h"
#include "client.h"
-#include "rpcclient.h"
/*
* Size of new password account encoding string. DO NOT CHANGE.
@@ -1583,12 +1650,4 @@ typedef struct user_struct
#include "nsswitch/winbindd_nss.h"
#include "smb_acls.h"
-/* Used by winbindd_glue functions */
-
-typedef struct {
- struct cli_state *cli;
- POLICY_HND handle;
- TALLOC_CTX *mem_ctx;
-} CLI_POLICY_HND;
-
#endif /* _SMB_H */
diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h
index 37aa7cb65c2..53adf39dbc5 100644
--- a/source/include/smb_acls.h
+++ b/source/include/smb_acls.h
@@ -122,6 +122,47 @@ typedef struct acl *SMB_ACL_ENTRY_T;
#define SMB_ACL_TYPE_ACCESS 0
#define SMB_ACL_TYPE_DEFAULT 1
+#elif defined(HAVE_HPUX_ACLS)
+
+/*
+ * Based on the Solaris & UnixWare code.
+ */
+
+#undef GROUP
+#include <sys/aclv.h>
+
+/* SVR4.2 ES/MP ACLs */
+typedef int SMB_ACL_TAG_T;
+typedef int SMB_ACL_TYPE_T;
+typedef ushort *SMB_ACL_PERMSET_T;
+typedef ushort SMB_ACL_PERM_T;
+#define SMB_ACL_READ 4
+#define SMB_ACL_WRITE 2
+#define SMB_ACL_EXECUTE 1
+
+/* Types of ACLs. */
+#define SMB_ACL_USER USER
+#define SMB_ACL_USER_OBJ USER_OBJ
+#define SMB_ACL_GROUP GROUP
+#define SMB_ACL_GROUP_OBJ GROUP_OBJ
+#define SMB_ACL_OTHER OTHER_OBJ
+#define SMB_ACL_MASK CLASS_OBJ
+
+typedef struct SMB_ACL_T {
+ int size;
+ int count;
+ int next;
+ struct acl acl[1];
+} *SMB_ACL_T;
+
+typedef struct acl *SMB_ACL_ENTRY_T;
+
+#define SMB_ACL_FIRST_ENTRY 0
+#define SMB_ACL_NEXT_ENTRY 1
+
+#define SMB_ACL_TYPE_ACCESS 0
+#define SMB_ACL_TYPE_DEFAULT 1
+
#elif defined(HAVE_IRIX_ACLS)
#define SMB_ACL_TAG_T acl_tag_t
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 6b554cb4795..5155d241d84 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -27,7 +27,6 @@
/* Misc bit macros */
#define BOOLSTR(b) ((b) ? "Yes" : "No")
-#define BITSETB(ptr,bit) ((((char *)ptr)[0] & (1<<(bit)))!=0)
#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
/* for readability... */
@@ -38,7 +37,9 @@
#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
/* free memory if the pointer is valid and zero the pointer */
-#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
/* zero a structure */
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
@@ -73,14 +74,17 @@
#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn)
#define CHECK_FSP(fsp,conn) if (!FNUM_OK(fsp,conn)) \
- return(ERROR(ERRDOS,ERRbadfid)); \
+ return(ERROR_DOS(ERRDOS,ERRbadfid)); \
else if((fsp)->fd == -1) \
- return(ERROR(ERRDOS,ERRbadaccess))
+ return(ERROR_DOS(ERRDOS,ERRbadaccess))
#define CHECK_READ(fsp) if (!(fsp)->can_read) \
- return(ERROR(ERRDOS,ERRbadaccess))
+ return(ERROR_DOS(ERRDOS,ERRbadaccess))
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
- return(ERROR(ERRDOS,ERRbadaccess))
+ return(ERROR_DOS(ERRDOS,ERRbadaccess))
+
+#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
+ return(CACHED_ERROR(fsp))
/* translates a connection number into a service number */
#define SNUM(conn) ((conn)?(conn)->service:-1)
@@ -132,22 +136,33 @@
#define SMB_LPID_OFFSET(indx) (10 * (indx))
#define SMB_LKOFF_OFFSET(indx) ( 2 + (10 * (indx)))
#define SMB_LKLEN_OFFSET(indx) ( 6 + (10 * (indx)))
-#define SMB_LARGE__LPID_OFFSET(indx) (20 * (indx))
+#define SMB_LARGE_LPID_OFFSET(indx) (20 * (indx))
#define SMB_LARGE_LKOFF_OFFSET_HIGH(indx) (4 + (20 * (indx)))
#define SMB_LARGE_LKOFF_OFFSET_LOW(indx) (8 + (20 * (indx)))
#define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
#define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
+/* Macro to cache an error in a write_bmpx_struct */
+#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
+ w->wr_discard = True, -1)
+/* Macro to test if an error has been cached for this fnum */
+#define HAS_CACHED_ERROR(fsp) ((fsp)->wbmpx_ptr && \
+ (fsp)->wbmpx_ptr->wr_discard)
+/* Macro to turn the cached error into an error packet */
+#define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__)
+
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
-#define ERROR(class,x) error_packet(outbuf,0,class,x,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,status,0,0,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,__LINE__,__FILE__)
#define ERROR_BOTH(nterr,class,x) error_packet(outbuf,nterr,class,x,__LINE__,__FILE__)
/* 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) (SMB_ROUNDUP((SMB_OFF_T)((s)+1), ((SMB_OFF_T)SMB_ROUNDUP_ALLOCATION_SIZE)))
/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)
@@ -200,6 +215,13 @@ copy an IP address from one buffer to another
#define putip(dest,src) memcpy(dest,src,4)
+
+/*******************************************************************
+ Return True if a server has CIFS UNIX capabilities.
+********************************************************************/
+
+#define SERVER_HAS_UNIX_CIFS(c) ((c)->capabilities & CAP_UNIX)
+
/****************************************************************************
Make a filename into unix format.
****************************************************************************/
@@ -219,6 +241,12 @@ copy an IP address from one buffer to another
#define vfs_stat(conn, fname, st) ((conn)->vfs_ops.stat((conn), dos_to_unix((fname),False),(st)))
/*******************************************************************
+ vfs lstat wrapper that calls dos_to_unix.
+********************************************************************/
+
+#define vfs_lstat(conn, fname, st) ((conn)->vfs_ops.lstat((conn), dos_to_unix((fname),False),(st)))
+
+/*******************************************************************
vfs fstat wrapper that calls dos_to_unix.
********************************************************************/
diff --git a/source/include/talloc.h b/source/include/talloc.h
index 89c2f82e056..06efbf6952a 100644
--- a/source/include/talloc.h
+++ b/source/include/talloc.h
@@ -32,4 +32,9 @@ typedef struct {
size_t total_alloc_size;
} TALLOC_CTX;
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
#endif
diff --git a/source/include/trans2.h b/source/include/trans2.h
index 3bf6203710e..2e086510e6e 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2002.
Extensively modified by Andrew Tridgell, 1995
@@ -235,6 +235,14 @@ Byte offset Type name description
* Thursby MAC extensions....
*/
+/*
+ * MAC CIFS Extensions have the range 0x300 - 0x2FF reserved.
+ * Supposedly Microsoft have agreed to this.
+ */
+
+#define MIN_MAC_INFO_LEVEL 0x300
+#define MAX_MAC_INFO_LEVEL 0x3FF
+
#define SMB_MAC_QUERY_FS_INFO 0x301
#define DIRLEN_GUESS (45+MAX(l1_achName,l2_achName))
@@ -299,8 +307,132 @@ Byte offset Type name description
#define SMB_FILE_TRACKING_INFORMATION 1036
#define SMB_FILE_MAXIMUM_INFORMATION 1037
+/* NT passthough levels for qfsinfo. */
-#endif
+#define SMB_FS_VOLUME_INFORMATION 1001
+#define SMB_FS_LABEL_INFORMATION 1002
+#define SMB_FS_SIZE_INFORMATION 1003
+#define SMB_FS_DEVICE_INFORMATION 1004
+#define SMB_FS_ATTRIBUTE_INFORMATION 1005
+#define SMB_FS_CONTROL_INFORMATION 1006
+#define SMB_FS_FULL_SIZE_INFORMATION 1007
+#define SMB_FS_OBJECTID_INFORMATION 1008
+
+/* UNIX CIFS Extensions - created by HP */
+/*
+ * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.
+ * Supposedly Microsoft have agreed to this.
+ */
+#define MIN_UNIX_INFO_LEVEL 0x200
+#define MAX_UNIX_INFO_LEVEL 0x2FF
+#define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL))
+#define SMB_QUERY_FILE_UNIX_BASIC 0x200 /* UNIX File Info*/
+#define SMB_SET_FILE_UNIX_BASIC 0x200
+
+#define SMB_MODE_NO_CHANGE 0xFFFFFFFF /* file mode value which */
+ /* means "don't change it" */
+#define SMB_UID_NO_CHANGE 0xFFFFFFFF
+#define SMB_GID_NO_CHANGE 0xFFFFFFFF
+
+/*
+Offset Size Name
+0 LARGE_INTEGER EndOfFile File size
+8 LARGE_INTEGER Blocks Number of bytes used on disk (st_blocks).
+16 LARGE_INTEGER CreationTime Creation time
+24 LARGE_INTEGER LastAccessTime Last access time
+32 LARGE_INTEGER LastModificationTime Last modification time
+40 LARGE_INTEGER Uid Numeric user id for the owner
+48 LARGE_INTEGER Gid Numeric group id of owner
+56 ULONG Type Enumeration specifying the pathname type:
+ 0 -- File
+ 1 -- Directory
+ 2 -- Symbolic link
+ 3 -- Character device
+ 4 -- Block device
+ 5 -- FIFO (named pipe)
+ 6 -- Unix domain socket
+
+60 LARGE_INTEGER devmajor Major device number if type is device
+68 LARGE_INTEGER devminor Minor device number if type is device
+76 LARGE_INTEGER uniqueid This is a server-assigned unique id for the file. The client
+ will typically map this onto an inode number. The scope of
+ uniqueness is the share.
+84 LARGE_INTEGER permissions Standard UNIX file permissions - see below.
+92 LARGE_INTEGER nlinks The number of directory entries that map to this entry
+ (number of hard links)
+
+100 - end.
+*/
+
+/* UNIX filetype mappings. */
+
+#define UNIX_TYPE_FILE 0
+#define UNIX_TYPE_DIR 1
+#define UNIX_TYPE_SYMLINK 2
+#define UNIX_TYPE_CHARDEV 3
+#define UNIX_TYPE_BLKDEV 4
+#define UNIX_TYPE_FIFO 5
+#define UNIX_TYPE_SOCKET 6
+#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF
+
+/*
+ * Oh this is fun. "Standard UNIX permissions" has no
+ * meaning in POSIX. We need to define the mapping onto
+ * and off the wire as this was not done in the original HP
+ * spec. JRA.
+ */
+
+#define UNIX_X_OTH 0000001
+#define UNIX_W_OTH 0000002
+#define UNIX_R_OTH 0000004
+#define UNIX_X_GRP 0000010
+#define UNIX_W_GRP 0000020
+#define UNIX_R_GRP 0000040
+#define UNIX_X_USR 0000100
+#define UNIX_W_USR 0000200
+#define UNIX_R_USR 0000400
+#define UNIX_STICKY 0001000
+#define UNIX_SET_GID 0002000
+#define UNIX_SET_UID 0004000
+
+/* Masks for the above */
+#define UNIX_OTH_MASK 0000007
+#define UNIX_GRP_MASK 0000070
+#define UNIX_USR_MASK 0000700
+#define UNIX_PERM_MASK 0000777
+#define UNIX_EXTRA_MASK 0007000
+#define UNIX_ALL_MASK 0007777
+
+#define SMB_QUERY_FILE_UNIX_LINK 0x201
+#define SMB_SET_FILE_UNIX_LINK 0x201
+#define SMB_SET_FILE_UNIX_HLINK 0x203
+
+#define SMB_FIND_FILE_UNIX 0x202
+
+/*
+ Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus
+ 64-bits worth of capability fun :-).
+*/
+
+#define SMB_QUERY_CIFS_UNIX_INFO 0x200
+
+/* Returns the following.
+
+ UINT16 major version number
+ UINT16 minor version number
+ LARGE_INTEGER capability bitfield
+
+*/
+
+#define CIFS_UNIX_MAJOR_VERSION 1
+#define CIFS_UNIX_MINOR_VERSION 0
+
+#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1
+#define CIFS_UNIX_POSIX_ACLS_CAP 0x2
+
+/* ... more as we think of them :-). */
+
+#endif
diff --git a/source/include/util_getent.h b/source/include/util_getent.h
index 11926b89641..5d4674ddefa 100644
--- a/source/include/util_getent.h
+++ b/source/include/util_getent.h
@@ -19,9 +19,13 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* element for a single linked list of group entries */
-/* replace the use of struct group in some cases */
-/* used by getgrent_list() */
+#ifndef _UTIL_GETENT_H
+#define _UTIL_GETENT_H
+
+/* Element for a single linked list of group entries */
+/* Replace the use of struct group in some cases */
+/* Used by getgrent_list() */
+
struct sys_grent {
char *gr_name;
char *gr_passwd;
@@ -30,9 +34,10 @@ struct sys_grent {
struct sys_grent *next;
};
-/* element for a single linked list of passwd entries */
-/* replace the use of struct passwd in some cases */
-/* used by getpwent_list() */
+/* Element for a single linked list of passwd entries */
+/* Replace the use of struct passwd in some cases */
+/* Used by getpwent_list() */
+
struct sys_pwent {
char *pw_name;
char *pw_passwd;
@@ -43,3 +48,15 @@ struct sys_pwent {
char *pw_shell;
struct sys_pwent *next;
};
+
+/* Element for a single linked list of user names in a group. */
+/* Used to return group lists that may span multiple lines in
+ /etc/group file. */
+/* Used by get_users_in_group() */
+
+struct sys_userlist {
+ struct sys_userlist *next, *prev;
+ char *unix_name;
+};
+
+#endif /* _UTIL_GETENT_H */
diff --git a/source/include/version.h b/source/include/version.h
index 5c72fb27810..2a79661b62c 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -1 +1 @@
-#define VERSION "2.2.2"
+#define VERSION "2.2.3-pre"
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 7d61e6f1062..ee4bdea6022 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -39,7 +39,8 @@
* vfs_ops below. JRA.
*/
-#define SMB_VFS_INTERFACE_VERSION 1
+/* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */
+#define SMB_VFS_INTERFACE_VERSION 2
/* VFS operations structure */
@@ -49,45 +50,48 @@ struct security_descriptor_info;
struct vfs_ops {
- /* Disk operations */
+ /* Disk operations */
- int (*connect)(struct connection_struct *conn, char *service, char *user);
- void (*disconnect)(struct connection_struct *conn);
- SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
+ int (*connect)(struct connection_struct *conn, char *service, char *user);
+ void (*disconnect)(struct connection_struct *conn);
+ SMB_BIG_UINT (*disk_free)(struct connection_struct *conn, char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
- /* Directory operations */
+ /* Directory operations */
- DIR *(*opendir)(struct connection_struct *conn, char *fname);
- struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp);
- int (*mkdir)(struct connection_struct *conn, char *path, mode_t mode);
- int (*rmdir)(struct connection_struct *conn, char *path);
- int (*closedir)(struct connection_struct *conn, DIR *dir);
+ DIR *(*opendir)(struct connection_struct *conn, char *fname);
+ struct dirent *(*readdir)(struct connection_struct *conn, DIR *dirp);
+ int (*mkdir)(struct connection_struct *conn, char *path, mode_t mode);
+ int (*rmdir)(struct connection_struct *conn, char *path);
+ int (*closedir)(struct connection_struct *conn, DIR *dir);
- /* File operations */
+ /* File operations */
- int (*open)(struct connection_struct *conn, char *fname, int flags, mode_t mode);
- int (*close)(struct files_struct *fsp, int fd);
- ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n);
- ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n);
- SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
- int (*rename)(struct connection_struct *conn, char *old, char *new);
- int (*fsync)(struct files_struct *fsp, int fd);
- int (*stat)(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
- int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
- int (*lstat)(struct connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf);
- int (*unlink)(struct connection_struct *conn, char *path);
- int (*chmod)(struct connection_struct *conn, char *path, mode_t mode);
- int (*fchmod)(struct files_struct *fsp, int fd, mode_t mode);
+ int (*open)(struct connection_struct *conn, char *fname, int flags, mode_t mode);
+ int (*close)(struct files_struct *fsp, int fd);
+ ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n);
+ ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n);
+ SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
+ int (*rename)(struct connection_struct *conn, char *old, char *new);
+ int (*fsync)(struct files_struct *fsp, int fd);
+ int (*stat)(struct connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
+ int (*fstat)(struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
+ int (*lstat)(struct connection_struct *conn, char *path, SMB_STRUCT_STAT *sbuf);
+ int (*unlink)(struct connection_struct *conn, char *path);
+ int (*chmod)(struct connection_struct *conn, char *path, mode_t mode);
+ int (*fchmod)(struct files_struct *fsp, int fd, mode_t mode);
int (*chown)(struct connection_struct *conn, char *path, uid_t uid, gid_t gid);
int (*fchown)(struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
int (*chdir)(struct connection_struct *conn, char *path);
char *(*getwd)(struct connection_struct *conn, char *buf);
- int (*utime)(struct connection_struct *conn, char *path, struct utimbuf *times);
+ int (*utime)(struct connection_struct *conn, char *path, struct utimbuf *times);
int (*ftruncate)(struct files_struct *fsp, int fd, SMB_OFF_T offset);
BOOL (*lock)(struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
int (*symlink)(struct connection_struct *conn, const char *oldpath, const char *newpath);
int (*readlink)(struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
+ int (*link)(struct connection_struct *conn, const char *oldpath, const char *newpath);
+ int (*mknod)(struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
+ char *(*realpath)(struct connection_struct *conn, const char *path, char *resolved_path);
/* NT ACL operations. */
diff --git a/source/lib/access.c b/source/lib/access.c
index ed4d5ac3631..d61915f0b24 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -10,8 +10,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* Delimiters for lists of daemons or clients. */
static char *sep = ", \t";
@@ -88,7 +86,7 @@ static int string_match(char *tok,char *s, char *invalid_char)
tok+1,
BOOLSTR(netgroup_ok)));
- free(hostname);
+ SAFE_FREE(hostname);
if (netgroup_ok) return(True);
#else
@@ -182,12 +180,12 @@ static int list_match(char *list,char *item, int (*match_fn)(char *, char *))
while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
/* VOID */ ;
if (tok == 0 || list_match((char *) 0, item, match_fn) == False) {
- if (listcopy != 0) free(listcopy); /* jkf */
+ SAFE_FREE(listcopy); /* jkf */
return (match);
}
}
- if (listcopy != 0) free(listcopy); /* jkf */
+ SAFE_FREE(listcopy); /* jkf */
return (False);
}
@@ -203,8 +201,14 @@ BOOL allow_access(char *deny_list,char *allow_list,
/* if it is loopback then always allow unless specifically denied */
if (strcmp(caddr, "127.0.0.1") == 0) {
+ /*
+ * If 127.0.0.1 matches both allow and deny then allow.
+ * Patch from Steve Langasek vorlon@netexpress.net.
+ */
if (deny_list &&
- list_match(deny_list,(char *)client,client_match)) {
+ list_match(deny_list,(char *)client,client_match) &&
+ (!allow_list ||
+ !list_match(allow_list,(char *)client, client_match))) {
return False;
}
return True;
@@ -274,8 +278,7 @@ static BOOL only_ipaddrs_in_list(const char* list)
}
}
- if (listcopy)
- free (listcopy);
+ SAFE_FREE(listcopy);
return only_ip;
}
@@ -323,10 +326,8 @@ BOOL check_access(int sock, char *allow_list, char *deny_list)
}
}
- if (deny)
- free(deny);
- if (allow)
- free(allow);
+ SAFE_FREE(deny);
+ SAFE_FREE(allow);
return(ret);
}
diff --git a/source/lib/bitmap.c b/source/lib/bitmap.c
index 7625f529095..6a327a5d95f 100644
--- a/source/lib/bitmap.c
+++ b/source/lib/bitmap.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* these functions provide a simple way to allocate integers from a
pool without repitition */
@@ -41,7 +39,7 @@ struct bitmap *bitmap_allocate(int n)
bm->n = n;
bm->b = (uint32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
if (!bm->b) {
- free(bm);
+ SAFE_FREE(bm);
return NULL;
}
@@ -59,10 +57,8 @@ void bitmap_free(struct bitmap *bm)
if (!bm)
return;
- if(bm->b)
- free(bm->b);
-
- free(bm);
+ SAFE_FREE(bm->b);
+ SAFE_FREE(bm);
}
/****************************************************************************
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 4a3d7090e31..0462668ff84 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
#define CTRLZ 26
-extern int DEBUGLEVEL;
static char cvtbuf[sizeof(pstring)];
@@ -270,6 +269,29 @@ update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
}
+/* Init for Bulgarian, Belarussian, and variants of Russian and Ukrainian locales */
+/* Patch from Alexander Bokovoy. */
+
+static void init_1251(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 866 -> 1251 */
+
+update_map ("\240\377\241\366\242\367\244\375");
+update_map ("\250\360\252\362\257\364");
+update_map ("\260\370\267\372");
+update_map ("\270\361\271\374\272\363\277\365");
+update_map ("\300\200\301\201\302\202\303\203\304\204\305\205\306\206\307\207");
+update_map ("\310\210\311\211\312\212\313\213\314\214\315\215\316\216\317\217");
+update_map ("\320\220\321\221\322\222\323\223\324\224\325\225\326\226\327\227");
+update_map ("\330\230\331\231\332\232\333\233\334\234\335\235\336\236\337\237");
+update_map ("\340\240\341\241\342\242\343\243\344\244\345\245\346\246\347\247");
+update_map ("\350\250\351\251\352\252\353\253\354\254\355\255\356\256\357\257");
+update_map ("\360\340\361\341\362\342\363\343\364\344\365\345\366\346\367\347");
+update_map ("\370\350\371\351\372\352\373\353\374\354\375\355\376\356\377\357");
+}
+
/* Init for ROMAN-8 (HP-UX) */
@@ -360,11 +382,13 @@ void interpret_character_set(char *str, int codepage)
init_iso8859_15(codepage);
} else if (strequal (str, "koi8-r")) {
init_koi8_r();
+ } else if (strequal (str, "1251")) {
+ init_1251();
} else if (strequal (str, "roman8")) {
init_roman8();
} else {
DEBUG(0,("unrecognized character set %s\n", str));
}
- load_unix_unicode_map(str);
+ load_unix_unicode_map(str, True);
}
diff --git a/source/lib/charset.c b/source/lib/charset.c
index d699df3e2b8..b4da2174c09 100644
--- a/source/lib/charset.c
+++ b/source/lib/charset.c
@@ -22,8 +22,6 @@
#define CHARSET_C
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
* Codepage definitions.
*/
@@ -314,8 +312,7 @@ clean_and_exit:
if(fd != -1)
close(fd);
- if(cp_p)
- free((char *)cp_p);
+ SAFE_FREE(cp_p);
return NULL;
}
@@ -373,6 +370,7 @@ for code page %d failed. Using default client codepage 850\n",
/* Try and load the unicode map. */
load_dos_unicode_map(client_codepage);
+ load_unix_unicode_map("iso8859-1", False); /* This will be reset by character set = XXX */
}
/*******************************************************************
@@ -396,5 +394,5 @@ void add_char_string(char *s)
}
}
- free(extra_chars);
+ SAFE_FREE(extra_chars);
}
diff --git a/source/lib/crc32.c b/source/lib/crc32.c
index 16b337c764b..e026fbf8615 100644
--- a/source/lib/crc32.c
+++ b/source/lib/crc32.c
@@ -7,7 +7,6 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
static unsigned long CRCTable[256] =
{
diff --git a/source/lib/debug.c b/source/lib/debug.c
index 982d59acc10..d3ba8f9c370 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -85,6 +85,7 @@ BOOL append_log = False;
int DEBUGLEVEL_CLASS[DBGC_LAST];
int DEBUGLEVEL = DEBUGLEVEL_CLASS;
+BOOL AllowDebugChange = True;
/* -------------------------------------------------------------------------- **
@@ -213,6 +214,8 @@ BOOL debug_parse_levels(char *params_str)
char *params[DBGC_LAST];
int debuglevel_class[DBGC_LAST];
+ if (AllowDebugChange == False)
+ return True;
ZERO_ARRAY(params);
ZERO_ARRAY(debuglevel_class);
@@ -336,7 +339,8 @@ BOOL reopen_logs( void )
log_overflow = True;
DEBUG(0, ("Unable to open new log file %s: %s\n", debugf, strerror(errno)));
log_overflow = False;
- fflush(dbf);
+ if (dbf)
+ fflush(dbf);
ret = False;
} else {
setbuf(new_dbf, NULL);
diff --git a/source/lib/domain_namemap.c b/source/lib/domain_namemap.c
index 988f5e5d659..81b519a88d6 100644
--- a/source/lib/domain_namemap.c
+++ b/source/lib/domain_namemap.c
@@ -47,7 +47,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern fstring global_myworkgroup;
extern DOM_SID global_member_sid;
@@ -240,19 +239,10 @@ static ubi_slList ntusrname_map_list;
static void delete_name_entry(name_map_entry *gmep)
{
- if (gmep->grp.nt_name)
- {
- free(gmep->grp.nt_name);
- }
- if (gmep->grp.nt_domain)
- {
- free(gmep->grp.nt_domain);
- }
- if (gmep->grp.unix_name)
- {
- free(gmep->grp.unix_name);
- }
- free((char*)gmep);
+ SAFE_FREE(gmep->grp.nt_name);
+ SAFE_FREE(gmep->grp.nt_domain);
+ SAFE_FREE(gmep->grp.unix_name);
+ SAFE_FREE(gmep);
}
/**************************************************************************
@@ -930,15 +920,8 @@ static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
{
res3 = False;
}
- if (types != NULL)
- {
- free(types);
- }
-
- if (sids != NULL)
- {
- free(sids);
- }
+ SAFE_FREE(types);
+ SAFE_FREE(sids);
return res3 && res4;
}
diff --git a/source/lib/error.c b/source/lib/error.c
index 880eba59497..df177bcea0a 100644
--- a/source/lib/error.c
+++ b/source/lib/error.c
@@ -23,53 +23,51 @@
/* Mapping between Unix, DOS and NT error numbers */
-struct {
- int unix_error;
- int dos_error;
- uint32 nt_error;
-} unix_dos_nt_errmap[] = {
- { EPERM, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
- { EACCES, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
- { ENOENT, ERRbadfile, NT_STATUS_NO_SUCH_FILE },
- { ENOTDIR, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY },
- { EIO, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR },
- { EBADF, ERRsrverror, NT_STATUS_INVALID_HANDLE },
- { EINVAL, ERRsrverror, NT_STATUS_INVALID_HANDLE },
- { EEXIST, ERRfilexists, NT_STATUS_ACCESS_DENIED},
- { ENFILE, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
- { EMFILE, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
- { ENOSPC, ERRdiskfull, NT_STATUS_DISK_FULL },
+struct unix_error_map unix_dos_nt_errmap[] = {
+ { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+ { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED },
+ { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE },
+ { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY },
+ { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR },
+ { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+ { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE },
+ { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_ACCESS_DENIED},
+ { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
+ { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
#ifdef EDQUOT
- { EDQUOT, ERRdiskfull, NT_STATUS_DISK_FULL },
+ { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
#endif
#ifdef ENOTEMPTY
- { ENOTEMPTY, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
+ { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY },
#endif
#ifdef EXDEV
- { EXDEV, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
+ { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE },
#endif
- { EROFS, ERRnowrite, NT_STATUS_ACCESS_DENIED },
-
- { 0, 0, 0 }
+#ifdef EROFS
+ { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED },
+#endif
+ { 0, 0, 0, NT_STATUS_OK }
};
-/* Map an NT error code from a Unix error code */
+/*********************************************************************
+ Map an NT error code from a Unix error code.
+*********************************************************************/
-uint32 map_nt_error_from_unix(int unix_error)
+NTSTATUS map_nt_error_from_unix(int unix_error)
{
int i = 0;
- /* Look through list */
+ if (unix_error == 0)
+ return NT_STATUS_OK;
+ /* Look through list */
while(unix_dos_nt_errmap[i].unix_error != 0) {
- if (unix_dos_nt_errmap[i].unix_error == unix_error) {
+ if (unix_dos_nt_errmap[i].unix_error == unix_error)
return unix_dos_nt_errmap[i].nt_error;
- }
-
i++;
}
/* Default return */
-
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source/lib/fault.c b/source/lib/fault.c
index 29272f19280..8d08fccd24c 100644
--- a/source/lib/fault.c
+++ b/source/lib/fault.c
@@ -20,8 +20,6 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
-
static void (*cont_fn)(void *);
@@ -79,6 +77,3 @@ void fault_setup(void (*fn)(void *))
CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
#endif
}
-
-
-
diff --git a/source/lib/genrand.c b/source/lib/genrand.c
index e5912601182..aad61d08309 100644
--- a/source/lib/genrand.c
+++ b/source/lib/genrand.c
@@ -23,9 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
static unsigned char hash[258];
static uint32 counter;
unsigned char *reseed_data;
@@ -37,8 +34,7 @@ size_t reseed_data_size;
void set_rand_reseed_data(unsigned char *data, size_t len)
{
- if (reseed_data)
- free(reseed_data);
+ SAFE_FREE(reseed_data);
reseed_data_size = 0;
reseed_data = (unsigned char *)memdup(data, len);
diff --git a/source/lib/hash.c b/source/lib/hash.c
index 3abdc2ef11b..68c334a8ca8 100644
--- a/source/lib/hash.c
+++ b/source/lib/hash.c
@@ -28,8 +28,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static BOOL enlarge_hash_table(hash_table *table);
static int primes[] =
{17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411};
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 3e45d627d37..3a269294ed9 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -21,13 +21,9 @@
#include "includes.h"
-#define MAX_INTERFACES 128
-
static struct iface_struct *probed_ifaces;
static int total_probed;
-extern int DEBUGLEVEL;
-
struct in_addr ipzero;
struct in_addr allones_ip;
struct in_addr loopback_ip;
@@ -179,17 +175,14 @@ void load_interfaces(void)
allones_ip = *interpret_addr2("255.255.255.255");
loopback_ip = *interpret_addr2("127.0.0.1");
- if (probed_ifaces) {
- free(probed_ifaces);
- probed_ifaces = NULL;
- }
+ SAFE_FREE(probed_ifaces);
/* dump the current interfaces if any */
while (local_interfaces) {
struct interface *iface = local_interfaces;
DLIST_REMOVE(local_interfaces, local_interfaces);
ZERO_STRUCTPN(iface);
- free(iface);
+ SAFE_FREE(iface);
}
/* probe the kernel for interfaces */
diff --git a/source/lib/messages.c b/source/lib/messages.c
index f7a5be4c2cc..b4fd82139ea 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -57,8 +57,9 @@ static struct dispatch_fns {
} *dispatch_fns;
/****************************************************************************
-notifications come in as signals
+ Notifications come in as signals.
****************************************************************************/
+
static void sig_usr1(void)
{
received_signal = 1;
@@ -66,16 +67,20 @@ static void sig_usr1(void)
}
/****************************************************************************
-a useful function for testing the message system
+ A useful function for testing the message system.
****************************************************************************/
+
void ping_message(int msg_type, pid_t src, void *buf, size_t len)
{
- DEBUG(1,("INFO: Received PING message from PID %u\n",(unsigned int)src));
+ char *msg = buf ? buf : "none";
+ DEBUG(1,("INFO: Received PING message from PID %u [%s]\n",(unsigned int)src, msg));
message_send_pid(src, MSG_PONG, buf, len, True);
}
+
/****************************************************************************
-return current debug level
+ Return current debug level.
****************************************************************************/
+
void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
{
DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
@@ -85,6 +90,7 @@ void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
/****************************************************************************
Initialise the messaging functions.
****************************************************************************/
+
BOOL message_init(void)
{
if (tdb) return True;
@@ -106,10 +112,10 @@ BOOL message_init(void)
return True;
}
-
/*******************************************************************
- form a static tdb key from a pid
+ Form a static tdb key from a pid.
******************************************************************/
+
static TDB_DATA message_key_pid(pid_t pid)
{
static char key[20];
@@ -122,11 +128,11 @@ static TDB_DATA message_key_pid(pid_t pid)
return kbuf;
}
-
/****************************************************************************
-notify a process that it has a message. If the process doesn't exist
-then delete its record in the database
+ Notify a process that it has a message. If the process doesn't exist
+ then delete its record in the database.
****************************************************************************/
+
static BOOL message_notify(pid_t pid)
{
if (kill(pid, SIGUSR1) == -1) {
@@ -142,8 +148,9 @@ static BOOL message_notify(pid_t pid)
}
/****************************************************************************
-send a message to a particular pid
+ Send a message to a particular pid.
****************************************************************************/
+
BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL duplicates_allowed)
{
TDB_DATA kbuf;
@@ -175,7 +182,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
dbuf.dptr = p;
dbuf.dsize = len + sizeof(rec);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- free(p);
+ SAFE_FREE(p);
goto ok;
}
@@ -193,7 +200,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
if (!memcmp(ptr, &rec, sizeof(rec))) {
if (!len || (len && !memcmp( ptr + sizeof(rec), (char *)buf, len))) {
DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return True;
}
@@ -211,11 +218,11 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
memcpy((void *)((char*)p+dbuf.dsize), &rec, sizeof(rec));
if (len > 0) memcpy((void *)((char*)p+dbuf.dsize+sizeof(rec)), buf, len);
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize += len + sizeof(rec);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
ok:
tdb_chainunlock(tdb, kbuf);
@@ -228,11 +235,10 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
return False;
}
-
-
/****************************************************************************
-retrieve the next message for the current process
+ Retrieve the next message for the current process.
****************************************************************************/
+
static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
{
TDB_DATA kbuf;
@@ -275,7 +281,7 @@ static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
else
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return True;
@@ -284,12 +290,12 @@ static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
return False;
}
-
/****************************************************************************
-receive and dispatch any messages pending for this process
-notice that all dispatch handlers for a particular msg_type get called,
-so you can register multiple handlers for a message
+ Receive and dispatch any messages pending for this process.
+ Notice that all dispatch handlers for a particular msg_type get called,
+ so you can register multiple handlers for a message.
****************************************************************************/
+
void message_dispatch(void)
{
int msg_type;
@@ -311,14 +317,14 @@ void message_dispatch(void)
dfn->fn(msg_type, src, buf, len);
}
}
- if (buf) free(buf);
+ SAFE_FREE(buf);
}
}
-
/****************************************************************************
-register a dispatch function for a particular message type
+ Register a dispatch function for a particular message type.
****************************************************************************/
+
void message_register(int msg_type,
void (*fn)(int msg_type, pid_t pid, void *buf, size_t len))
{
@@ -342,8 +348,9 @@ void message_register(int msg_type,
}
/****************************************************************************
-de-register the function for a particular message type
+ De-register the function for a particular message type.
****************************************************************************/
+
void message_deregister(int msg_type)
{
struct dispatch_fns *dfn, *next;
@@ -352,7 +359,7 @@ void message_deregister(int msg_type)
next = dfn->next;
if (dfn->msg_type == msg_type) {
DLIST_REMOVE(dispatch_fns, dfn);
- free(dfn);
+ SAFE_FREE(dfn);
}
}
}
@@ -365,8 +372,9 @@ struct msg_all {
};
/****************************************************************************
-send one of the messages for the broadcast
+ Send one of the messages for the broadcast.
****************************************************************************/
+
static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
struct connections_data crec;
@@ -396,10 +404,11 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
}
/****************************************************************************
-this is a useful function for sending messages to all smbd processes.
-It isn't very efficient, but should be OK for the sorts of applications that
-use it. When we need efficient broadcast we can add it.
+ This is a useful function for sending messages to all smbd processes.
+ It isn't very efficient, but should be OK for the sorts of applications that
+ use it. When we need efficient broadcast we can add it.
****************************************************************************/
+
BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, void *buf, size_t len, BOOL duplicates_allowed)
{
struct msg_all msg_all;
diff --git a/source/lib/netatalk.c b/source/lib/netatalk.c
index ae0a57154e1..e1913f5379b 100644
--- a/source/lib/netatalk.c
+++ b/source/lib/netatalk.c
@@ -28,8 +28,6 @@
#ifdef WITH_NETATALK
-extern int DEBUGLEVEL;
-
/*****************
ntalk_resourcepath: creates the path to the netatalk resource fork for
a given file
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index a26aa12a3c1..25ca1944111 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#ifndef O_NONBLOCK
#define O_NONBLOCK
#endif
diff --git a/source/lib/readline.c b/source/lib/readline.c
index a1cdbe15872..91f9a1b31d5 100644
--- a/source/lib/readline.c
+++ b/source/lib/readline.c
@@ -23,45 +23,58 @@
#include "includes.h"
/****************************************************************************
-display the prompt and wait for input. Call callback() regularly
+ Display the prompt and wait for input. Call callback() regularly
****************************************************************************/
+
char *smb_readline(char *prompt, void (*callback)(void),
- char **(completion_fn)(char *text, int start, int end))
+ char **(completion_fn)(const char *text, int start, int end))
{
char *ret;
+ int fd = fileno(stdin);
+
#if HAVE_LIBREADLINE
- if (completion_fn) {
- rl_attempted_completion_function = completion_fn;
- }
- if (callback) rl_event_hook = (Function *)callback;
- ret = readline(prompt);
- if (ret && *ret) add_history(ret);
- return ret;
-#else
- fd_set fds;
- extern FILE *dbf;
- static pstring line;
- struct timeval timeout;
- int fd = fileno(stdin);
+ /*
+ * Current versions of readline on Linux seem to have
+ * problems with EOF on a pipe.
+ */
+
+ if (isatty(fd)) {
+ if (completion_fn)
+ rl_attempted_completion_function = completion_fn;
- fprintf(dbf, "%s", prompt);
- fflush(dbf);
+ if (callback)
+ rl_event_hook = (Function *)callback;
+ ret = readline(prompt);
+ if (ret && *ret)
+ add_history(ret);
+ return ret;
+ } else
+#endif
+ {
+ fd_set fds;
+ extern FILE *dbf;
+ static pstring line;
+ struct timeval timeout;
- while (1) {
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
+ fprintf(dbf, "%s", prompt);
+ fflush(dbf);
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
+ while (1) {
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
- if (sys_select_intr(fd+1,&fds,&timeout) == 1) {
- ret = fgets(line, sizeof(line), stdin);
- return ret;
+ if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
+ ret = fgets(line, sizeof(line), stdin);
+ return ret;
+ }
+ if (callback)
+ callback();
}
- if (callback) callback();
}
-#endif
}
/****************************************************************************
diff --git a/source/lib/replace.c b/source/lib/replace.c
index 45c302f498a..16d7450d69e 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
void replace_dummy(void);
void replace_dummy(void) {}
@@ -194,7 +192,7 @@ Corrections by richard.kettlewell@kewill.com
}
endgrent();
ret = sys_setgroups(i,grouplst);
- free((char *)grouplst);
+ SAFE_FREE(grouplst);
return ret;
#endif /* HAVE_SETGROUPS */
}
diff --git a/source/lib/select.c b/source/lib/select.c
index 396ecb5dd6b..f70268b7ce4 100644
--- a/source/lib/select.c
+++ b/source/lib/select.c
@@ -21,22 +21,23 @@
#include "includes.h"
-/* this is here because it allows us to avoid a nasty race in signal handling.
+/* This is here because it allows us to avoid a nasty race in signal handling.
We need to guarantee that when we get a signal we get out of a select immediately
but doing that involves a race condition. We can avoid the race by getting the
signal handler to write to a pipe that is in the select/poll list
- this means all Samba signal handlers should call sys_select_signal()
+ This means all Samba signal handlers should call sys_select_signal().
*/
+
static pid_t initialised;
static int select_pipe[2];
static VOLATILE unsigned pipe_written, pipe_read;
-
/*******************************************************************
-call this from all Samba signal handlers if you want to avoid a
-nasty signal race condition
+ Call this from all Samba signal handlers if you want to avoid a
+ nasty signal race condition.
********************************************************************/
+
void sys_select_signal(void)
{
char c = 1;
@@ -48,13 +49,15 @@ void sys_select_signal(void)
}
/*******************************************************************
-like select() but avoids the signal race using a pipe
-it also guuarantees that fds on return only ever contains bits set
-for file descriptors that were readable
+ Like select() but avoids the signal race using a pipe
+ it also guuarantees that fds on return only ever contains bits set
+ for file descriptors that were readable.
********************************************************************/
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
+
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
{
int ret, saved_errno;
+ fd_set *readfds2, readfds_buf;
if (initialised != sys_getpid()) {
pipe(select_pipe);
@@ -77,16 +80,29 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
}
maxfd = MAX(select_pipe[0]+1, maxfd);
- FD_SET(select_pipe[0], fds);
+
+ /* If readfds is NULL we need to provide our own set. */
+ if (readfds) {
+ readfds2 = readfds;
+ } else {
+ readfds2 = &readfds_buf;
+ FD_ZERO(readfds2);
+ }
+ FD_SET(select_pipe[0], readfds2);
+
errno = 0;
- ret = select(maxfd,fds,NULL,NULL,tval);
+ ret = select(maxfd,readfds2,writefds,errorfds,tval);
if (ret <= 0) {
- FD_ZERO(fds);
+ FD_ZERO(readfds2);
+ if (writefds)
+ FD_ZERO(writefds);
+ if (errorfds)
+ FD_ZERO(errorfds);
}
- if (FD_ISSET(select_pipe[0], fds)) {
- FD_CLR(select_pipe[0], fds);
+ if (FD_ISSET(select_pipe[0], readfds2)) {
+ FD_CLR(select_pipe[0], readfds2);
ret--;
if (ret == 0) {
ret = -1;
@@ -110,20 +126,35 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
}
/*******************************************************************
-similar to sys_select() but catch EINTR and continue
-this is what sys_select() used to do in Samba
+ Similar to sys_select() but catch EINTR and continue.
+ This is what sys_select() used to do in Samba.
********************************************************************/
-int sys_select_intr(int maxfd, fd_set *fds,struct timeval *tval)
+
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
{
int ret;
- fd_set fds2;
+ fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
+
+ readfds2 = (readfds ? &readfds_buf : NULL);
+ writefds2 = (writefds ? &writefds_buf : NULL);
+ errorfds2 = (errorfds ? &errorfds_buf : NULL);
do {
- fds2 = *fds;
- ret = sys_select(maxfd, &fds2, tval);
+ if (readfds)
+ readfds_buf = *readfds;
+ if (writefds)
+ writefds_buf = *writefds;
+ if (errorfds)
+ errorfds_buf = *errorfds;
+ ret = sys_select(maxfd, readfds2, writefds2, errorfds2, tval);
} while (ret == -1 && errno == EINTR);
- *fds = fds2;
+ if (readfds)
+ *readfds = readfds_buf;
+ if (writefds)
+ *writefds = writefds_buf;
+ if (errorfds)
+ *errorfds = errorfds_buf;
return ret;
}
diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c
index 62378503e0f..1ace6e3a991 100644
--- a/source/lib/smbrun.c
+++ b/source/lib/smbrun.c
@@ -24,8 +24,6 @@
/* need to move this from here!! need some sleep ... */
struct current_user current_user;
-extern int DEBUGLEVEL;
-
/****************************************************************************
This is a utility function of smbrun().
****************************************************************************/
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index 0a52e1762b1..0b0bdb0b335 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -94,6 +94,11 @@
#define LLONG long
#endif
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
static size_t dopr(char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
@@ -333,6 +338,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
break;
case 's':
strvalue = va_arg (args, char *);
+ if (!strvalue) strvalue = "(NULL)";
if (max == -1) {
max = strlen(strvalue);
}
@@ -748,6 +754,7 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
(*currlen)++;
}
+/* yes this really must be a ||. Don't muck with this (tridge) */
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
@@ -755,7 +762,15 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
}
#endif
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
+/* yes this really must be a ||. Don't muck wiith this (tridge)
+ *
+ * The logic for these two is that we need our own definition if the
+ * OS *either* has no definition of *sprintf, or if it does have one
+ * that doesn't work properly according to the autoconf test. Perhaps
+ * these should really be smb_snprintf to avoid conflicts with buggy
+ * linkers? -- mbp
+ */
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_SNPRINTF)
int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
@@ -793,6 +808,7 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
va_list ap;
int ret;
+ *ptr = NULL;
va_start(ap, format);
ret = vasprintf(ptr, format, ap);
va_end(ap);
@@ -801,6 +817,20 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
}
#endif
+#ifndef HAVE_VSYSLOG
+#ifdef HAVE_SYSLOG
+ void vsyslog (int facility_priority, char *format, va_list arglist)
+{
+ char *msg = NULL;
+ vasprintf(&msg, format, arglist);
+ if (!msg)
+ return;
+ syslog(facility_priority, "%s", msg);
+ SAFE_FREE(msg);
+}
+#endif /* HAVE_SYSLOG */
+#endif /* HAVE_VSYSLOG */
+
#ifdef TEST_SNPRINTF
int sprintf(char *str,const char *fmt,...);
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 25be4b030f7..387b07bc512 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
fstring local_machine="";
fstring remote_arch="UNKNOWN";
userdom_struct current_user_info;
@@ -39,6 +37,7 @@ fstring remote_machine="";
Based on code by Branko Cibej <branko.cibej@hermes.si>
When this is called p points at the '%' character.
********************************************************************/
+
static size_t expand_env_var(char *p, int len)
{
fstring envname;
@@ -91,13 +90,14 @@ static size_t expand_env_var(char *p, int len)
Patch from jkf@soton.ac.uk
Added this to implement %p (NIS auto-map version of %H)
*******************************************************************/
+
static char *automount_path(char *user_name)
{
static pstring server_path;
/* use the passwd entry as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
- /* pstrcpy() copes with get_user_home_dir() returning NULL */
+
pstrcpy(server_path, get_user_home_dir(user_name));
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
@@ -115,9 +115,7 @@ static char *automount_path(char *user_name)
}
} else {
/* NIS key lookup failed: default to user home directory from password file */
- pstrcpy(server_path, get_user_home_dir(user_name));
- DEBUG(5, ("NIS lookup failed. Using Home path from passwd file. Home path is: %s\n",
- server_path ));
+ DEBUG(5, ("NIS lookup failed. Using Home path from passwd file. Home path is: %s\n", server_path ));
}
}
#endif
@@ -127,32 +125,33 @@ static char *automount_path(char *user_name)
return server_path;
}
-
/*******************************************************************
Patch from jkf@soton.ac.uk
This is Luke's original function with the NIS lookup code
moved out to a separate function.
*******************************************************************/
+
static char *automount_server(char *user_name)
{
+ extern pstring global_myname;
static pstring server_name;
/* use the local machine name as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
- pstrcpy(server_name, local_machine);
+ if (*local_machine)
+ pstrcpy(server_name, local_machine);
+ else
+ pstrcpy(server_name, global_myname);
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
- if (lp_nis_home_map())
- {
+ if (lp_nis_home_map()) {
int home_server_len;
char *automount_value = automount_lookup(user_name);
home_server_len = strcspn(automount_value,":");
DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
if (home_server_len > sizeof(pstring))
- {
home_server_len = sizeof(pstring);
- }
strncpy(server_name, automount_value, home_server_len);
server_name[home_server_len] = '\0';
}
@@ -166,10 +165,12 @@ static char *automount_server(char *user_name)
/****************************************************************************
Do some standard substitutions in a string.
****************************************************************************/
+
void standard_sub_basic(char *str)
{
char *p, *s;
fstring pidstr;
+ struct passwd *pass;
for (s=str; (p=strchr(s, '%'));s=p) {
fstring tmp_str;
@@ -182,6 +183,14 @@ void standard_sub_basic(char *str)
strlower(tmp_str);
string_sub(p,"%U",tmp_str,l);
break;
+ case 'G' :
+ fstrcpy(tmp_str, sam_logon_in_ssb?samlogon_user:current_user_info.smb_name);
+ if ((pass = Get_Pwnam(tmp_str, False))!=NULL) {
+ string_sub(p,"%G",gidtoname(pass->pw_gid),l);
+ } else {
+ p += 2;
+ }
+ break;
case 'D' :
fstrcpy(tmp_str, current_user_info.domain);
strupper(tmp_str);
@@ -211,26 +220,18 @@ void standard_sub_basic(char *str)
}
}
-
/****************************************************************************
Do some standard substitutions in a string.
****************************************************************************/
+
void standard_sub_advanced(int snum, char *user, char *connectpath, gid_t gid, char *str)
{
char *p, *s, *home;
- struct passwd *pass;
for (s=str; (p=strchr(s, '%'));s=p) {
int l = sizeof(pstring) - (int)(p-str);
switch (*(p+1)) {
- case 'G' :
- if ((pass = Get_Pwnam(user,False))!=NULL) {
- string_sub(p,"%G",gidtoname(pass->pw_gid),l);
- } else {
- p += 2;
- }
- break;
case 'N' : string_sub(p,"%N", automount_server(user),l); break;
case 'H':
if ((home = get_user_home_dir(user))) {
@@ -279,14 +280,47 @@ void standard_sub_advanced(int snum, char *user, char *connectpath, gid_t gid, c
/****************************************************************************
Do some standard substitutions in a string.
****************************************************************************/
+
void standard_sub_conn(connection_struct *conn, char *str)
{
standard_sub_advanced(SNUM(conn), conn->user, conn->connectpath, conn->gid, str);
}
/****************************************************************************
-like standard_sub but by snum
+ Like standard_sub but for a homes share where snum still points to the [homes]
+ share. No user specific snum created yet so servicename should be the username.
+****************************************************************************/
+
+void standard_sub_home(int snum, char *user, char *str)
+{
+ char *p, *s;
+
+ for (s=str; (p=strchr(s, '%'));s=p) {
+ int l = sizeof(pstring) - (int)(p-str);
+
+ switch (*(p+1)) {
+ case 'S':
+ string_sub(p,"%S", user, l);
+ break;
+ case 'p':
+ string_sub(p,"%p", automount_path(user), l);
+ break;
+ case '\0':
+ p++;
+ break; /* don't run off the end of the string */
+
+ default: p+=2;
+ break;
+ }
+ }
+
+ standard_sub_advanced(snum, user, "", -1, str);
+}
+
+/****************************************************************************
+ Like standard_sub but by snum.
****************************************************************************/
+
void standard_sub_snum(int snum, char *str)
{
extern struct current_user current_user;
@@ -306,6 +340,7 @@ void standard_sub_snum(int snum, char *str)
/*******************************************************************
Substitute strings with useful parameters.
********************************************************************/
+
void standard_sub_vuser(char *str, user_struct *vuser)
{
standard_sub_advanced(-1, vuser->user.unix_name, "", -1, str);
@@ -314,8 +349,8 @@ void standard_sub_vuser(char *str, user_struct *vuser)
/*******************************************************************
Substitute strings with useful parameters.
********************************************************************/
+
void standard_sub_vsnum(char *str, user_struct *vuser, int snum)
{
standard_sub_advanced(snum, vuser->user.unix_name, "", -1, str);
}
-
diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c
index 0f488888a8f..743c098bebd 100644
--- a/source/lib/sysacls.c
+++ b/source/lib/sysacls.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
This file wraps all differing system ACL interfaces into a consistent
one based on the POSIX interface. It also returns the correct errors
@@ -700,7 +698,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
maxlen += nbytes + 20 * (acl_d->count - i);
if ((text = Realloc(oldtext, maxlen)) == NULL) {
- free(oldtext);
+ SAFE_FREE(oldtext);
errno = ENOMEM;
return NULL;
}
@@ -928,9 +926,7 @@ int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
ret = acl(name, SETACL, acl_count, acl_p);
- if (acl_buf) {
- free(acl_buf);
- }
+ SAFE_FREE(acl_buf);
return ret;
}
@@ -966,13 +962,968 @@ int sys_acl_delete_def_file(const char *path)
int sys_acl_free_text(char *text)
{
- free(text);
+ SAFE_FREE(text);
+ return 0;
+}
+
+int sys_acl_free_acl(SMB_ACL_T acl_d)
+{
+ SAFE_FREE(acl_d);
+ return 0;
+}
+
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
+{
+ return 0;
+}
+
+#elif defined(HAVE_HPUX_ACLS)
+#include <dl.h>
+
+/*
+ * Based on the Solaris/SCO code - with modifications.
+ */
+
+/*
+ * Note that while this code implements sufficient functionality
+ * to support the sys_acl_* interfaces it does not provide all
+ * of the semantics of the POSIX ACL interfaces.
+ *
+ * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
+ * from a call to sys_acl_get_entry() should not be assumed to be
+ * valid after calling any of the following functions, which may
+ * reorder the entries in the ACL.
+ *
+ * sys_acl_valid()
+ * sys_acl_set_file()
+ * sys_acl_set_fd()
+ */
+
+/* This checks if the POSIX ACL system call is defined */
+/* which basically corresponds to whether JFS 3.3 or */
+/* higher is installed. If acl() was called when it */
+/* isn't defined, it causes the process to core dump */
+/* so it is important to check this and avoid acl() */
+/* calls if it isn't there. */
+
+static BOOL hpux_acl_call_presence(void)
+{
+
+ shl_t handle = NULL;
+ void *value;
+ int ret_val=0;
+ static BOOL already_checked=0;
+
+ if(already_checked)
+ return True;
+
+
+ ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);
+
+ if(ret_val != 0) {
+ DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",
+ ret_val, errno, strerror(errno)));
+ DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));
+ return False;
+ }
+
+ DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));
+
+ already_checked = True;
+ return True;
+}
+
+int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+ if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (entry_p == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (entry_id == SMB_ACL_FIRST_ENTRY) {
+ acl_d->next = 0;
+ }
+
+ if (acl_d->next < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (acl_d->next >= acl_d->count) {
+ return 0;
+ }
+
+ *entry_p = &acl_d->acl[acl_d->next++];
+
+ return 1;
+}
+
+int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
+{
+ *type_p = entry_d->a_type;
+
+ return 0;
+}
+
+int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+ *permset_p = &entry_d->a_perm;
+
+ return 0;
+}
+
+void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
+{
+ if (entry_d->a_type != SMB_ACL_USER
+ && entry_d->a_type != SMB_ACL_GROUP) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return &entry_d->a_id;
+}
+
+/*
+ * There is no way of knowing what size the ACL returned by
+ * ACL_GET will be unless you first call ACL_CNT which means
+ * making an additional system call.
+ *
+ * In the hope of avoiding the cost of the additional system
+ * call in most cases, we initially allocate enough space for
+ * an ACL with INITIAL_ACL_SIZE entries. If this turns out to
+ * be too small then we use ACL_CNT to find out the actual
+ * size, reallocate the ACL buffer, and then call ACL_GET again.
+ */
+
+#define INITIAL_ACL_SIZE 16
+
+SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
+{
+ SMB_ACL_T acl_d;
+ int count; /* # of ACL entries allocated */
+ int naccess; /* # of access ACL entries */
+ int ndefault; /* # of default ACL entries */
+
+ if(hpux_acl_call_presence() == False) {
+ /* Looks like we don't have the acl() system call on HPUX.
+ * May be the system doesn't have the latest version of JFS.
+ */
+ return NULL;
+ }
+
+ if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ count = INITIAL_ACL_SIZE;
+ if ((acl_d = sys_acl_init(count)) == NULL) {
+ return NULL;
+ }
+
+ /*
+ * If there isn't enough space for the ACL entries we use
+ * ACL_CNT to determine the actual number of ACL entries
+ * reallocate and try again. This is in a loop because it
+ * is possible that someone else could modify the ACL and
+ * increase the number of entries between the call to
+ * ACL_CNT and the call to ACL_GET.
+ */
+ while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {
+
+ sys_acl_free_acl(acl_d);
+
+ if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {
+ return NULL;
+ }
+
+ if ((acl_d = sys_acl_init(count)) == NULL) {
+ return NULL;
+ }
+ }
+
+ if (count < 0) {
+ sys_acl_free_acl(acl_d);
+ return NULL;
+ }
+
+ /*
+ * calculate the number of access and default ACL entries
+ *
+ * Note: we assume that the acl() system call returned a
+ * well formed ACL which is sorted so that all of the
+ * access ACL entries preceed any default ACL entries
+ */
+ for (naccess = 0; naccess < count; naccess++) {
+ if (acl_d->acl[naccess].a_type & ACL_DEFAULT)
+ break;
+ }
+ ndefault = count - naccess;
+
+ /*
+ * if the caller wants the default ACL we have to copy
+ * the entries down to the start of the acl[] buffer
+ * and mask out the ACL_DEFAULT flag from the type field
+ */
+ if (type == SMB_ACL_TYPE_DEFAULT) {
+ int i, j;
+
+ for (i = 0, j = naccess; i < ndefault; i++, j++) {
+ acl_d->acl[i] = acl_d->acl[j];
+ acl_d->acl[i].a_type &= ~ACL_DEFAULT;
+ }
+
+ acl_d->count = ndefault;
+ } else {
+ acl_d->count = naccess;
+ }
+
+ return acl_d;
+}
+
+SMB_ACL_T sys_acl_get_fd(int fd)
+{
+ /*
+ * HPUX doesn't have the facl call. Fake it using the path.... JRA.
+ */
+
+ files_struct *fsp = file_find_fd(fd);
+
+ if (fsp == NULL) {
+ errno = EBADF;
+ return NULL;
+ }
+
+ /*
+ * We know we're in the same conn context. So we
+ * can use the relative path.
+ */
+
+ return sys_acl_get_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS);
+}
+
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
+{
+ *permset_d = 0;
+
+ return 0;
+}
+
+int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
+{
+ if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
+ && perm != SMB_ACL_EXECUTE) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (permset_d == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *permset_d |= perm;
+
+ return 0;
+}
+
+int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
+{
+ return *permset_d & perm;
+}
+
+char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
+{
+ int i;
+ int len, maxlen;
+ char *text;
+
+ /*
+ * use an initial estimate of 20 bytes per ACL entry
+ * when allocating memory for the text representation
+ * of the ACL
+ */
+ len = 0;
+ maxlen = 20 * acl_d->count;
+ if ((text = malloc(maxlen)) == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ for (i = 0; i < acl_d->count; i++) {
+ struct acl *ap = &acl_d->acl[i];
+ struct passwd *pw;
+ struct group *gr;
+ char tagbuf[12];
+ char idbuf[12];
+ char *tag;
+ char *id = "";
+ char perms[4];
+ int nbytes;
+
+ switch (ap->a_type) {
+ /*
+ * for debugging purposes it's probably more
+ * useful to dump unknown tag types rather
+ * than just returning an error
+ */
+ default:
+ slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
+ ap->a_type);
+ tag = tagbuf;
+ slprintf(idbuf, sizeof(idbuf)-1, "%ld",
+ (long)ap->a_id);
+ id = idbuf;
+ break;
+
+ case SMB_ACL_USER:
+ if ((pw = sys_getpwuid(ap->a_id)) == NULL) {
+ slprintf(idbuf, sizeof(idbuf)-1, "%ld",
+ (long)ap->a_id);
+ id = idbuf;
+ } else {
+ id = pw->pw_name;
+ }
+ case SMB_ACL_USER_OBJ:
+ tag = "user";
+ break;
+
+ case SMB_ACL_GROUP:
+ if ((gr = getgrgid(ap->a_id)) == NULL) {
+ slprintf(idbuf, sizeof(idbuf)-1, "%ld",
+ (long)ap->a_id);
+ id = idbuf;
+ } else {
+ id = gr->gr_name;
+ }
+ case SMB_ACL_GROUP_OBJ:
+ tag = "group";
+ break;
+
+ case SMB_ACL_OTHER:
+ tag = "other";
+ break;
+
+ case SMB_ACL_MASK:
+ tag = "mask";
+ break;
+
+ }
+
+ perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
+ perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
+ perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
+ perms[3] = '\0';
+
+ /* <tag> : <qualifier> : rwx \n \0 */
+ nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
+
+ /*
+ * If this entry would overflow the buffer
+ * allocate enough additional memory for this
+ * entry and an estimate of another 20 bytes
+ * for each entry still to be processed
+ */
+ if ((len + nbytes) > maxlen) {
+ char *oldtext = text;
+
+ maxlen += nbytes + 20 * (acl_d->count - i);
+
+ if ((text = Realloc(oldtext, maxlen)) == NULL) {
+ SAFE_FREE(oldtext);
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+
+ slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
+ len += nbytes - 1;
+ }
+
+ if (len_p)
+ *len_p = len;
+
+ return text;
+}
+
+SMB_ACL_T sys_acl_init(int count)
+{
+ SMB_ACL_T a;
+
+ if (count < 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /*
+ * note that since the definition of the structure pointed
+ * to by the SMB_ACL_T includes the first element of the
+ * acl[] array, this actually allocates an ACL with room
+ * for (count+1) entries
+ */
+ if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ a->size = count + 1;
+ a->count = 0;
+ a->next = -1;
+
+ return a;
+}
+
+
+int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
+{
+ SMB_ACL_T acl_d;
+ SMB_ACL_ENTRY_T entry_d;
+
+ if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (acl_d->count >= acl_d->size) {
+ errno = ENOSPC;
+ return -1;
+ }
+
+ entry_d = &acl_d->acl[acl_d->count++];
+ entry_d->a_type = 0;
+ entry_d->a_id = -1;
+ entry_d->a_perm = 0;
+ *entry_p = entry_d;
+
+ return 0;
+}
+
+int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
+{
+ switch (tag_type) {
+ case SMB_ACL_USER:
+ case SMB_ACL_USER_OBJ:
+ case SMB_ACL_GROUP:
+ case SMB_ACL_GROUP_OBJ:
+ case SMB_ACL_OTHER:
+ case SMB_ACL_MASK:
+ entry_d->a_type = tag_type;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return 0;
+}
+
+int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
+{
+ if (entry_d->a_type != SMB_ACL_GROUP
+ && entry_d->a_type != SMB_ACL_USER) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ entry_d->a_id = *((id_t *)qual_p);
+
+ return 0;
+}
+
+int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
+{
+ if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
+ return EINVAL;
+ }
+
+ entry_d->a_perm = *permset_d;
+
+ return 0;
+}
+
+/* Structure to capture the count for each type of ACE. */
+
+struct hpux_acl_types {
+ int n_user;
+ int n_def_user;
+ int n_user_obj;
+ int n_def_user_obj;
+
+ int n_group;
+ int n_def_group;
+ int n_group_obj;
+ int n_def_group_obj;
+
+ int n_other;
+ int n_other_obj;
+ int n_def_other_obj;
+
+ int n_class_obj;
+ int n_def_class_obj;
+
+ int n_illegal_obj;
+};
+
+/* count_obj:
+ * Counts the different number of objects in a given array of ACL
+ * structures.
+ * Inputs:
+ *
+ * acl_count - Count of ACLs in the array of ACL strucutres.
+ * aclp - Array of ACL structures.
+ * acl_type_count - Pointer to acl_types structure. Should already be
+ * allocated.
+ * Output:
+ *
+ * acl_type_count - This structure is filled up with counts of various
+ * acl types.
+ */
+
+static int hpux_count_obj(int acl_count, struct acl *aclp, struct hpux_acl_types *acl_type_count)
+{
+ int i;
+
+ memset(acl_type_count, 0, sizeof(struct hpux_acl_types));
+
+ for(i=0;i<acl_count;i++) {
+ switch(aclp[i].a_type) {
+ case USER:
+ acl_type_count->n_user++;
+ break;
+ case USER_OBJ:
+ acl_type_count->n_user_obj++;
+ break;
+ case DEF_USER_OBJ:
+ acl_type_count->n_def_user_obj++;
+ break;
+ case GROUP:
+ acl_type_count->n_group++;
+ break;
+ case GROUP_OBJ:
+ acl_type_count->n_group_obj++;
+ break;
+ case DEF_GROUP_OBJ:
+ acl_type_count->n_def_group_obj++;
+ break;
+ case OTHER_OBJ:
+ acl_type_count->n_other_obj++;
+ break;
+ case DEF_OTHER_OBJ:
+ acl_type_count->n_def_other_obj++;
+ break;
+ case CLASS_OBJ:
+ acl_type_count->n_class_obj++;
+ break;
+ case DEF_CLASS_OBJ:
+ acl_type_count->n_def_class_obj++;
+ break;
+ case DEF_USER:
+ acl_type_count->n_def_user++;
+ break;
+ case DEF_GROUP:
+ acl_type_count->n_def_group++;
+ break;
+ default:
+ acl_type_count->n_illegal_obj++;
+ break;
+ }
+ }
+}
+
+/* swap_acl_entries: Swaps two ACL entries.
+ *
+ * Inputs: aclp0, aclp1 - ACL entries to be swapped.
+ */
+
+static void hpux_swap_acl_entries(struct acl *aclp0, struct acl *aclp1)
+{
+ struct acl temp_acl;
+
+ temp_acl.a_type = aclp0->a_type;
+ temp_acl.a_id = aclp0->a_id;
+ temp_acl.a_perm = aclp0->a_perm;
+
+ aclp0->a_type = aclp1->a_type;
+ aclp0->a_id = aclp1->a_id;
+ aclp0->a_perm = aclp1->a_perm;
+
+ aclp1->a_type = temp_acl.a_type;
+ aclp1->a_id = temp_acl.a_id;
+ aclp1->a_perm = temp_acl.a_perm;
+}
+
+/* prohibited_duplicate_type
+ * Identifies if given ACL type can have duplicate entries or
+ * not.
+ *
+ * Inputs: acl_type - ACL Type.
+ *
+ * Outputs:
+ *
+ * Return..
+ *
+ * True - If the ACL type matches any of the prohibited types.
+ * False - If the ACL type doesn't match any of the prohibited types.
+ */
+
+static BOOL hpux_prohibited_duplicate_type(int acl_type)
+{
+ switch(acl_type) {
+ case USER:
+ case GROUP:
+ case DEF_USER:
+ case DEF_GROUP:
+ return True;
+ default:
+ return False;
+ }
+}
+
+/* get_needed_class_perm
+ * Returns the permissions of a ACL structure only if the ACL
+ * type matches one of the pre-determined types for computing
+ * CLASS_OBJ permissions.
+ *
+ * Inputs: aclp - Pointer to ACL structure.
+ */
+
+static int hpux_get_needed_class_perm(struct acl *aclp)
+{
+ switch(aclp->a_type) {
+ case USER:
+ case GROUP_OBJ:
+ case GROUP:
+ case DEF_USER_OBJ:
+ case DEF_USER:
+ case DEF_GROUP_OBJ:
+ case DEF_GROUP:
+ case DEF_CLASS_OBJ:
+ case DEF_OTHER_OBJ:
+ return aclp->a_perm;
+ default:
+ return 0;
+ }
+}
+
+/* acl_sort for HPUX.
+ * Sorts the array of ACL structures as per the description in
+ * aclsort man page. Refer to aclsort man page for more details
+ *
+ * Inputs:
+ *
+ * acl_count - Count of ACLs in the array of ACL structures.
+ * calclass - If this is not zero, then we compute the CLASS_OBJ
+ * permissions.
+ * aclp - Array of ACL structures.
+ *
+ * Outputs:
+ *
+ * aclp - Sorted array of ACL structures.
+ *
+ * Outputs:
+ *
+ * Returns 0 for success -1 for failure. Prints a message to the Samba
+ * debug log in case of failure.
+ */
+
+static int hpux_acl_sort(int acl_count, int calclass, struct acl *aclp)
+{
+#if !defined(HAVE_HPUX_ACLSORT)
+ /*
+ * The aclsort() system call is availabe on the latest HPUX General
+ * Patch Bundles. So for HPUX, we developed our version of acl_sort
+ * function. Because, we don't want to update to a new
+ * HPUX GR bundle just for aclsort() call.
+ */
+
+ struct hpux_acl_types acl_obj_count;
+ int n_class_obj_perm = 0;
+ int i, j;
+
+ if(!acl_count) {
+ DEBUG(10,("Zero acl count passed. Returning Success\n"));
+ return 0;
+ }
+
+ if(aclp == NULL) {
+ DEBUG(0,("Null ACL pointer in hpux_acl_sort. Returning Failure. \n"));
+ return -1;
+ }
+
+ /* Count different types of ACLs in the ACLs array */
+
+ hpux_count_obj(acl_count, aclp, &acl_obj_count);
+
+ /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
+ * CLASS_OBJ and OTHER_OBJ
+ */
+
+ if( (acl_obj_count.n_user_obj != 1) ||
+ (acl_obj_count.n_group_obj != 1) ||
+ (acl_obj_count.n_class_obj != 1) ||
+ (acl_obj_count.n_other_obj != 1)
+ ) {
+ DEBUG(0,("hpux_acl_sort: More than one entry or no entries for \
+USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
+ return -1;
+ }
+
+ /* If any of the default objects are present, there should be only
+ * one of them each.
+ */
+
+ if( (acl_obj_count.n_def_user_obj > 1) || (acl_obj_count.n_def_group_obj > 1) ||
+ (acl_obj_count.n_def_other_obj > 1) || (acl_obj_count.n_def_class_obj > 1) ) {
+ DEBUG(0,("hpux_acl_sort: More than one entry for DEF_CLASS_OBJ \
+or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
+ return -1;
+ }
+
+ /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
+ * structures.
+ *
+ * Sorting crieteria - First sort by ACL type. If there are multiple entries of
+ * same ACL type, sort by ACL id.
+ *
+ * I am using the trival kind of sorting method here because, performance isn't
+ * really effected by the ACLs feature. More over there aren't going to be more
+ * than 17 entries on HPUX.
+ */
+
+ for(i=0; i<acl_count;i++) {
+ for (j=i+1; j<acl_count; j++) {
+ if( aclp[i].a_type > aclp[j].a_type ) {
+ /* ACL entries out of order, swap them */
+
+ hpux_swap_acl_entries((aclp+i), (aclp+j));
+
+ } else if ( aclp[i].a_type == aclp[j].a_type ) {
+
+ /* ACL entries of same type, sort by id */
+
+ if(aclp[i].a_id > aclp[j].a_id) {
+ hpux_swap_acl_entries((aclp+i), (aclp+j));
+ } else if (aclp[i].a_id == aclp[j].a_id) {
+ /* We have a duplicate entry. */
+ if(hpux_prohibited_duplicate_type(aclp[i].a_type)) {
+ DEBUG(0, ("hpux_acl_sort: Duplicate entry: Type(hex): %x Id: %d\n",
+ aclp[i].a_type, aclp[i].a_id));
+ return -1;
+ }
+ }
+
+ }
+ }
+ }
+
+ /* set the class obj permissions to the computed one. */
+ if(calclass) {
+ int n_class_obj_index = -1;
+
+ for(i=0;i<acl_count;i++) {
+ n_class_obj_perm |= hpux_get_needed_class_perm((aclp+i));
+
+ if(aclp[i].a_type == CLASS_OBJ)
+ n_class_obj_index = i;
+ }
+ aclp[n_class_obj_index].a_perm = n_class_obj_perm;
+ }
+
+ return 0;
+#else
+ return aclsort(acl_count, calclass, aclp);
+#endif
+}
+
+/*
+ * sort the ACL and check it for validity
+ *
+ * if it's a minimal ACL with only 4 entries then we
+ * need to recalculate the mask permissions to make
+ * sure that they are the same as the GROUP_OBJ
+ * permissions as required by the UnixWare acl() system call.
+ *
+ * (note: since POSIX allows minimal ACLs which only contain
+ * 3 entries - ie there is no mask entry - we should, in theory,
+ * check for this and add a mask entry if necessary - however
+ * we "know" that the caller of this interface always specifies
+ * a mask so, in practice "this never happens" (tm) - if it *does*
+ * happen aclsort() will fail and return an error and someone will
+ * have to fix it ...)
+ */
+
+static int acl_sort(SMB_ACL_T acl_d)
+{
+ int fixmask = (acl_d->count <= 4);
+
+ if (hpux_acl_sort(acl_d->count, fixmask, acl_d->acl) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+}
+
+int sys_acl_valid(SMB_ACL_T acl_d)
+{
+ return acl_sort(acl_d);
+}
+
+int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+{
+ struct stat s;
+ struct acl *acl_p;
+ int acl_count;
+ struct acl *acl_buf = NULL;
+ int ret;
+
+ if(hpux_acl_call_presence() == False) {
+ /* Looks like we don't have the acl() system call on HPUX.
+ * May be the system doesn't have the latest version of JFS.
+ */
+ errno=ENOSYS;
+ return -1;
+ }
+
+ if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (acl_sort(acl_d) != 0) {
+ return -1;
+ }
+
+ acl_p = &acl_d->acl[0];
+ acl_count = acl_d->count;
+
+ /*
+ * if it's a directory there is extra work to do
+ * since the acl() system call will replace both
+ * the access ACLs and the default ACLs (if any)
+ */
+ if (stat(name, &s) != 0) {
+ return -1;
+ }
+ if (S_ISDIR(s.st_mode)) {
+ SMB_ACL_T acc_acl;
+ SMB_ACL_T def_acl;
+ SMB_ACL_T tmp_acl;
+ int i;
+
+ if (type == SMB_ACL_TYPE_ACCESS) {
+ acc_acl = acl_d;
+ def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);
+
+ } else {
+ def_acl = acl_d;
+ acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);
+ }
+
+ if (tmp_acl == NULL) {
+ return -1;
+ }
+
+ /*
+ * allocate a temporary buffer for the complete ACL
+ */
+ acl_count = acc_acl->count + def_acl->count;
+ acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
+
+ if (acl_buf == NULL) {
+ sys_acl_free_acl(tmp_acl);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /*
+ * copy the access control and default entries into the buffer
+ */
+ memcpy(&acl_buf[0], &acc_acl->acl[0],
+ acc_acl->count * sizeof(acl_buf[0]));
+
+ memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],
+ def_acl->count * sizeof(acl_buf[0]));
+
+ /*
+ * set the ACL_DEFAULT flag on the default entries
+ */
+ for (i = acc_acl->count; i < acl_count; i++) {
+ acl_buf[i].a_type |= ACL_DEFAULT;
+ }
+
+ sys_acl_free_acl(tmp_acl);
+
+ } else if (type != SMB_ACL_TYPE_ACCESS) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ret = acl(name, ACL_SET, acl_count, acl_p);
+
+ SAFE_FREE(acl_buf);
+
+ return ret;
+}
+
+int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
+{
+ /*
+ * HPUX doesn't have the facl call. Fake it using the path.... JRA.
+ */
+
+ files_struct *fsp = file_find_fd(fd);
+
+ if (fsp == NULL) {
+ errno = EBADF;
+ return NULL;
+ }
+
+ if (acl_sort(acl_d) != 0) {
+ return -1;
+ }
+
+ /*
+ * We know we're in the same conn context. So we
+ * can use the relative path.
+ */
+
+ return sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS, acl_d);
+}
+
+int sys_acl_delete_def_file(const char *path)
+{
+ SMB_ACL_T acl_d;
+ int ret;
+
+ /*
+ * fetching the access ACL and rewriting it has
+ * the effect of deleting the default ACL
+ */
+ if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {
+ return -1;
+ }
+
+ ret = acl(path, ACL_SET, acl_d->count, acl_d->acl);
+
+ sys_acl_free_acl(acl_d);
+
+ return ret;
+}
+
+int sys_acl_free_text(char *text)
+{
+ SAFE_FREE(text);
return 0;
}
int sys_acl_free_acl(SMB_ACL_T acl_d)
{
- free(acl_d);
+ SAFE_FREE(acl_d);
return 0;
}
@@ -1047,7 +1998,7 @@ SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type)
return NULL;
}
if ((a->aclp = acl_get_file(path_p, type)) == NULL) {
- free(a);
+ SAFE_FREE(a);
return NULL;
}
a->next = -1;
@@ -1064,7 +2015,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
return NULL;
}
if ((a->aclp = acl_get_fd(fd)) == NULL) {
- free(a);
+ SAFE_FREE(a);
return NULL;
}
a->next = -1;
@@ -1355,7 +2306,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
rc = statacl((char *)path_p,0,file_acl,BUFSIZ);
if(rc == -1) {
DEBUG(0,("statacl returned %d with errno %d\n",rc,errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1375,7 +2326,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
if(acl_entry_link->entryp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return(NULL);
@@ -1412,7 +2363,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
malloc(sizeof(struct acl_entry_link));
if(acl_entry_link->nextp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return(NULL);
@@ -1422,7 +2373,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
acl_entry_link = acl_entry_link->nextp;
acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
if(acl_entry_link->entryp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return(NULL);
@@ -1481,7 +2432,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
if(acl_entry_link_head->count != 0) {
acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
if(acl_entry_link->nextp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return(NULL);
@@ -1491,7 +2442,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
acl_entry_link = acl_entry_link->nextp;
acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
if(acl_entry_link->entryp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return(NULL);
@@ -1535,7 +2486,7 @@ SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
}
acl_entry_link_head->count = 0;
- free(file_acl);
+ SAFE_FREE(file_acl);
return(acl_entry_link_head);
}
@@ -1569,7 +2520,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
rc = fstatacl(fd,0,file_acl,BUFSIZ);
if(rc == -1) {
DEBUG(0,("The fstatacl call returned %d with errno %d\n",rc,errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1585,7 +2536,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
acl_entry_link_head = acl_entry_link = sys_acl_init(0);
if(acl_entry_link_head == NULL){
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1594,7 +2545,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1630,7 +2581,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
acl_entry_link->nextp->prevp = acl_entry_link;
@@ -1639,7 +2590,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1698,7 +2649,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
- free(file_acl);
+ SAFE_FREE(file_acl);
return(NULL);
}
@@ -1707,7 +2658,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
if(acl_entry_link->entryp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
return(NULL);
@@ -1750,7 +2701,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
}
acl_entry_link_head->count = 0;
- free(file_acl);
+ SAFE_FREE(file_acl);
return(acl_entry_link_head);
}
@@ -1955,14 +2906,14 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
acl_length += sizeof(struct acl_entry);
file_acl_temp = (struct acl *)malloc(acl_length);
if(file_acl_temp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_set_file is %d\n",errno));
return(-1);
}
memcpy(file_acl_temp,file_acl,file_acl->acl_len);
- free(file_acl);
+ SAFE_FREE(file_acl);
file_acl = file_acl_temp;
}
@@ -1989,7 +2940,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
rc = chacl(name,file_acl,file_acl->acl_len);
DEBUG(10,("errno is %d\n",errno));
DEBUG(10,("return code is %d\n",rc));
- free(file_acl);
+ SAFE_FREE(file_acl);
DEBUG(10,("Exiting the sys_acl_set_file\n"));
return(rc);
}
@@ -2044,14 +2995,14 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
acl_length += sizeof(struct acl_entry);
file_acl_temp = (struct acl *)malloc(acl_length);
if(file_acl_temp == NULL) {
- free(file_acl);
+ SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_set_fd is %d\n",errno));
return(-1);
}
memcpy(file_acl_temp,file_acl,file_acl->acl_len);
- free(file_acl);
+ SAFE_FREE(file_acl);
file_acl = file_acl_temp;
}
@@ -2078,7 +3029,7 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
rc = fchacl(fd,file_acl,file_acl->acl_len);
DEBUG(10,("errno is %d\n",errno));
DEBUG(10,("return code is %d\n",rc));
- free(file_acl);
+ SAFE_FREE(file_acl);
DEBUG(10,("Exiting sys_acl_set_fd\n"));
return(rc);
}
@@ -2104,14 +3055,14 @@ int sys_acl_free_acl(SMB_ACL_T posix_acl)
struct acl_entry_link *acl_entry_link;
for(acl_entry_link = posix_acl->nextp; acl_entry_link->nextp != NULL; acl_entry_link = acl_entry_link->nextp) {
- free(acl_entry_link->prevp->entryp);
- free(acl_entry_link->prevp);
+ SAFE_FREE(acl_entry_link->prevp->entryp);
+ SAFE_FREE(acl_entry_link->prevp);
}
- free(acl_entry_link->prevp->entryp);
- free(acl_entry_link->prevp);
- free(acl_entry_link->entryp);
- free(acl_entry_link);
+ SAFE_FREE(acl_entry_link->prevp->entryp);
+ SAFE_FREE(acl_entry_link->prevp);
+ SAFE_FREE(acl_entry_link->entryp);
+ SAFE_FREE(acl_entry_link);
return(0);
}
diff --git a/source/lib/system.c b/source/lib/system.c
index a402af77c9b..a4420f5c6c2 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -3,6 +3,7 @@
Version 1.9.
Samba system utilities
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998-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
@@ -21,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
The idea is that this file will eventually have wrappers around all
important system calls in samba. The aims are:
@@ -47,30 +46,30 @@ extern int DEBUGLEVEL;
int sys_usleep(long usecs)
{
#ifndef HAVE_USLEEP
- struct timeval tval;
+ struct timeval tval;
#endif
- /*
- * We need this braindamage as the glibc usleep
- * is not SPEC1170 complient... grumble... JRA.
- */
+ /*
+ * We need this braindamage as the glibc usleep
+ * is not SPEC1170 complient... grumble... JRA.
+ */
- if(usecs < 0 || usecs > 1000000) {
- errno = EINVAL;
- return -1;
- }
+ if(usecs < 0 || usecs > 1000000) {
+ errno = EINVAL;
+ return -1;
+ }
#if HAVE_USLEEP
- usleep(usecs);
- return 0;
+ usleep(usecs);
+ return 0;
#else /* HAVE_USLEEP */
- /*
- * Fake it with select...
- */
- tval.tv_sec = 0;
- tval.tv_usec = usecs/1000;
- select(0,NULL,NULL,NULL,&tval);
- return 0;
+ /*
+ * Fake it with select...
+ */
+ tval.tv_sec = 0;
+ tval.tv_usec = usecs/1000;
+ select(0,NULL,NULL,NULL,&tval);
+ return 0;
#endif /* HAVE_USLEEP */
}
@@ -132,9 +131,9 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
int sys_ftruncate(int fd, SMB_OFF_T offset)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
- return ftruncate64(fd, offset);
+ return ftruncate64(fd, offset);
#else
- return ftruncate(fd, offset);
+ return ftruncate(fd, offset);
#endif
}
@@ -145,9 +144,9 @@ int sys_ftruncate(int fd, SMB_OFF_T offset)
SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
- return lseek64(fd, offset, whence);
+ return lseek64(fd, offset, whence);
#else
- return lseek(fd, offset, whence);
+ return lseek(fd, offset, whence);
#endif
}
@@ -158,11 +157,11 @@ SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
- return fseek64(fp, offset, whence);
+ return fseek64(fp, offset, whence);
#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
- return fseeko64(fp, offset, whence);
+ return fseeko64(fp, offset, whence);
#else
- return fseek(fp, offset, whence);
+ return fseek(fp, offset, whence);
#endif
}
@@ -173,11 +172,11 @@ int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
SMB_OFF_T sys_ftell(FILE *fp)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
- return (SMB_OFF_T)ftell64(fp);
+ return (SMB_OFF_T)ftell64(fp);
#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
- return (SMB_OFF_T)ftello64(fp);
+ return (SMB_OFF_T)ftello64(fp);
#else
- return (SMB_OFF_T)ftell(fp);
+ return (SMB_OFF_T)ftell(fp);
#endif
}
@@ -188,13 +187,13 @@ SMB_OFF_T sys_ftell(FILE *fp)
int sys_creat(const char *path, mode_t mode)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
- return creat64(path, mode);
+ return creat64(path, mode);
#else
- /*
- * If creat64 isn't defined then ensure we call a potential open64.
- * JRA.
- */
- return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+ /*
+ * If creat64 isn't defined then ensure we call a potential open64.
+ * JRA.
+ */
+ return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
#endif
}
@@ -205,9 +204,9 @@ int sys_creat(const char *path, mode_t mode)
int sys_open(const char *path, int oflag, mode_t mode)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
- return open64(path, oflag, mode);
+ return open64(path, oflag, mode);
#else
- return open(path, oflag, mode);
+ return open(path, oflag, mode);
#endif
}
@@ -218,9 +217,9 @@ int sys_open(const char *path, int oflag, mode_t mode)
FILE *sys_fopen(const char *path, const char *type)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
- return fopen64(path, type);
+ return fopen64(path, type);
#else
- return fopen(path, type);
+ return fopen(path, type);
#endif
}
@@ -231,9 +230,43 @@ FILE *sys_fopen(const char *path, const char *type)
SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
{
#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
- return readdir64(dirp);
+ return readdir64(dirp);
#else
- return readdir(dirp);
+ return readdir(dirp);
+#endif
+}
+
+/*******************************************************************
+ An mknod() wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
+{
+#if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
+ return mknod64(path, mode, dev);
+#else
+ return mknod(path, mode, dev);
+#endif
+#else
+ /* No mknod system call. */
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+/*******************************************************************
+ Wrapper for realpath.
+********************************************************************/
+
+char *sys_realpath(const char *path, char *resolved_path)
+{
+#if defined(HAVE_REALPATH)
+ return realpath(path, resolved_path);
+#else
+ /* As realpath is not a system call we can't return ENOSYS. */
+ errno = EINVAL;
+ return NULL;
#endif
}
@@ -244,24 +277,25 @@ The wait() calls vary between systems
int sys_waitpid(pid_t pid,int *status,int options)
{
#ifdef HAVE_WAITPID
- return waitpid(pid,status,options);
+ return waitpid(pid,status,options);
#else /* HAVE_WAITPID */
- return wait4(pid, status, options, NULL);
+ return wait4(pid, status, options, NULL);
#endif /* HAVE_WAITPID */
}
/*******************************************************************
-system wrapper for getwd
+ System wrapper for getwd
********************************************************************/
+
char *sys_getwd(char *s)
{
- char *wd;
+ char *wd;
#ifdef HAVE_GETCWD
- wd = (char *)getcwd(s, sizeof (pstring));
+ wd = (char *)getcwd(s, sizeof (pstring));
#else
- wd = (char *)getwd(s);
+ wd = (char *)getwd(s);
#endif
- return wd;
+ return wd;
}
/*******************************************************************
@@ -293,6 +327,20 @@ int sys_readlink(const char *path, char *buf, size_t bufsiz)
}
/*******************************************************************
+system wrapper for link
+********************************************************************/
+
+int sys_link(const char *oldpath, const char *newpath)
+{
+#ifndef HAVE_LINK
+ errno = ENOSYS;
+ return -1;
+#else
+ return link(oldpath, newpath);
+#endif
+}
+
+/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
@@ -332,39 +380,40 @@ A wrapper for gethostbyname() that tries avoids looking up hostnames
in the root domain, which can cause dial-on-demand links to come up for no
apparent reason.
****************************************************************************/
+
struct hostent *sys_gethostbyname(const char *name)
{
#ifdef REDUCE_ROOT_DNS_LOOKUPS
- char query[256], hostname[256];
- char *domain;
+ char query[256], hostname[256];
+ char *domain;
- /* Does this name have any dots in it? If so, make no change */
+ /* Does this name have any dots in it? If so, make no change */
- if (strchr(name, '.'))
- return(gethostbyname(name));
+ if (strchr(name, '.'))
+ return(gethostbyname(name));
- /* Get my hostname, which should have domain name
- attached. If not, just do the gethostname on the
- original string.
- */
+ /* Get my hostname, which should have domain name
+ attached. If not, just do the gethostname on the
+ original string.
+ */
- gethostname(hostname, sizeof(hostname) - 1);
- hostname[sizeof(hostname) - 1] = 0;
- if ((domain = strchr(hostname, '.')) == NULL)
- return(gethostbyname(name));
+ gethostname(hostname, sizeof(hostname) - 1);
+ hostname[sizeof(hostname) - 1] = 0;
+ if ((domain = strchr(hostname, '.')) == NULL)
+ return(gethostbyname(name));
- /* Attach domain name to query and do modified query.
- If names too large, just do gethostname on the
- original string.
- */
+ /* Attach domain name to query and do modified query.
+ If names too large, just do gethostname on the
+ original string.
+ */
- if((strlen(name) + strlen(domain)) >= sizeof(query))
- return(gethostbyname(name));
+ if((strlen(name) + strlen(domain)) >= sizeof(query))
+ return(gethostbyname(name));
- slprintf(query, sizeof(query)-1, "%s%s", name, domain);
- return(gethostbyname(query));
+ slprintf(query, sizeof(query)-1, "%s%s", name, domain);
+ return(gethostbyname(query));
#else /* REDUCE_ROOT_DNS_LOOKUPS */
- return(gethostbyname(name));
+ return(gethostbyname(name));
#endif /* REDUCE_ROOT_DNS_LOOKUPS */
}
@@ -375,33 +424,32 @@ struct hostent *sys_gethostbyname(const char *name)
****************************************************************************/
static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
{
- if(cap_flag == KERNEL_OPLOCK_CAPABILITY)
- {
- cap_t cap = cap_get_proc();
-
- if (cap == NULL) {
- DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
- strerror(errno)));
- return False;
- }
-
- if(enable)
- cap->cap_effective |= CAP_NETWORK_MGT;
- else
- cap->cap_effective &= ~CAP_NETWORK_MGT;
-
- if (cap_set_proc(cap) == -1) {
- DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
- strerror(errno)));
- cap_free(cap);
- return False;
- }
-
- cap_free(cap);
-
- DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
- }
- return True;
+ if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
+ cap_t cap = cap_get_proc();
+
+ if (cap == NULL) {
+ DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
+ strerror(errno)));
+ return False;
+ }
+
+ if(enable)
+ cap->cap_effective |= CAP_NETWORK_MGT;
+ else
+ cap->cap_effective &= ~CAP_NETWORK_MGT;
+
+ if (cap_set_proc(cap) == -1) {
+ DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
+ strerror(errno)));
+ cap_free(cap);
+ return False;
+ }
+
+ cap_free(cap);
+
+ DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
+ }
+ return True;
}
/**************************************************************************
@@ -410,39 +458,39 @@ static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
{
- if(cap_flag == KERNEL_OPLOCK_CAPABILITY)
- {
- cap_t cap = cap_get_proc();
-
- if (cap == NULL) {
- DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
- strerror(errno)));
- return False;
- }
-
- if(enable)
- cap->cap_inheritable |= CAP_NETWORK_MGT;
- else
- cap->cap_inheritable &= ~CAP_NETWORK_MGT;
-
- if (cap_set_proc(cap) == -1) {
- DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
- strerror(errno)));
- cap_free(cap);
- return False;
- }
-
- cap_free(cap);
-
- DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
- }
- return True;
+ if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
+ cap_t cap = cap_get_proc();
+
+ if (cap == NULL) {
+ DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
+ strerror(errno)));
+ return False;
+ }
+
+ if(enable)
+ cap->cap_inheritable |= CAP_NETWORK_MGT;
+ else
+ cap->cap_inheritable &= ~CAP_NETWORK_MGT;
+
+ if (cap_set_proc(cap) == -1) {
+ DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
+ strerror(errno)));
+ cap_free(cap);
+ return False;
+ }
+
+ cap_free(cap);
+
+ DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
+ }
+ return True;
}
#endif
/****************************************************************************
-gain the oplock capability from the kernel if possible
+ Gain the oplock capability from the kernel if possible.
****************************************************************************/
+
void oplock_set_capability(BOOL this_process, BOOL inherit)
{
#if HAVE_KERNEL_OPLOCKS_IRIX
@@ -458,12 +506,12 @@ void oplock_set_capability(BOOL this_process, BOOL inherit)
long sys_random(void)
{
#if defined(HAVE_RANDOM)
- return (long)random();
+ return (long)random();
#elif defined(HAVE_RAND)
- return (long)rand();
+ return (long)rand();
#else
- DEBUG(0,("Error - no random function available !\n"));
- exit(1);
+ DEBUG(0,("Error - no random function available !\n"));
+ exit(1);
#endif
}
@@ -474,12 +522,12 @@ long sys_random(void)
void sys_srandom(unsigned int seed)
{
#if defined(HAVE_SRANDOM)
- srandom(seed);
+ srandom(seed);
#elif defined(HAVE_SRAND)
- srand(seed);
+ srand(seed);
#else
- DEBUG(0,("Error - no srandom function available !\n"));
- exit(1);
+ DEBUG(0,("Error - no srandom function available !\n"));
+ exit(1);
#endif
}
@@ -490,10 +538,10 @@ void sys_srandom(unsigned int seed)
int groups_max(void)
{
#if defined(SYSCONF_SC_NGROUPS_MAX)
- int ret = sysconf(_SC_NGROUPS_MAX);
- return (ret == -1) ? NGROUPS_MAX : ret;
+ int ret = sysconf(_SC_NGROUPS_MAX);
+ return (ret == -1) ? NGROUPS_MAX : ret;
#else
- return NGROUPS_MAX;
+ return NGROUPS_MAX;
#endif
}
@@ -504,47 +552,47 @@ int groups_max(void)
int sys_getgroups(int setlen, gid_t *gidset)
{
#if !defined(HAVE_BROKEN_GETGROUPS)
- return getgroups(setlen, gidset);
+ return getgroups(setlen, gidset);
#else
- GID_T gid;
- GID_T *group_list;
- int i, ngroups;
+ GID_T gid;
+ GID_T *group_list;
+ int i, ngroups;
- if(setlen == 0) {
- return getgroups(setlen, &gid);
- }
+ if(setlen == 0) {
+ return getgroups(setlen, &gid);
+ }
- /*
- * Broken case. We need to allocate a
- * GID_T array of size setlen.
- */
+ /*
+ * Broken case. We need to allocate a
+ * GID_T array of size setlen.
+ */
- if(setlen < 0) {
- errno = EINVAL;
- return -1;
- }
+ if(setlen < 0) {
+ errno = EINVAL;
+ return -1;
+ }
- if (setlen == 0)
- setlen = groups_max();
+ if (setlen == 0)
+ setlen = groups_max();
- if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
- DEBUG(0,("sys_getgroups: Malloc fail.\n"));
- return -1;
- }
+ if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
+ DEBUG(0,("sys_getgroups: Malloc fail.\n"));
+ return -1;
+ }
- if((ngroups = getgroups(setlen, group_list)) < 0) {
- int saved_errno = errno;
- free((char *)group_list);
- errno = saved_errno;
- return -1;
- }
+ if((ngroups = getgroups(setlen, group_list)) < 0) {
+ int saved_errno = errno;
+ SAFE_FREE(group_list);
+ errno = saved_errno;
+ return -1;
+ }
- for(i = 0; i < ngroups; i++)
- gidset[i] = (gid_t)group_list[i];
+ for(i = 0; i < ngroups; i++)
+ gidset[i] = (gid_t)group_list[i];
- free((char *)group_list);
- return ngroups;
+ SAFE_FREE(group_list);
+ return ngroups;
#endif /* HAVE_BROKEN_GETGROUPS */
}
@@ -558,42 +606,42 @@ int sys_getgroups(int setlen, gid_t *gidset)
int sys_setgroups(int setlen, gid_t *gidset)
{
#if !defined(HAVE_BROKEN_GETGROUPS)
- return setgroups(setlen, gidset);
+ return setgroups(setlen, gidset);
#else
- GID_T *group_list;
- int i ;
+ GID_T *group_list;
+ int i ;
- if (setlen == 0)
- return 0 ;
+ if (setlen == 0)
+ return 0 ;
- if (setlen < 0 || setlen > groups_max()) {
- errno = EINVAL;
- return -1;
- }
+ if (setlen < 0 || setlen > groups_max()) {
+ errno = EINVAL;
+ return -1;
+ }
- /*
- * Broken case. We need to allocate a
- * GID_T array of size setlen.
- */
+ /*
+ * Broken case. We need to allocate a
+ * GID_T array of size setlen.
+ */
- if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
- DEBUG(0,("sys_setgroups: Malloc fail.\n"));
- return -1;
- }
+ if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
+ DEBUG(0,("sys_setgroups: Malloc fail.\n"));
+ return -1;
+ }
- for(i = 0; i < setlen; i++)
- group_list[i] = (GID_T) gidset[i];
-
- if(setgroups(setlen, group_list) != 0) {
- int saved_errno = errno;
- free((char *)group_list);
- errno = saved_errno;
- return -1;
- }
+ for(i = 0; i < setlen; i++)
+ group_list[i] = (GID_T) gidset[i];
+
+ if(setgroups(setlen, group_list) != 0) {
+ int saved_errno = errno;
+ SAFE_FREE(group_list);
+ errno = saved_errno;
+ return -1;
+ }
- free((char *)group_list);
- return 0 ;
+ SAFE_FREE(group_list);
+ return 0 ;
#endif /* HAVE_BROKEN_GETGROUPS */
}
@@ -726,6 +774,7 @@ struct passwd *sys_getpwuid(uid_t uid)
return setup_pwret(getpwuid(uid));
}
+#if 0 /* NOT CURRENTLY USED - JRA */
/**************************************************************************
The following are the UNICODE versions of *all* system interface functions
called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
@@ -895,6 +944,7 @@ SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
return &retval;
}
+#endif /* NOT CURRENTLY USED - JRA */
/**************************************************************************
Extract a command into an arg list. Uses a static pstring for storage.
@@ -1056,7 +1106,7 @@ int sys_popen(const char *command)
*/
close (child_end);
- free((char *)argl);
+ SAFE_FREE(argl);
/* Link into popen_chain. */
entry->next = popen_chain;
@@ -1067,10 +1117,8 @@ int sys_popen(const char *command)
err_exit:
- if(entry)
- free((char *)entry);
- if(argl)
- free((char *)argl);
+ SAFE_FREE(entry);
+ SAFE_FREE(argl);
close(pipe_fds[0]);
close(pipe_fds[1]);
return -1;
@@ -1079,6 +1127,7 @@ err_exit:
/**************************************************************************
Wrapper for pclose. Modified from the glibc sources.
****************************************************************************/
+
int sys_pclose(int fd)
{
int wstatus;
@@ -1110,7 +1159,7 @@ int sys_pclose(int fd)
wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
} while (wait_pid == -1 && errno == EINTR);
- free((char *)entry);
+ SAFE_FREE(entry);
if (wait_pid == -1)
return -1;
@@ -1147,3 +1196,12 @@ int sys_dlclose (void *handle)
return 0;
#endif
}
+
+const char *sys_dlerror(void)
+{
+#ifdef HAVE_LIBDL
+ return dlerror();
+#else
+ return NULL;
+#endif
+}
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index cfd130e888b..fb5c3495fe4 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -62,7 +62,7 @@ void *talloc(TALLOC_CTX *t, size_t size)
tc = malloc(sizeof(*tc));
if (!tc) {
- free(p);
+ SAFE_FREE(p);
return NULL;
}
@@ -79,6 +79,7 @@ void *talloc(TALLOC_CTX *t, size_t size)
void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
{
struct talloc_chunk *tc;
+ void *new_ptr;
/* size zero is equivalent to free() */
if (size == 0)
@@ -90,13 +91,13 @@ void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
for (tc=t->list; tc; tc=tc->next) {
if (tc->ptr == ptr) {
- ptr = Realloc(ptr, size);
- if (ptr) {
+ new_ptr = Realloc(ptr, size);
+ if (new_ptr) {
t->total_alloc_size += (size - tc->size);
tc->size = size;
- tc->ptr = ptr;
+ tc->ptr = new_ptr;
}
- return ptr;
+ return new_ptr;
}
}
return NULL;
@@ -112,8 +113,8 @@ void talloc_destroy_pool(TALLOC_CTX *t)
while (t->list) {
c = t->list->next;
- if (t->list->ptr) free(t->list->ptr);
- free(t->list);
+ SAFE_FREE(t->list->ptr);
+ SAFE_FREE(t->list);
t->list = c;
}
@@ -128,7 +129,7 @@ void talloc_destroy(TALLOC_CTX *t)
return;
talloc_destroy_pool(t);
memset(t, 0, sizeof(*t));
- free(t);
+ SAFE_FREE(t);
}
/* return the current total size of the pool. */
diff --git a/source/lib/time.c b/source/lib/time.c
index bf58cdd018a..43c8ca67dd4 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -27,11 +27,8 @@
*/
-int serverzone=0;
int extra_time_offset = 0;
-extern int DEBUGLEVEL;
-
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
@@ -107,21 +104,61 @@ static int TimeZone(time_t t)
}
+static BOOL done_serverzone_init;
-/*******************************************************************
-init the time differences
-********************************************************************/
-void TimeInit(void)
+/* Return the smb serverzone value */
+
+static int get_serverzone(void)
{
- serverzone = TimeZone(time(NULL));
+ static int serverzone;
- if ((serverzone % 60) != 0) {
- DEBUG(1,("WARNING: Your timezone is not a multiple of 1 minute.\n"));
- }
+ if (!done_serverzone_init) {
+ serverzone = TimeZone(time(NULL));
+
+ if ((serverzone % 60) != 0) {
+ DEBUG(1,("WARNING: Your timezone is not a multiple of 1 minute.\n"));
+ }
+
+ DEBUG(4,("Serverzone is %d\n",serverzone));
+
+ done_serverzone_init = True;
+ }
- DEBUG(4,("Serverzone is %d\n",serverzone));
+ return serverzone;
}
+/* Re-read the smb serverzone value */
+
+static struct timeval start_time_hires;
+
+void TimeInit(void)
+{
+ done_serverzone_init = False;
+ get_serverzone();
+ /* Save the start time of this process. */
+ if (start_time_hires.tv_sec == 0 && start_time_hires.tv_usec == 0)
+ GetTimeOfDay(&start_time_hires);
+}
+
+/**********************************************************************
+ Return a timeval struct of the uptime of this process. As TimeInit is
+ done before a daemon fork then this is the start time from the parent
+ daemon start. JRA.
+***********************************************************************/
+
+void get_process_uptime(struct timeval *ret_time)
+{
+ struct timeval time_now_hires;
+
+ GetTimeOfDay(&time_now_hires);
+ ret_time->tv_sec = time_now_hires.tv_sec - start_time_hires.tv_sec;
+ ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;
+ if (time_now_hires.tv_usec < start_time_hires.tv_usec) {
+ ret_time->tv_sec -= 1;
+ ret_time->tv_usec = 1000000 + (time_now_hires.tv_usec - start_time_hires.tv_usec);
+ } else
+ ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;
+}
/*******************************************************************
return the same value as TimeZone, but it should be more efficient.
@@ -157,14 +194,12 @@ static int TimeZoneFaster(time_t t)
sizeof(dst_table[0])*(i+1));
if (!tdt) {
DEBUG(0,("TimeZoneFaster: out of memory!\n"));
- if (dst_table)
- free(dst_table);
+ SAFE_FREE(dst_table);
table_size = 0;
} else {
-
dst_table = tdt;
table_size++;
-
+
dst_table[i].zone = zone;
dst_table[i].start = dst_table[i].end = t;
@@ -288,12 +323,56 @@ time_t nt_time_to_unix(NTTIME *nt)
ret = (time_t)(d+0.5);
/* this takes us from kludge-GMT to real GMT */
- ret -= serverzone;
+ ret -= get_serverzone();
ret += LocTimeDiff(ret);
return(ret);
}
+/****************************************************************************
+convert a NTTIME structure to a time_t
+It's originally in "100ns units"
+
+this is an absolute version of the one above.
+By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970
+if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
+****************************************************************************/
+time_t nt_time_to_unix_abs(NTTIME *nt)
+{
+ double d;
+ time_t ret;
+ /* The next two lines are a fix needed for the
+ broken SCO compiler. JRA. */
+ time_t l_time_min = TIME_T_MIN;
+ time_t l_time_max = TIME_T_MAX;
+
+ if (nt->high == 0)
+ return(0);
+
+ if (nt->high==0x80000000 && nt->low==0)
+ return -1;
+
+ /* reverse the time */
+ /* it's a negative value, turn it to positive */
+ nt->high=~nt->high;
+ nt->low=~nt->low;
+
+ d = ((double)nt->high)*4.0*(double)(1<<30);
+ d += (nt->low&0xFFF00000);
+ d *= 1.0e-7;
+
+ if (!(l_time_min <= d && d <= l_time_max))
+ return(0);
+
+ ret = (time_t)(d+0.5);
+
+ /* this takes us from kludge-GMT to real GMT */
+ ret -= get_serverzone();
+ ret += LocTimeDiff(ret);
+
+ return(ret);
+}
+
/****************************************************************************
@@ -335,7 +414,7 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
}
/* this converts GMT to kludge-GMT */
- t -= LocTimeDiff(t) - serverzone;
+ t -= LocTimeDiff(t) - get_serverzone();
d = (double)(t);
d += TIME_FIXUP_CONSTANT;
@@ -345,6 +424,50 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
}
+/****************************************************************************
+convert a time_t to a NTTIME structure
+
+this is an absolute version of the one above.
+By absolute I mean, it doesn't adjust from 1/1/1970 to 1/1/1601
+if the nttime_t was 5 seconds, the NTTIME is 5 seconds. JFM
+****************************************************************************/
+void unix_to_nt_time_abs(NTTIME *nt, time_t t)
+{
+ double d;
+
+ if (t==0) {
+ nt->low = 0;
+ nt->high = 0;
+ return;
+ }
+
+ if (t == TIME_T_MAX) {
+ nt->low = 0xffffffff;
+ nt->high = 0x7fffffff;
+ return;
+ }
+
+ if (t == -1) {
+ /* that's what NT uses for infinite */
+ nt->low = 0x0;
+ nt->high = 0x80000000;
+ return;
+ }
+
+ /* this converts GMT to kludge-GMT */
+ t -= LocTimeDiff(t) - get_serverzone();
+
+ d = (double)(t);
+ d *= 1.0e7;
+
+ nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
+ nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
+
+ /* convert to a negative value */
+ nt->high=~nt->high;
+ nt->low=~nt->low;
+}
+
/****************************************************************************
take an NTTIME structure, containing high / low time. convert to unix time.
@@ -616,3 +739,12 @@ time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs)
return ret;
}
+/****************************************************************************
+initialise an NTTIME to -1, which means "unknown" or "don't expire"
+****************************************************************************/
+
+void init_nt_time(NTTIME *nt)
+{
+ nt->high = 0x7FFFFFFF;
+ nt->low = 0xFFFFFFFF;
+}
diff --git a/source/lib/username.c b/source/lib/username.c
index 5cd57e0ae50..7ad2341d627 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -3,6 +3,7 @@
Version 1.9.
Username handling
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1997-2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,26 +21,68 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
/* internal functions */
static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (char *), int N);
static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
+/*****************************************************************
+ Check if a user or group name is local (this is a *local* name for
+ *local* people, there's nothing for you here...).
+*****************************************************************/
+
+BOOL name_is_local(const char *name)
+{
+ return !strchr(name, *lp_winbind_separator());
+}
+
/****************************************************************************
Get a users home directory.
****************************************************************************/
char *get_user_home_dir(char *user)
{
- static struct passwd *pass;
-
- pass = Get_Pwnam(user, False);
+ static struct passwd *pass;
- if (!pass) return(NULL);
- return(pass->pw_dir);
+ pass = Get_Pwnam(user, False);
+ if (!pass)
+ return(NULL);
+ /* Return home directory from struct passwd. */
+ return(pass->pw_dir);
}
+/****************************************************************************
+ Get a users home service directory.
+****************************************************************************/
+
+char *get_user_service_home_dir(char *user)
+{
+ static struct passwd *pass;
+ int snum;
+
+ /* Ensure the user exists. */
+
+ pass = Get_Pwnam(user, False);
+ if (!pass)
+ return(NULL);
+
+ /* If a path is specified in [homes] then use it instead of the
+ user's home directory from struct passwd. */
+
+ if ((snum = lp_servicenumber(HOMES_NAME)) != -1) {
+ static pstring home_dir;
+
+ pstrcpy(home_dir, lp_pathname(snum));
+ standard_sub_home(snum, user, home_dir);
+
+ if (home_dir[0])
+ return home_dir;
+ }
+
+ /* Return home directory from struct passwd. */
+
+ return(pass->pw_dir);
+}
/*******************************************************************
Map a username from a dos name to a unix name by looking in the username
@@ -54,120 +97,119 @@ char *get_user_home_dir(char *user)
BOOL map_username(char *user)
{
- static BOOL initialised=False;
- static fstring last_from,last_to;
- FILE *f;
- char *mapfile = lp_username_map();
- char *s;
- pstring buf;
- BOOL mapped_user = False;
-
- if (!*user)
- return False;
-
- if (!*mapfile)
- return False;
-
- if (!initialised) {
- *last_from = *last_to = 0;
- initialised = True;
- }
-
- if (strequal(user,last_to))
- return False;
-
- if (strequal(user,last_from)) {
- DEBUG(3,("Mapped user %s to %s\n",user,last_to));
- fstrcpy(user,last_to);
- return True;
- }
+ static BOOL initialised=False;
+ static fstring last_from,last_to;
+ FILE *f;
+ char *mapfile = lp_username_map();
+ char *s;
+ pstring buf;
+ BOOL mapped_user = False;
+
+ if (!*user)
+ return False;
+
+ if (!*mapfile)
+ return False;
+
+ if (!initialised) {
+ *last_from = *last_to = 0;
+ initialised = True;
+ }
+
+ if (strequal(user,last_to))
+ return False;
+
+ if (strequal(user,last_from)) {
+ DEBUG(3,("Mapped user %s to %s\n",user,last_to));
+ fstrcpy(user,last_to);
+ return True;
+ }
- f = sys_fopen(mapfile,"r");
- if (!f) {
- DEBUG(0,("can't open username map %s. Error %s\n",mapfile, strerror(errno) ));
- return False;
- }
-
- DEBUG(4,("Scanning username map %s\n",mapfile));
-
- while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
- char *unixname = s;
- char *dosname = strchr(unixname,'=');
- BOOL return_if_mapped = False;
-
- if (!dosname)
- continue;
-
- *dosname++ = 0;
-
- while (isspace(*unixname))
- unixname++;
- if ('!' == *unixname) {
- return_if_mapped = True;
- unixname++;
- while (*unixname && isspace(*unixname))
- unixname++;
- }
+ f = sys_fopen(mapfile,"r");
+ if (!f) {
+ DEBUG(0,("can't open username map %s. Error %s\n",mapfile, strerror(errno) ));
+ return False;
+ }
+
+ DEBUG(4,("Scanning username map %s\n",mapfile));
+
+ while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
+ char *unixname = s;
+ char *dosname = strchr(unixname,'=');
+ BOOL return_if_mapped = False;
+
+ if (!dosname)
+ continue;
+
+ *dosname++ = 0;
+
+ while (isspace((int)*unixname))
+ unixname++;
+ if ('!' == *unixname) {
+ return_if_mapped = True;
+ unixname++;
+
+ while (*unixname && isspace((int)*unixname))
+ unixname++;
+ }
- if (!*unixname || strchr("#;",*unixname))
- continue;
-
- {
- int l = strlen(unixname);
- while (l && isspace(unixname[l-1])) {
- unixname[l-1] = 0;
- l--;
- }
- }
-
- if (strchr(dosname,'*') || user_in_list(user,dosname)) {
- DEBUG(3,("Mapped user %s to %s\n",user,unixname));
- mapped_user = True;
- fstrcpy(last_from,user);
- sscanf(unixname,"%s",user);
- fstrcpy(last_to,user);
- if(return_if_mapped) {
- fclose(f);
- return True;
- }
- }
- }
-
- fclose(f);
-
- /*
- * Setup the last_from and last_to as an optimization so
- * that we don't scan the file again for the same user.
- */
- fstrcpy(last_from,user);
- fstrcpy(last_to,user);
-
- return mapped_user;
+ if (!*unixname || strchr("#;",*unixname))
+ continue;
+
+ {
+ int l = strlen(unixname);
+ while (l && isspace((int)unixname[l-1])) {
+ unixname[l-1] = 0;
+ l--;
+ }
+ }
+
+ if (strchr(dosname,'*') || user_in_list(user,dosname)) {
+ DEBUG(3,("Mapped user %s to %s\n",user,unixname));
+ mapped_user = True;
+ fstrcpy(last_from,user);
+ sscanf(unixname,"%s",user);
+ fstrcpy(last_to,user);
+ if(return_if_mapped) {
+ fclose(f);
+ return True;
+ }
+ }
+ }
+
+ fclose(f);
+
+ /*
+ * Setup the last_from and last_to as an optimization so
+ * that we don't scan the file again for the same user.
+ */
+ fstrcpy(last_from,user);
+ fstrcpy(last_to,user);
+
+ return mapped_user;
}
/****************************************************************************
- Get_Pwnam wrapper
+ Get_Pwnam wrapper.
****************************************************************************/
static struct passwd *_Get_Pwnam(char *s)
{
- struct passwd *ret;
+ struct passwd *ret;
- ret = sys_getpwnam(s);
- if (ret) {
+ ret = sys_getpwnam(s);
+ if (ret) {
#ifdef HAVE_GETPWANAM
- struct passwd_adjunct *pwret;
- pwret = getpwanam(s);
- if (pwret && pwret->pwa_passwd) {
- pstrcpy(ret->pw_passwd,pwret->pwa_passwd);
- }
+ struct passwd_adjunct *pwret;
+ pwret = getpwanam(s);
+ if (pwret && pwret->pwa_passwd)
+ pstrcpy(ret->pw_passwd,pwret->pwa_passwd);
#endif
- }
+ }
- return(ret);
+ return(ret);
}
-
/****************************************************************************
A wrapper for getpwnam(). The following variations are tried...
- in all lower case
@@ -188,8 +230,7 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
/* make a few copies to work with */
fstrcpy(orig_username, user);
- if (!allow_change)
- {
+ if (!allow_change) {
/* allow_change was False, so make a copy and temporarily
assign the char* user to the temp copy */
fstrcpy(user2,user);
@@ -208,8 +249,7 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
/* try as transmitted, but only if the original username
gives us a different case */
- if (strcmp(user, orig_username) != 0)
- {
+ if (strcmp(user, orig_username) != 0) {
ret = _Get_Pwnam(orig_username);
if (ret) {
if (allow_change)
@@ -224,8 +264,7 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
strupper(user);
dos_to_unix(user, True);
- if (strcmp(user, orig_username) != 0)
- {
+ if (strcmp(user, orig_username) != 0) {
ret = _Get_Pwnam(user);
if (ret)
return(ret);
@@ -251,24 +290,24 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
static BOOL user_in_netgroup_list(char *user,char *ngname)
{
#ifdef HAVE_NETGROUP
- static char *mydomain = NULL;
- if (mydomain == NULL)
- yp_get_default_domain(&mydomain);
-
- if(mydomain == NULL) {
- DEBUG(5,("Unable to get default yp domain\n"));
- } else {
- DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
- user, mydomain, ngname));
- DEBUG(5,("innetgr is %s\n",
- innetgr(ngname, NULL, user, mydomain)
- ? "True" : "False"));
-
- if (innetgr(ngname, NULL, user, mydomain))
- return (True);
- }
+ static char *mydomain = NULL;
+ if (mydomain == NULL)
+ yp_get_default_domain(&mydomain);
+
+ if(mydomain == NULL) {
+ DEBUG(5,("Unable to get default yp domain\n"));
+ return False;
+ }
+
+ DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
+ user, mydomain, ngname));
+ DEBUG(5,("innetgr is %s\n", innetgr(ngname, NULL, user, mydomain)
+ ? "True" : "False"));
+
+ if (innetgr(ngname, NULL, user, mydomain))
+ return (True);
#endif /* HAVE_NETGROUP */
- return False;
+ return False;
}
/****************************************************************************
@@ -327,13 +366,13 @@ failed with error %s\n", strerror(errno) ));
}
*winbind_answered = True;
- safe_free(groups);
+ SAFE_FREE(groups);
return ret;
err:
*winbind_answered = False;
- safe_free(groups);
+ SAFE_FREE(groups);
return False;
}
@@ -341,11 +380,11 @@ failed with error %s\n", strerror(errno) ));
Check if a user is in a UNIX group.
****************************************************************************/
-static BOOL user_in_unix_group_list(char *user,char *gname)
+static BOOL user_in_unix_group_list(char *user,const char *gname)
{
- struct group *gptr;
- char **member;
struct passwd *pass = Get_Pwnam(user,False);
+ struct sys_userlist *user_list;
+ struct sys_userlist *member;
DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n", user, gname));
@@ -355,27 +394,28 @@ static BOOL user_in_unix_group_list(char *user,char *gname)
*/
if (pass) {
- gptr = getgrgid(pass->pw_gid);
- if (gptr && strequal(gptr->gr_name,gname)) {
+ if (strequal(gname, gidtoname(pass->pw_gid))) {
DEBUG(10,("user_in_unix_group_list: group %s is primary group.\n", gname ));
return True;
}
}
- if ((gptr = (struct group *)getgrnam(gname)) == NULL) {
+ user_list = get_users_in_group(gname);
+ if (user_list == NULL) {
DEBUG(10,("user_in_unix_group_list: no such group %s\n", gname ));
return False;
}
-
- member = gptr->gr_mem;
- while (member && *member) {
- DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n", user, *member ));
- if (strequal(*member,user)) {
+
+ for (member = user_list; member; member = member->next) {
+ DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n",
+ user, member->unix_name ));
+ if (strequal(member->unix_name,user)) {
+ free_userlist(user_list);
return(True);
}
- member++;
}
+ free_userlist(user_list);
return False;
}
@@ -386,12 +426,15 @@ static BOOL user_in_unix_group_list(char *user,char *gname)
BOOL user_in_group_list(char *user,char *gname)
{
BOOL winbind_answered = False;
- BOOL ret = user_in_winbind_group_list(user, gname, &winbind_answered);
+ BOOL ret;
- if (winbind_answered)
- return ret;
+ ret = user_in_winbind_group_list(user, gname, &winbind_answered);
+ if (!winbind_answered)
+ ret = user_in_unix_group_list(user, gname);
- return user_in_unix_group_list(user, gname);
+ if (ret)
+ DEBUG(10,("user_in_group_list: user |%s| is in group |%s|\n", user, gname));
+ return ret;
}
/****************************************************************************
@@ -401,73 +444,99 @@ BOOL user_in_group_list(char *user,char *gname)
BOOL user_in_list(char *user,char *list)
{
- pstring tok;
- char *p=list;
-
- DEBUG(10,("user_in_list: checking user %s in list %s\n", user, list));
-
- while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
- /*
- * Check raw username.
- */
- if (strequal(user,tok))
- return(True);
-
- /*
- * Now check to see if any combination
- * of UNIX and netgroups has been specified.
- */
-
- if(*tok == '@') {
- /*
- * Old behaviour. Check netgroup list
- * followed by UNIX list.
- */
- if(user_in_netgroup_list(user,&tok[1]))
- return True;
- if(user_in_group_list(user,&tok[1]))
- return True;
- } else if (*tok == '+') {
-
- if(tok[1] == '&') {
- /*
- * Search UNIX list followed by netgroup.
- */
- if(user_in_group_list(user,&tok[2]))
- return True;
- if(user_in_netgroup_list(user,&tok[2]))
- return True;
-
- } else {
-
- /*
- * Just search UNIX list.
- */
-
- if(user_in_group_list(user,&tok[1]))
- return True;
- }
-
- } else if (*tok == '&') {
-
- if(tok[1] == '+') {
- /*
- * Search netgroup list followed by UNIX list.
- */
- if(user_in_netgroup_list(user,&tok[2]))
- return True;
- if(user_in_group_list(user,&tok[2]))
- return True;
- } else {
- /*
- * Just search netgroup list.
- */
- if(user_in_netgroup_list(user,&tok[1]))
- return True;
- }
- }
- }
- return(False);
+ pstring tok;
+ char *p=list;
+
+ DEBUG(10,("user_in_list: checking user %s in list %s\n", user, list));
+
+ while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
+
+ DEBUG(10,("user_in_list: checking user |%s| in group |%s|\n", user, tok));
+
+ /*
+ * Check raw username.
+ */
+ if (strequal(user,tok))
+ return(True);
+
+ /*
+ * Now check to see if any combination
+ * of UNIX and netgroups has been specified.
+ */
+
+ if(*tok == '@') {
+ /*
+ * Old behaviour. Check netgroup list
+ * followed by UNIX list.
+ */
+ if(user_in_netgroup_list(user,&tok[1]))
+ return True;
+ if(user_in_group_list(user,&tok[1]))
+ return True;
+ } else if (*tok == '+') {
+
+ if(tok[1] == '&') {
+ /*
+ * Search UNIX list followed by netgroup.
+ */
+ if(user_in_group_list(user,&tok[2]))
+ return True;
+ if(user_in_netgroup_list(user,&tok[2]))
+ return True;
+
+ } else {
+
+ /*
+ * Just search UNIX list.
+ */
+
+ if(user_in_group_list(user,&tok[1]))
+ return True;
+ }
+
+ } else if (*tok == '&') {
+
+ if(tok[1] == '+') {
+ /*
+ * Search netgroup list followed by UNIX list.
+ */
+ if(user_in_netgroup_list(user,&tok[2]))
+ return True;
+ if(user_in_group_list(user,&tok[2]))
+ return True;
+ } else {
+ /*
+ * Just search netgroup list.
+ */
+ if(user_in_netgroup_list(user,&tok[1]))
+ return True;
+ }
+ } else if (!name_is_local(tok)) {
+ /*
+ * If user name did not match and token is not
+ * a unix group and the token has a winbind separator in the
+ * name then see if it is a Windows group.
+ */
+
+ DOM_SID g_sid;
+ enum SID_NAME_USE name_type;
+ BOOL winbind_answered = False;
+ BOOL ret;
+
+ /* Check to see if name is a Windows group */
+ if (winbind_lookup_name(tok, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+
+ /* Check if user name is in the Windows group */
+ ret = user_in_winbind_group_list(user, tok, &winbind_answered);
+
+ if (winbind_answered && ret == True) {
+ DEBUG(10,("user_in_list: user |%s| is in group |%s|\n", user, tok));
+ return ret;
+ }
+ }
+ }
+ }
+ return(False);
}
/* The functions below have been taken from password.c and slightly modified */
@@ -481,28 +550,24 @@ BOOL user_in_list(char *user,char *list)
static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(char *),int N)
{
- ssize_t len = (ssize_t)strlen(s);
- int i;
- struct passwd *ret;
-
-#ifdef PASSWORD_LENGTH
- len = MIN(len,PASSWORD_LENGTH);
-#endif
-
- if (N <= 0 || offset >= len)
- return(fn(s));
-
- for (i=offset;i<(len-(N-1));i++) {
- char c = s[i];
- if (!islower(c))
- continue;
- s[i] = toupper(c);
- ret = uname_string_combinations2(s,i+1,fn,N-1);
- if(ret)
- return(ret);
- s[i] = c;
- }
- return(NULL);
+ ssize_t len = (ssize_t)strlen(s);
+ int i;
+ struct passwd *ret;
+
+ if (N <= 0 || offset >= len)
+ return(fn(s));
+
+ for (i=offset;i<(len-(N-1));i++) {
+ char c = s[i];
+ if (!islower((int)c))
+ continue;
+ s[i] = toupper(c);
+ ret = uname_string_combinations2(s,i+1,fn,N-1);
+ if(ret)
+ return(ret);
+ s[i] = c;
+ }
+ return(NULL);
}
/****************************************************************************
@@ -515,15 +580,15 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(char *),int N)
{
- int n;
- struct passwd *ret;
-
- for (n=1;n<=N;n++) {
- ret = uname_string_combinations2(s,0,fn,n);
- if(ret)
- return(ret);
- }
- return(NULL);
+ int n;
+ struct passwd *ret;
+
+ for (n=1;n<=N;n++) {
+ ret = uname_string_combinations2(s,0,fn,n);
+ if(ret)
+ return(ret);
+ }
+ return(NULL);
}
@@ -539,18 +604,19 @@ struct passwd *smb_getpwnam(char *user, BOOL allow_change)
extern pstring global_myname;
pw = Get_Pwnam(user, allow_change);
- if (pw) return pw;
+ 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.
+ */
- /* 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();
- if (!sep || !*sep) sep = "\\";
p = strchr(user,*sep);
- if (p &&
- strncasecmp(global_myname, user, strlen(global_myname))==0) {
+ if (p && strncasecmp(global_myname, user, strlen(global_myname))==0)
return Get_Pwnam(p+1, allow_change);
- }
return NULL;
}
diff --git a/source/lib/util.c b/source/lib/util.c
index 26ca621fde2..9aad4f976aa 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -4,6 +4,7 @@
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001
+ Copyright (C) Simo Sorce 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,10 +46,6 @@
#include <rpcsvc/nis.h>
-#else /* !WITH_NISPLUS_HOME */
-
-#include "rpcsvc/ypclnt.h"
-
#endif /* WITH_NISPLUS_HOME */
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
@@ -59,8 +56,6 @@ extern SSL *ssl;
extern int sslFd;
#endif /* WITH_SSL */
-extern int DEBUGLEVEL;
-
int Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
@@ -165,9 +160,9 @@ char *get_numlist(char *p, uint32 **num, int *count)
uint32 *tn;
tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
- if (tn == NULL) {
- if (*num)
- free(*num);
+ if (tn == NULL)
+ {
+ SAFE_FREE(*num);
return NULL;
} else
(*num) = tn;
@@ -312,10 +307,10 @@ void smb_setlen(char *buf,int len)
{
_smb_setlen(buf,len);
- CVAL(buf,4) = 0xFF;
- CVAL(buf,5) = 'S';
- CVAL(buf,6) = 'M';
- CVAL(buf,7) = 'B';
+ SCVAL(buf,4,0xFF);
+ SCVAL(buf,5,'S');
+ SCVAL(buf,6,'M');
+ SCVAL(buf,7,'B');
}
/*******************************************************************
@@ -325,7 +320,7 @@ int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
{
if (zero)
memset(buf + smb_size,'\0',num_words*2 + num_bytes);
- CVAL(buf,smb_wct) = num_words;
+ SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
@@ -334,20 +329,21 @@ int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
/*******************************************************************
setup only the byte count for a smb message
********************************************************************/
-void set_message_bcc(char *buf,int num_bytes)
+int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
+ return (smb_size + num_words*2 + num_bytes);
}
/*******************************************************************
setup only the byte count for a smb message, using the end of the
message as a marker
********************************************************************/
-void set_message_end(void *outbuf,void *end_ptr)
+int set_message_end(void *outbuf,void *end_ptr)
{
- set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
+ return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
}
/*******************************************************************
@@ -442,7 +438,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
memcpy(buf+1,mask2,MIN(strlen(mask2),11));
memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
- CVAL(buf,21) = mode;
+ SCVAL(buf,21,mode);
put_dos_date(buf,22,date);
SSVAL(buf,26,size & 0xFFFF);
SSVAL(buf,28,(size >> 16)&0xFFFF);
@@ -513,44 +509,55 @@ int set_blocking(int fd, BOOL set)
Transfer some data between two fd's.
****************************************************************************/
+#ifndef TRANSFER_BUF_SIZE
+#define TRANSFER_BUF_SIZE 65536
+#endif
+
ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
ssize_t (*write_fn)(int, const void *, size_t))
{
- static char buf[16384];
+ char *buf;
size_t total = 0;
ssize_t read_ret;
- size_t write_total = 0;
- ssize_t write_ret;
+ ssize_t write_ret;
+ size_t num_to_read_thistime;
+ size_t num_written = 0;
+
+ if ((buf = malloc(TRANSFER_BUF_SIZE)) == NULL)
+ return -1;
while (total < n) {
- size_t num_to_read_thistime = MIN((n - total), sizeof(buf));
+ num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
- read_ret = (*read_fn)(infd, buf + total, num_to_read_thistime);
+ read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
if (read_ret == -1) {
DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
+ SAFE_FREE(buf);
return -1;
}
if (read_ret == 0)
break;
- write_total = 0;
+ num_written = 0;
- while (write_total < read_ret) {
- write_ret = (*write_fn)(outfd,buf + total, read_ret);
+ while (num_written < read_ret) {
+ write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
if (write_ret == -1) {
DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
+ SAFE_FREE(buf);
return -1;
}
if (write_ret == 0)
return (ssize_t)total;
- write_total += (size_t)write_ret;
+ num_written += (size_t)write_ret;
}
total += (size_t)read_ret;
}
+ SAFE_FREE(buf);
return (ssize_t)total;
}
@@ -578,7 +585,7 @@ void msleep(int t)
FD_ZERO(&fds);
errno = 0;
- sys_select_intr(0,&fds,&tval);
+ sys_select_intr(0,&fds,NULL,NULL,&tval);
GetTimeOfDay(&t2);
tdiff = TvalDiff(&t1,&t2);
@@ -639,8 +646,7 @@ void *Realloc(void *p,size_t size)
void *ret=NULL;
if (size == 0) {
- if (p)
- free(p);
+ SAFE_FREE(p);
DEBUG(5,("Realloc asked for 0 bytes\n"));
return NULL;
}
@@ -658,12 +664,13 @@ void *Realloc(void *p,size_t size)
/****************************************************************************
Free memory, checks for NULL.
+use directly SAFE_FREE()
+exist only because we need to pass a function pointer somewhere --SSS
****************************************************************************/
void safe_free(void *p)
{
- if (p != NULL)
- free(p);
+ SAFE_FREE(p);
}
/****************************************************************************
@@ -744,7 +751,7 @@ BOOL is_ipaddress(const char *str)
interpret an internet address or name into an IP address in 4 byte form
****************************************************************************/
-uint32 interpret_addr(char *str)
+uint32 interpret_addr(const char *str)
{
struct hostent *hp;
uint32 res;
@@ -777,7 +784,7 @@ uint32 interpret_addr(char *str)
/*******************************************************************
a convenient addition to interpret_addr()
******************************************************************/
-struct in_addr *interpret_addr2(char *str)
+struct in_addr *interpret_addr2(const char *str)
{
static struct in_addr ret;
uint32 a = interpret_addr(str);
@@ -972,7 +979,8 @@ char *uidtoname(uid_t uid)
return name;
pass = sys_getpwuid(uid);
- if (pass) return(pass->pw_name);
+ if (pass)
+ return(pass->pw_name);
slprintf(name, sizeof(name) - 1, "%d",(int)uid);
return(name);
}
@@ -991,7 +999,8 @@ char *gidtoname(gid_t gid)
return name;
grp = getgrgid(gid);
- if (grp) return(grp->gr_name);
+ if (grp)
+ return(grp->gr_name);
slprintf(name,sizeof(name) - 1, "%d",(int)gid);
return(name);
}
@@ -1245,13 +1254,11 @@ routine to free a namearray.
void free_namearray(name_compare_entry *name_array)
{
- if(name_array == 0)
+ if(name_array == NULL)
return;
- if(name_array->name != NULL)
- free(name_array->name);
-
- free((char *)name_array);
+ SAFE_FREE(name_array->name);
+ SAFE_FREE(name_array);
}
/****************************************************************************
@@ -1326,6 +1333,48 @@ BOOL is_myname(char *s)
return(ret);
}
+BOOL is_myname_or_ipaddr(char *s)
+{
+ char *ptr;
+ pstring nbname;
+
+ /* optimize for the common case */
+ if (strequal(s, global_myname))
+ return True;
+
+ /* maybe its an IP address? */
+ if (is_ipaddress(s))
+ {
+ struct iface_struct nics[MAX_INTERFACES];
+ int i, n;
+ uint32 ip;
+
+ ip = interpret_addr(s);
+ if ((ip==0) || (ip==0xffffffff))
+ return False;
+
+ n = get_interfaces(nics, MAX_INTERFACES);
+ for (i=0; i<n; i++) {
+ if (ip == nics[i].ip.s_addr)
+ return True;
+ }
+ }
+
+ /* check for an alias */
+ ptr = lp_netbios_aliases();
+ while ( next_token(&ptr, nbname, NULL, sizeof(nbname)) )
+ {
+ if (StrCaseCmp(s, nbname) == 0)
+ return True;
+ }
+
+
+ /* no match */
+ return False;
+
+}
+
+
/*******************************************************************
set the horrid remote_arch string based on an enum.
********************************************************************/
@@ -1500,7 +1549,7 @@ zero a memory area then free it. Used to catch bugs faster
void zero_free(void *p, size_t size)
{
memset(p, 0, size);
- free(p);
+ SAFE_FREE(p);
}
@@ -1648,6 +1697,44 @@ int smb_mkstemp(char *template)
}
/*****************************************************************
+ malloc that aborts with smb_panic on fail or zero size.
+ *****************************************************************/
+
+void *smb_xmalloc(size_t size)
+{
+ void *p;
+ if (size == 0)
+ smb_panic("smb_xmalloc: called with zero size.\n");
+ if ((p = malloc(size)) == NULL)
+ smb_panic("smb_xmalloc: malloc fail.\n");
+ return p;
+}
+
+/*****************************************************************
+ Memdup with smb_panic on fail.
+ *****************************************************************/
+
+void *xmemdup(const void *p, size_t size)
+{
+ void *p2;
+ p2 = smb_xmalloc(size);
+ memcpy(p2, p, size);
+ return p2;
+}
+
+/*****************************************************************
+ strdup that aborts on malloc fail.
+ *****************************************************************/
+
+char *xstrdup(const char *s)
+{
+ char *s1 = strdup(s);
+ if (!s1)
+ smb_panic("xstrdup: malloc fail\n");
+ return s1;
+}
+
+/*****************************************************************
like strdup but for memory
*****************************************************************/
void *memdup(void *p, size_t size)
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index f3d8afde5d4..526e8b01568 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -19,8 +19,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static int gotalarm;
/***************************************************************
@@ -292,8 +290,7 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
t = (char *)Realloc(s,maxlen);
if (!t) {
DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
- if (s)
- free(s);
+ SAFE_FREE(s);
return(NULL);
} else
s = t;
@@ -325,7 +322,7 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
return(s);
case EOF:
if (len <= 0 && !s2)
- free(s);
+ SAFE_FREE(s);
return(len>0?s:NULL);
case ' ':
if (start_of_line)
@@ -342,8 +339,7 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
t = (char *)Realloc(s,maxlen);
if (!t) {
DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
- if (s)
- free(s);
+ SAFE_FREE(s);
return(NULL);
} else
s = t;
@@ -374,8 +370,7 @@ char *file_pload(char *syscmd, size_t *size)
if (!tp) {
DEBUG(0,("file_pload: failed to exand buffer!\n"));
close(fd);
- if (p)
- free(p);
+ SAFE_FREE(p);
return NULL;
} else
p = tp;
@@ -406,7 +401,7 @@ char *fd_load(int fd, size_t *size)
if (!p) return NULL;
if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
- free(p);
+ SAFE_FREE(p);
return NULL;
}
p[sbuf.st_size] = 0;
@@ -453,7 +448,7 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, BOOL convert
ret = (char **)malloc(sizeof(ret[0])*(i+2));
if (!ret) {
- free(p);
+ SAFE_FREE(p);
return NULL;
}
memset(ret, 0, sizeof(ret[0])*(i+2));
@@ -533,8 +528,8 @@ free lines loaded with file_lines_load
void file_lines_free(char **lines)
{
if (!lines) return;
- free(lines[0]);
- free(lines);
+ SAFE_FREE(lines[0]);
+ SAFE_FREE(lines);
}
diff --git a/source/lib/util_getent.c b/source/lib/util_getent.c
index 5c1652f6bf5..81b36effcb4 100644
--- a/source/lib/util_getent.c
+++ b/source/lib/util_getent.c
@@ -3,6 +3,7 @@
Version 3.0
Samba utility functions
Copyright (C) Simo Sorce 2001
+ Copyright (C) Jeremy Allison 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -66,7 +67,7 @@ struct sys_grent * getgrent_list(void)
grp = getgrent();
if (grp == NULL) {
endgrent();
- free(glist);
+ SAFE_FREE(glist);
return NULL;
}
@@ -130,19 +131,17 @@ void grent_free (struct sys_grent *glist)
while (glist) {
struct sys_grent *prev;
- if (glist->gr_name)
- free(glist->gr_name);
- if (glist->gr_passwd)
- free(glist->gr_passwd);
+ SAFE_FREE(glist->gr_name);
+ SAFE_FREE(glist->gr_passwd);
if (glist->gr_mem) {
int i;
for (i = 0; glist->gr_mem[i]; i++)
- free(glist->gr_mem[i]);
- free(glist->gr_mem);
+ SAFE_FREE(glist->gr_mem[i]);
+ SAFE_FREE(glist->gr_mem);
}
prev = glist;
glist = glist->next;
- free(prev);
+ SAFE_FREE(prev);
}
}
@@ -221,19 +220,94 @@ void pwent_free (struct sys_pwent *plist)
while (plist) {
struct sys_pwent *prev;
- if (plist->pw_name)
- free(plist->pw_name);
- if (plist->pw_passwd)
- free(plist->pw_passwd);
- if (plist->pw_gecos)
- free(plist->pw_gecos);
- if (plist->pw_dir)
- free(plist->pw_dir);
- if (plist->pw_shell)
- free(plist->pw_shell);
+ SAFE_FREE(plist->pw_name);
+ SAFE_FREE(plist->pw_passwd);
+ SAFE_FREE(plist->pw_gecos);
+ SAFE_FREE(plist->pw_dir);
+ SAFE_FREE(plist->pw_shell);
prev = plist;
plist = plist->next;
- free(prev);
+ SAFE_FREE(prev);
+ }
+}
+
+/****************************************************************
+ Add the individual group users onto the list.
+****************************************************************/
+
+static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp)
+{
+ size_t num_users, i;
+
+ /* Count the number of users. */
+ for (num_users = 0; grp->gr_mem[num_users]; num_users++)
+ ;
+
+ for (i = 0; i < num_users; i++) {
+ struct sys_userlist *entry = (struct sys_userlist *)malloc(sizeof(*entry));
+ size_t len = strlen(grp->gr_mem[i])+1;
+ if (entry == NULL) {
+ free_userlist(list_head);
+ return NULL;
+ }
+ entry->unix_name = (char *)malloc(len);
+ if (entry->unix_name == NULL) {
+ SAFE_FREE(entry);
+ free_userlist(list_head);
+ return NULL;
+ }
+ safe_strcpy(entry->unix_name, grp->gr_mem[i],len);
+ DLIST_ADD(list_head, entry);
+ }
+ return list_head;
+}
+
+/****************************************************************
+ Get the list of UNIX users in a group.
+ We have to enumerate the /etc/group file as some UNIX getgrnam()
+ calls won't do that for us (notably Tru64 UNIX).
+****************************************************************/
+
+struct sys_userlist *get_users_in_group(const char *gname)
+{
+ struct sys_userlist *list_head = NULL;
+ struct group *gptr;
+
+ /*
+ * If we're doing this via winbindd, don't do the
+ * entire group list enumeration as we know this is
+ * pointless (and slow).
+ */
+
+ if (strchr(gname,*lp_winbind_separator())) {
+ if ((gptr = (struct group *)getgrnam(gname)) == NULL)
+ return NULL;
+ return add_members_to_userlist(list_head, gptr);
+ }
+
+ setgrent();
+ while((gptr = getgrent()) != NULL) {
+ if (strequal(gname, gptr->gr_name)) {
+ list_head = add_members_to_userlist(list_head, gptr);
+ if (list_head == NULL)
+ return NULL;
+ }
+ }
+ endgrent();
+ return list_head;
+}
+
+/****************************************************************
+ Free list allocated above.
+****************************************************************/
+
+void free_userlist(struct sys_userlist *list_head)
+{
+ while (list_head) {
+ struct sys_userlist *old_head = list_head;
+ DLIST_REMOVE(list_head, list_head);
+ SAFE_FREE(old_head->unix_name);
+ SAFE_FREE(old_head);
}
}
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
index 860988aad57..b8dc43dede4 100644
--- a/source/lib/util_seaccess.c
+++ b/source/lib/util_seaccess.c
@@ -24,8 +24,6 @@
#include "nterr.h"
#include "sids.h"
-extern int DEBUGLEVEL;
-
/**********************************************************************************
Check if this ACE has a SID in common with the token.
**********************************************************************************/
@@ -35,7 +33,7 @@ static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
size_t i;
for (i = 0; i < token->num_sids; i++) {
- if (sid_equal(&ace->sid, &token->user_sids[i]))
+ if (sid_equal(&ace->trustee, &token->user_sids[i]))
return True;
}
@@ -47,7 +45,8 @@ 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, uint32 *status)
+static uint32 check_ace(SEC_ACE *ace, NT_USER_TOKEN *token, uint32 acc_desired,
+ NTSTATUS *status)
{
uint32 mask = ace->info.mask;
@@ -106,7 +105,9 @@ 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, uint32 desired, uint32 *status)
+static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *granted,
+ uint32 desired,
+ NTSTATUS *status)
{
uint32 acc_denied = 0;
uint32 acc_granted = 0;
@@ -202,7 +203,8 @@ void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
*****************************************************************************/
BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
- uint32 acc_desired, uint32 *acc_granted, uint32 *status)
+ uint32 acc_desired, uint32 *acc_granted,
+ NTSTATUS *status)
{
extern NT_USER_TOKEN anonymous_token;
size_t i;
@@ -220,8 +222,8 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
*acc_granted = 0;
DEBUG(10,("se_access_check: requested access %x, for NT token with %u entries and first sid %s.\n",
- (unsigned int)acc_desired, (unsigned int)token->num_sids,
- sid_to_string(sid_str, &token->user_sids[0])));
+ (unsigned int)acc_desired, (unsigned int)token->num_sids,
+ sid_to_string(sid_str, &token->user_sids[0])));
/*
* No security descriptor or security descriptor with no DACL
@@ -239,7 +241,7 @@ 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[0]) ));
+ 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",
@@ -266,7 +268,8 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
if (tmp_acc_desired & MAXIMUM_ALLOWED_ACCESS) {
tmp_acc_desired &= ~MAXIMUM_ALLOWED_ACCESS;
- return get_max_access( the_acl, token, acc_granted, tmp_acc_desired, status);
+ return get_max_access( the_acl, token, acc_granted, tmp_acc_desired,
+ status);
}
for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
@@ -274,14 +277,14 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
DEBUG(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->sid),
+ sid_to_string(sid_str, &ace->trustee),
(unsigned int) ace->info.mask,
(unsigned int)tmp_acc_desired ));
tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
- if (*status != NT_STATUS_OK) {
+ if (NT_STATUS_V(*status)) {
*acc_granted = 0;
- DEBUG(5,("se_access_check: ACE %u denied with status %x.\n", (unsigned int)i, (unsigned int)*status ));
+ DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, get_nt_error_msg(*status)));
return False;
}
}
@@ -385,10 +388,10 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
continue;
init_sec_access(&new_ace->info, ace->info.mask);
- init_sec_ace(new_ace, &ace->sid, ace->type,
+ init_sec_ace(new_ace, &ace->trustee, ace->type,
new_ace->info, new_flags);
- sid_to_string(sid_str, &ace->sid);
+ sid_to_string(sid_str, &ace->trustee);
DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
" inherited as %s:%d/0x%02x/0x%08x\n", sid_str,
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index 5b8bdb44c1b..c559647bf45 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -21,7 +21,6 @@
#ifndef AUTOCONF_TEST
#include "includes.h"
-extern int DEBUGLEVEL;
#else
/* we are running this code in autoconf test mode to see which type of setuid
function works */
@@ -48,6 +47,7 @@ extern int DEBUGLEVEL;
/* are we running as non-root? This is used by the regresison test code,
and potentially also for sites that want non-root smbd */
static uid_t initial_uid;
+static gid_t initial_gid;
/****************************************************************************
remember what uid we got started as - this allows us to run correctly
@@ -56,6 +56,23 @@ as non-root while catching trapdoor systems
void sec_init(void)
{
initial_uid = geteuid();
+ initial_gid = getegid();
+}
+
+/****************************************************************************
+some code (eg. winbindd) needs to know what uid we started as
+****************************************************************************/
+uid_t sec_initial_uid(void)
+{
+ return initial_uid;
+}
+
+/****************************************************************************
+some code (eg. winbindd, profiling shm) needs to know what gid we started as
+****************************************************************************/
+gid_t sec_initial_gid(void)
+{
+ return initial_gid;
}
/****************************************************************************
@@ -396,3 +413,11 @@ main()
exit(0);
}
#endif
+
+/****************************************************************************
+Check if we are setuid root. Used in libsmb and smbpasswd parinoia checks.
+****************************************************************************/
+BOOL is_setuid_root(void)
+{
+ return (geteuid() == (uid_t)0) && (getuid() != (uid_t)0);
+}
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 864d8a50d21..d9f7efe39b8 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -24,7 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
DOM_SID global_sam_sid;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -365,23 +364,30 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
Convert a string to a SID. Returns True on success, False on fail.
*****************************************************************/
-BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
{
pstring tok;
- char *p = sidstr;
+ char *p, *q;
/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
uint32 ia;
- memset((char *)sidout, '\0', sizeof(DOM_SID));
if (StrnCaseCmp( sidstr, "S-", 2)) {
DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
return False;
}
- p += 2;
+ memset((char *)sidout, '\0', sizeof(DOM_SID));
+
+ q = p = strdup(sidstr + 2);
+ if (p == NULL) {
+ DEBUG(0, ("string_to_sid: out of memory!\n"));
+ return False;
+ }
+
if (!next_token(&p, tok, "-", sizeof(tok))) {
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ SAFE_FREE(q);
return False;
}
@@ -390,6 +396,7 @@ BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
if (!next_token(&p, tok, "-", sizeof(tok))) {
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ SAFE_FREE(q);
return False;
}
@@ -417,6 +424,7 @@ BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
+ SAFE_FREE(q);
return True;
}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 9058cf9368c..4d9a405cb5d 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -28,8 +28,6 @@ extern SSL *ssl;
extern int sslFd;
#endif /* WITH_SSL */
-extern int DEBUGLEVEL;
-
/* the last IP received from */
struct in_addr lastip;
@@ -261,7 +259,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
FD_ZERO(&fds);
FD_SET(fd,&fds);
- selrtn = sys_select_intr(fd+1,&fds,&timeout);
+ selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
/* Check if error */
if(selrtn == -1) {
@@ -365,7 +363,7 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
FD_ZERO(&fds);
FD_SET(fd,&fds);
- selrtn = sys_select_intr(fd+1,&fds,&timeout);
+ selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
if(selrtn <= 0)
return selrtn;
@@ -651,6 +649,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0) {
DEBUG(10,("receive_smb: length < 0!\n"));
+ smb_read_error = READ_ERROR;
return(False);
}
@@ -817,7 +816,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) {
if( DEBUGLVL( dlevel ) ) {
dbgtext( "open_socket_in(): setsockopt: ");
- dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" );
+ dbgtext( "SO_REUSEPORT = %s ", val?"True":"False" );
dbgtext( "on port %d failed ", port );
dbgtext( "with error = %s\n", strerror(errno) );
}
@@ -1076,74 +1075,6 @@ int open_pipe_sock(char *path)
return sock;
}
-int create_pipe_socket(char *dir, int dir_perms,
- char *path, int path_perms)
-{
- int s;
- struct sockaddr_un sa;
-
- DEBUG(0,("create_pipe_socket: %s %d %s %d\n",
- dir, dir_perms, path, path_perms));
-
- DEBUG(0,("*** RACE CONDITION. PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n"));
-
- mkdir(dir, dir_perms);
-
- if (chmod(dir, dir_perms) < 0)
- {
- DEBUG(0, ("chmod on %s failed\n", dir));
- return -1;
- }
-
- if (!remove(path))
- {
- DEBUG(0, ("remove on %s failed\n", path));
- }
-
- /* start listening on unix socket */
- s = socket(AF_UNIX, SOCK_STREAM, 0);
-
- if (s < 0)
- {
- DEBUG(0, ("socket open failed\n"));
- return -1;
- }
-
- ZERO_STRUCT(sa);
- sa.sun_family = AF_UNIX;
- safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
-
- if (bind(s, (struct sockaddr*) &sa, sizeof(sa)) < 0)
- {
- DEBUG(0, ("socket bind to %s failed\n", sa.sun_path));
- close(s);
- remove(path);
- return -1;
- }
-
- if (s == -1)
- {
- DEBUG(0,("bind failed\n"));
- remove(path);
- return -1;
- }
-
- if (path_perms != 0)
- {
- chmod(path, path_perms);
- }
-
- if (listen(s, 5) == -1)
- {
- DEBUG(0,("listen failed\n"));
- return -1;
- }
-
- DEBUG(5,("unix socket opened: %s\n", path));
-
- return s;
-}
-
/*******************************************************************
this is like socketpair but uses tcp. It is used by the Samba
regression test code
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 32e2c40a7b4..f5f9cc1fe44 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static char *last_ptr=NULL;
void set_first_token(char *ptr)
@@ -319,9 +317,9 @@ int strwicmp(char *psz1, char *psz2)
/* sync the strings on first non-whitespace */
while (1)
{
- while (isspace(*psz1))
+ while (isspace((int)*psz1))
psz1++;
- while (isspace(*psz2))
+ while (isspace((int)*psz2))
psz2++;
if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
|| *psz2 == '\0')
@@ -926,6 +924,8 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
{
size_t len, i;
+ size_t buflen;
+ smb_ucs2_t *str_ucs, *other_ucs;
if (!dest) {
DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
@@ -937,22 +937,44 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si
return dest;
}
- len = strlen(src);
- if (len >= maxlength)
- len = maxlength - 1;
+ /* Get UCS2 version of src string*/
+
+ buflen=2*strlen(src)+2;
+ if (buflen >= (2*maxlength))
+ buflen = 2*(maxlength - 1);
+
+ str_ucs = (smb_ucs2_t*)malloc(buflen);
+ if(!str_ucs) {
+ *dest=0;
+ return dest;
+ }
+ unix_to_unicode(str_ucs, src, buflen);
+ len = strlen_w(str_ucs);
if (!other_safe_chars)
other_safe_chars = "";
+ /* Get UCS2 version of other_safe_chars string*/
+ buflen=2*strlen(other_safe_chars)+2;
+ other_ucs = (smb_ucs2_t*)malloc(buflen);
+ if(!other_ucs) {
+ *dest=0;
+ SAFE_FREE(str_ucs);
+ return dest;
+ }
+ unix_to_unicode(other_ucs, other_safe_chars, buflen);
+
for(i = 0; i < len; i++) {
- int val = (src[i] & 0xff);
- if(isupper(val) || islower(val) || isdigit(val) || strchr(other_safe_chars, val))
- dest[i] = src[i];
+ if(isupper_w(str_ucs[i]) || islower_w(str_ucs[i]) || isdigit_w(str_ucs[i]) || strchr_w(other_ucs, str_ucs[i]))
+ ;
else
- dest[i] = '_';
+ str_ucs[i] = (smb_ucs2_t)'_'; /*This will work*/
+
}
+ unicode_to_unix(dest, str_ucs, maxlength);
- dest[i] = '\0';
+ SAFE_FREE(other_ucs);
+ SAFE_FREE(str_ucs);
return dest;
}
@@ -1117,8 +1139,7 @@ void string_free(char **s)
if (!s || !(*s)) return;
if (*s == null_string)
*s = NULL;
- if (*s) free(*s);
- *s = NULL;
+ SAFE_FREE(*s);
}
/****************************************************************************
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index 9b3e25dd7ea..c044e8f248c 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
(smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
(smb_ucs2_t)'\r', 0 };
@@ -43,6 +41,48 @@ static uint16 *ucs2_to_unixcp;
/*******************************************************************
Write a string in (little-endian) unicode format. src is in
+ the current UNIX character set. len is the length in bytes of the
+ string pointed to by dst.
+
+ if null_terminate is True then null terminate the packet (adds 2 bytes)
+
+ the return value is the length in bytes consumed by the string, including the
+ null termination if applied
+********************************************************************/
+
+size_t unix_PutUniCode(char *dst,const char *src, ssize_t len, BOOL null_terminate)
+{
+ size_t ret = 0;
+ while (*src && (len >= 2)) {
+ size_t skip = get_character_len(*src);
+ smb_ucs2_t val = (*src & 0xff);
+
+ /*
+ * If this is a multibyte character (and all DOS/Windows
+ * codepages have at maximum 2 byte multibyte characters)
+ * then work out the index value for the unicode conversion.
+ */
+
+ if (skip == 2)
+ val = ((val << 8) | (src[1] & 0xff));
+
+ SSVAL(dst,ret,unixcp_to_ucs2[val]);
+ ret += 2;
+ len -= 2;
+ if (skip)
+ src += skip;
+ else
+ src++;
+ }
+ if (null_terminate) {
+ SSVAL(dst,ret,0);
+ ret += 2;
+ }
+ return(ret);
+}
+
+/*******************************************************************
+ Write a string in (little-endian) unicode format. src is in
the current DOS codepage. len is the length in bytes of the
string pointed to by dst.
@@ -286,21 +326,21 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
}
src = str->buffer;
- len = MIN(str->uni_str_len, maxlen);
+ len = MIN(str->uni_str_len, maxlen);
if (len == 0) {
*dest='\0';
return;
}
- for (p = dest; (p-dest < len) && *src; src++) {
+ for (p = dest; (p-dest < maxlen-3) && (src - str->buffer < str->uni_str_len) && *src; src++) {
uint16 ucs2_val = SVAL(src,0);
uint16 cp_val = ucs2_to_doscp[ucs2_val];
if (cp_val < 256)
*p++ = (char)cp_val;
else {
- *p = (cp_val >> 8) & 0xff;
+ *p++ = (cp_val >> 8) & 0xff;
*p++ = (cp_val & 0xff);
}
}
@@ -481,15 +521,8 @@ static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
*pp_ucs2_to_cp = NULL;
}
- if (*pp_cp_to_ucs2) {
- free(*pp_cp_to_ucs2);
- *pp_cp_to_ucs2 = NULL;
- }
-
- if (*pp_ucs2_to_cp) {
- free(*pp_ucs2_to_cp);
- *pp_ucs2_to_cp = NULL;
- }
+ SAFE_FREE(*pp_cp_to_ucs2);
+ SAFE_FREE(*pp_ucs2_to_cp);
}
/*******************************************************************
@@ -668,6 +701,7 @@ BOOL load_dos_unicode_map(int codepage)
fstring codepage_str;
slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
+ DEBUG(10,("load_dos_unicode_map: %s\n", codepage_str));
return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
}
@@ -675,13 +709,23 @@ BOOL load_dos_unicode_map(int codepage)
Load a UNIX codepage to unicode and vica-versa map.
********************************************************************/
-BOOL load_unix_unicode_map(const char *unix_char_set)
+BOOL load_unix_unicode_map(const char *unix_char_set, BOOL override)
{
- fstring upper_unix_char_set;
+ static BOOL init_done;
+ fstring upper_unix_char_set;
+
+ fstrcpy(upper_unix_char_set, unix_char_set);
+ strupper(upper_unix_char_set);
+
+ DEBUG(10,("load_unix_unicode_map: %s (init_done=%d, override=%d)\n",
+ upper_unix_char_set, (int)init_done, (int)override ));
+
+ if (!init_done)
+ init_done = True;
+ else if (!override)
+ return True;
- fstrcpy(upper_unix_char_set, unix_char_set);
- strupper(upper_unix_char_set);
- return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
+ return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
}
/*******************************************************************
@@ -737,7 +781,7 @@ smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
- for(i = 0; (i < (dst_len - 1)) && src[i];) {
+ for(i = 0; (i < (dst_len - 1)) && *src;) {
size_t skip = skip_multibyte_char(*src);
smb_ucs2_t val = (*src & 0xff);
@@ -788,6 +832,28 @@ smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
}
/*******************************************************************
+ Convert a single UNICODE character to unix character. Returns the
+ number of bytes in the unix character.
+********************************************************************/
+
+size_t unicode_to_unix_char(char *dst, const smb_ucs2_t src)
+{
+ smb_ucs2_t val = ucs2_to_unixcp[src];
+ if(val < 256) {
+ *dst = (char)val;
+ return (size_t)1;
+ }
+ /*
+ * A 2 byte value is always written as
+ * high/low into the buffer stream.
+ */
+
+ dst[0] = (char)((val >> 8) & 0xff);
+ dst[1] = (char)(val & 0xff);
+ return (size_t)2;
+}
+
+/*******************************************************************
Convert a UNICODE string to DOS format. Note that the 'src' is in
native byte order, not little endian. Always zero terminates.
dst_len is in bytes.
@@ -1791,9 +1857,7 @@ void string_free_w(smb_ucs2_t **s)
return;
if (*s == null_string)
*s = NULL;
- if (*s)
- free((char *)*s);
- *s = NULL;
+ SAFE_FREE(*s);
}
/****************************************************************************
@@ -1983,3 +2047,12 @@ int ucs2doscp(smb_ucs2_t w)
return ((int)ucs2_to_doscp[w]);
}
+/* Temporary fix until 3.0... JRA */
+
+int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
+{
+ if(dest_len==-1)
+ dest_len=MAXUNI-3;
+ unistr_to_ascii(dest, src, dest_len - 1);
+ return src_len;
+}
diff --git a/source/lib/wins_srv.c b/source/lib/wins_srv.c
index 4f9922474e0..c0cf64f751e 100644
--- a/source/lib/wins_srv.c
+++ b/source/lib/wins_srv.c
@@ -130,9 +130,8 @@ BOOL wins_srv_load_list( char *src )
/* Empty the list. */
while( NULL != (entry =(list_entry *)ubi_slRemHead( wins_srv_list )) )
{
- if( entry->server )
- free( entry->server );
- free( entry );
+ SAFE_FREE( entry->server );
+ SAFE_FREE( entry );
}
(void)ubi_slInitList( wins_srv_list ); /* shouldn't be needed */
@@ -150,7 +149,7 @@ BOOL wins_srv_load_list( char *src )
entry->mourning = 0;
if( NULL == (entry->server = strdup( wins_id_bufr )) )
{
- free( entry );
+ SAFE_FREE( entry );
DEBUG( 0, ("wins_srv_load_list(): strdup(\"%s\") failed.\n", wins_id_bufr) );
}
else
diff --git a/source/libsmb/cli_lsarpc.c b/source/libsmb/cli_lsarpc.c
index ef5dd4896f1..992c5c0439c 100644
--- a/source/libsmb/cli_lsarpc.c
+++ b/source/libsmb/cli_lsarpc.c
@@ -25,73 +25,100 @@
#include "includes.h"
-/* Opens a SMB connection to the lsa pipe */
-
+/** @defgroup lsa LSA rpc client routines
+ * @ingroup rpc_client
+ *
+ * @{
+ **/
+
+/**
+ * @file cli_lsarpc.c
+ *
+ * RPC client routines for the LSA RPC pipe. LSA means "local
+ * security authority", which is half of a password database.
+ **/
+
+/** Opens a SMB connection and connects to the LSARPC pipe.
+ *
+ * @param cli Uninitialised client handle.
+ * @param system_name NETBIOS name of the machine to connect to.
+ * @param creds User credentials to connect as.
+ * @returns Initialised client handle.
+ */
struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name,
struct ntuser_creds *creds)
{
- struct in_addr dest_ip;
- struct nmb_name calling, called;
- fstring dest_host;
- extern pstring global_myname;
- struct ntuser_creds anon;
+ return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds);
+}
- /* Initialise cli_state information */
+/** Open a LSA policy handle
+ *
+ * @param cli Handle on an initialised SMB connection */
- if (!cli_initialise(cli)) {
- return NULL;
- }
+NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_OPEN_POL q;
+ LSA_R_OPEN_POL r;
+ LSA_SEC_QOS qos;
+ NTSTATUS result;
- if (!creds) {
- ZERO_STRUCT(anon);
- anon.pwd.null_pwd = 1;
- creds = &anon;
- }
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
- cli_init_creds(cli, creds);
+ /* Initialise parse structures */
- /* Establish a SMB connection */
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
- if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
- return NULL;
+ /* Initialise input parameters */
+
+ if (sec_qos) {
+ init_lsa_sec_qos(&qos, 2, 1, 0, des_access);
+ init_q_open_pol(&q, '\\', 0, des_access, &qos);
+ } else {
+ init_q_open_pol(&q, '\\', 0, des_access, NULL);
}
- make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
- make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+ /* Marshall data and send request */
- if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
- &called, "IPC$", "IPC", False, True)) {
- return NULL;
+ if (!lsa_io_q_open_pol("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- /* Open a NT session thingy */
+ /* Unmarshall response */
- if (!cli_nt_session_open(cli, PIPE_LSARPC)) {
- cli_shutdown(cli);
- return NULL;
+ if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- return cli;
-}
+ /* Return output parameters */
-/* Shut down a SMB connection to the LSA pipe */
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *pol = r.pol;
+ }
-void cli_lsa_shutdown(struct cli_state *cli)
-{
- if (cli->fd != -1) cli_ulogoff(cli);
- cli_shutdown(cli);
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
}
-/* Open a LSA policy handle */
+/** Open a LSA policy handle */
-uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
+NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
{
prs_struct qbuf, rbuf;
- LSA_Q_OPEN_POL q;
- LSA_R_OPEN_POL r;
+ LSA_Q_OPEN_POL2 q;
+ LSA_R_OPEN_POL2 r;
LSA_SEC_QOS qos;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -105,29 +132,31 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (sec_qos) {
init_lsa_sec_qos(&qos, 2, 1, 0, des_access);
- init_q_open_pol(&q, '\\', 0, des_access, &qos);
+ init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access,
+ &qos);
} else {
- init_q_open_pol(&q, '\\', 0, des_access, NULL);
+ init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access,
+ NULL);
}
/* Marshall data and send request */
- if (!lsa_io_q_open_pol("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) {
+ if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Unmarshall response */
- if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) {
+ if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*pol = r.pol;
}
@@ -138,15 +167,15 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Close a LSA policy handle */
+/** Close a LSA policy handle */
-uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
+NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol)
{
prs_struct qbuf, rbuf;
LSA_Q_CLOSE q;
LSA_R_CLOSE r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -175,7 +204,7 @@ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*pol = r.pol;
}
@@ -186,18 +215,18 @@ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Lookup a list of sids */
+/** Lookup a list of sids */
-uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_sids, DOM_SID *sids,
- char ***names, uint32 **types, int *num_names)
+NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_sids, DOM_SID *sids,
+ char ***names, uint32 **types, int *num_names)
{
prs_struct qbuf, rbuf;
LSA_Q_LOOKUP_SIDS q;
LSA_R_LOOKUP_SIDS r;
DOM_R_REF ref;
LSA_TRANS_NAME_ENUM t_names;
- uint32 result;
+ NTSTATUS result;
int i;
ZERO_STRUCT(q);
@@ -233,53 +262,55 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_OK && result != 0x00000107 &&
- result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) {
-
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN)) {
/* An actual error occured */
goto done;
}
- result = NT_STATUS_OK;
/* Return output parameters */
- (*num_names) = r.names->num_entries;
-
- if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) *
- r.names->num_entries))) {
+ if (r.mapped_count == 0) {
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ (*num_names) = r.mapped_count;
+ result = NT_STATUS_OK;
+
+ if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) {
DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) *
- r.names->num_entries))) {
+ if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count))) {
DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- for (i = 0; i < r.names->num_entries; i++) {
+ for (i = 0; i < r.mapped_count; i++) {
fstring name, dom_name, full_name;
uint32 dom_idx = t_names.name[i].domain_idx;
/* Translate optimised name through domain index array */
if (dom_idx != 0xffffffff) {
- unistr2_to_ascii(dom_name,
- &ref.ref_dom[dom_idx].uni_dom_name,
- sizeof(dom_name)- 1);
- unistr2_to_ascii(name, &t_names.uni_name[i],
- sizeof(name) - 1);
+
+ unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)- 1);
+ unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name) - 1);
slprintf(full_name, sizeof(full_name) - 1,
- "%s%s%s", dom_name, dom_name[0] ?
- "\\" : "", name);
+ "%s%s%s", dom_name,
+ (dom_name[0] && name[0]) ?
+ lp_winbind_separator() : "", name);
(*names)[i] = talloc_strdup(mem_ctx, full_name);
(*types)[i] = t_names.name[i].sid_name_use;
+
} else {
(*names)[i] = NULL;
(*types)[i] = SID_NAME_UNKNOWN;
@@ -293,17 +324,17 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Lookup a list of names */
+/** Lookup a list of names */
-uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_names, char **names,
- DOM_SID **sids, uint32 **types, int *num_sids)
+NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, int num_names, char **names,
+ DOM_SID **sids, uint32 **types, int *num_sids)
{
prs_struct qbuf, rbuf;
LSA_Q_LOOKUP_NAMES q;
LSA_R_LOOKUP_NAMES r;
DOM_R_REF ref;
- uint32 result;
+ NTSTATUS result;
int i;
ZERO_STRUCT(q);
@@ -336,35 +367,36 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_OK &&
- result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) {
-
+ if (!NT_STATUS_IS_OK(result)) {
/* An actual error occured */
goto done;
}
- result = NT_STATUS_OK;
/* Return output parameters */
- (*num_sids) = r.num_entries;
+ if (r.mapped_count == 0) {
+ result = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ (*num_sids) = r.mapped_count;
+ result = NT_STATUS_OK;
- if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) *
- r.num_entries)))) {
+ if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.mapped_count)))) {
DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) *
- r.num_entries)))) {
+ if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count)))) {
DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- for (i = 0; i < r.num_entries; i++) {
+ for (i = 0; i < r.mapped_count; i++) {
DOM_RID2 *t_rids = r.dom_rid;
uint32 dom_idx = t_rids[i].rid_idx;
uint32 dom_rid = t_rids[i].rid;
@@ -394,16 +426,16 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Query info policy */
+/** Query info policy */
-uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid)
+NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_INFO q;
LSA_R_QUERY_INFO r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -430,7 +462,7 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -481,17 +513,17 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-/* Enumerate list of trusted domains */
+/** Enumerate list of trusted domains */
-uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *enum_ctx,
- uint32 *num_domains, char ***domain_names,
- DOM_SID **domain_sids)
+NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx,
+ uint32 *num_domains, char ***domain_names,
+ DOM_SID **domain_sids)
{
prs_struct qbuf, rbuf;
LSA_Q_ENUM_TRUST_DOM q;
LSA_R_ENUM_TRUST_DOM r;
- uint32 result;
+ NTSTATUS result;
int i;
ZERO_STRUCT(q);
@@ -521,12 +553,8 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- /* For some undocumented reason this function sometimes returns
- 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and
- pretend everything is OK. */
-
- if (result != NT_STATUS_OK &&
- result != NT_STATUS_UNABLE_TO_FREE_VM) {
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) {
/* An actual error ocured */
@@ -579,3 +607,305 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
+
+/** Enumerate privileges*/
+
+NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
+ uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUM_PRIVS q;
+ LSA_R_ENUM_PRIVS r;
+ NTSTATUS result;
+ int i;
+
+ 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);
+
+ /* Marshall data and send request */
+
+ init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
+
+ if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ *enum_context = r.enum_context;
+ *count = r.count;
+
+ if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) {
+ DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ for (i = 0; i < r.count; i++) {
+ fstring name;
+
+ unistr2_to_ascii( name, &r.privs[i].name, sizeof(name)-1);
+
+ (*privs_name)[i] = talloc_strdup(mem_ctx, name);
+
+ (*privs_high)[i] = r.privs[i].luid_high;
+ (*privs_low)[i] = r.privs[i].luid_low;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Get privilege name */
+
+NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys,
+ fstring description, uint16 *lang_id_desc)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_PRIV_GET_DISPNAME q;
+ LSA_R_PRIV_GET_DISPNAME r;
+ NTSTATUS result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
+
+ if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ unistr2_to_ascii(description ,&r.desc, sizeof(description)-1);
+ *lang_id_desc = r.lang_id;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Enumerate list of SIDs */
+
+NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
+ uint32 *num_sids, DOM_SID **sids)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_ENUM_ACCOUNTS q;
+ LSA_R_ENUM_ACCOUNTS r;
+ NTSTATUS result;
+ int i;
+
+ 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);
+
+ /* Marshall data and send request */
+
+ init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
+
+ if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+
+ /* Return output parameters */
+
+ *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries);
+ if (!*sids) {
+ DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Copy across names and sids */
+
+ for (i = 0; i < r.sids.num_entries; i++) {
+ sid_copy(&(*sids)[i], &r.sids.sid[i].sid);
+ }
+
+ *num_sids= r.sids.num_entries;
+ *enum_ctx = r.enum_context;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/** Fetch a DOMAIN sid. Does complete cli setup / teardown anonymously. */
+
+BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid)
+{
+ extern pstring global_myname;
+ struct cli_state cli;
+ NTSTATUS result;
+ POLICY_HND lsa_pol;
+ BOOL ret = False;
+
+ ZERO_STRUCT(cli);
+ if(cli_initialise(&cli) == False) {
+ DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
+ return False;
+ }
+
+ if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
+ DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine));
+ goto done;
+ }
+
+ if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS \
+session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (cli.protocol != PROTOCOL_NT1) {
+ DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
+ remote_machine));
+ goto done;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ if (!(cli.sec_mode & 1)) {
+ DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
+ remote_machine));
+ goto done;
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ goto done;
+ }
+
+ /* Fetch domain sid */
+
+ if (!cli_nt_session_open(&cli, PIPE_LSARPC)) {
+ DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+ result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
+ get_nt_error_msg(result) ));
+ goto done;
+ }
+
+ result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
+ get_nt_error_msg(result) ));
+ goto done;
+ }
+
+ ret = True;
+
+ done:
+
+ cli_shutdown(&cli);
+ return ret;
+}
+/** @} **/
diff --git a/source/libsmb/cli_netlogon.c b/source/libsmb/cli_netlogon.c
index 47b7c2f22ec..1e4f7955d26 100644
--- a/source/libsmb/cli_netlogon.c
+++ b/source/libsmb/cli_netlogon.c
@@ -29,67 +29,196 @@ struct cli_state *cli_netlogon_initialise(struct cli_state *cli,
char *system_name,
struct ntuser_creds *creds)
{
- struct in_addr dest_ip;
- struct nmb_name calling, called;
- fstring dest_host;
- extern pstring global_myname;
- struct ntuser_creds anon;
+ return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds);
+}
- /* Initialise cli_state information */
+/* LSA Request Challenge. Sends our challenge to server, then gets
+ server response. These are used to generate the credentials. */
- if (!cli_initialise(cli)) {
- return NULL;
- }
+NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_REQ_CHAL q;
+ NET_R_REQ_CHAL r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ extern pstring global_myname;
- if (!creds) {
- ZERO_STRUCT(anon);
- anon.pwd.null_pwd = 1;
- creds = &anon;
- }
+ 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_REQCHAL */
- cli_init_creds(cli, creds);
+ DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
+ cli->desthost, global_myname, credstr(clnt_chal->data)));
+
+ /* store the parameters */
+ init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal);
+
+ /* Marshall data and send request */
- /* Establish a SMB connection */
+ if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) {
+ goto done;
+ }
- if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
- return NULL;
- }
+ /* Unmarhall response */
- make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
- make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+ if (!net_io_r_req_chal("", &r, &rbuf, 0)) {
+ goto done;
+ }
- if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
- &called, "IPC$", "IPC", False, True)) {
- return NULL;
- }
+ result = r.status;
- /* Open a NT session thingy */
+ /* Return result */
- if (!cli_nt_session_open(cli, PIPE_NETLOGON)) {
- cli_shutdown(cli);
- return NULL;
- }
+ if (NT_STATUS_IS_OK(result)) {
+ memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data));
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/****************************************************************************
+LSA Authenticate 2
+
+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 new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+ uint32 neg_flags, DOM_CHAL *srv_chal)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_AUTH_2 q;
+ NET_R_AUTH_2 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_auth2: 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_2(&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_2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_auth_2("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ result = r.status;
- return cli;
+ 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_auth2: 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;
}
-/* Shut down a SMB connection to the netlogon pipe */
+/* Initialize domain session credentials */
-void cli_netlogon_shutdown(struct cli_state *cli)
+NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli,
+ unsigned char mach_pwd[16])
{
- if (cli->fd != -1) cli_ulogoff(cli);
- cli_shutdown(cli);
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+ UTIME zerotime;
+ NTSTATUS result;
+
+ /******************* Request Challenge ********************/
+
+ generate_random_buffer(clnt_chal.data, 8, False);
+
+ /* send a client challenge; receive a server challenge */
+ result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
+ return result;
+ }
+
+ /**************** Long-term Session key **************/
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd,
+ cli->sess_key);
+ memset((char *)cli->sess_key+8, '\0', 8);
+
+ /******************* Authenticate 2 ********************/
+
+ /* calculate auth-2 credentials */
+ zerotime.time = 0;
+ 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.
+ */
+
+ result = new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff,
+ &srv_chal);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n",
+ get_nt_error_msg(result)));
+ }
+
+ return result;
}
/* Logon Control 2 */
-uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 query_level)
+NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 query_level)
{
prs_struct qbuf, rbuf;
NET_Q_LOGON_CTRL2 q;
NET_R_LOGON_CTRL2 r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -126,3 +255,240 @@ uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
+
+/****************************************************************************
+Generate the next creds to use. Yuck - this is a cut&paste from another
+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));
+
+}
+
+/* Sam synchronisation */
+
+NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_SYNC q;
+ NET_R_SAM_SYNC r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds;
+
+ 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 */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2,
+ &clnt_creds, database_id);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_sync("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+ *num_deltas = r.num_deltas2;
+ *hdr_deltas = r.hdr_deltas;
+ *deltas = r.deltas;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Sam synchronisation */
+
+NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 database_id, UINT64_S seqnum,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR **hdr_deltas,
+ SAM_DELTA_CTR **deltas)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_DELTAS q;
+ NET_R_SAM_DELTAS r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds;
+
+ 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 */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ init_net_q_sam_deltas(&q, cli->srv_name_slash,
+ cli->clnt_name_slash + 2, &clnt_creds,
+ database_id, seqnum);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_deltas("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+ *num_deltas = r.num_deltas2;
+ *hdr_deltas = r.hdr_deltas;
+ *deltas = r.deltas;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Logon domain user */
+
+NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char *username, char *password,
+ int logon_type)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_SAM_LOGON q;
+ NET_R_SAM_LOGON r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DOM_CRED clnt_creds, dummy_rtn_creds;
+ extern pstring global_myname;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 user;
+ int validation_level = 3;
+
+ 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 */
+
+ gen_next_creds(cli, &clnt_creds);
+
+ q.validation_level = validation_level;
+
+ memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
+ dummy_rtn_creds.timestamp.time = time(NULL);
+
+ ctr.switch_value = logon_type;
+
+ switch (logon_type) {
+ case INTERACTIVE_LOGON_TYPE: {
+ unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16];
+
+ nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
+
+ init_id_info1(&ctr.auth.id1, lp_workgroup(),
+ 0, /* param_ctrl */
+ 0xdead, 0xbeef, /* LUID? */
+ username, cli->clnt_name_slash,
+ (char *)cli->sess_key, lm_owf_user_pwd,
+ nt_owf_user_pwd);
+
+ break;
+ }
+ case NET_LOGON_TYPE: {
+ uint8 chal[8];
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
+
+ generate_random_buffer(chal, 8, False);
+
+ SMBencrypt((unsigned char *)password, chal, local_lm_response);
+ SMBNTencrypt((unsigned char *)password, chal, local_nt_response);
+
+ init_id_info2(&ctr.auth.id2, lp_workgroup(),
+ 0, /* param_ctrl */
+ 0xdead, 0xbeef, /* LUID? */
+ username, cli->clnt_name_slash, chal,
+ local_lm_response, 24, local_nt_response, 24);
+ break;
+ }
+ default:
+ DEBUG(0, ("switch value %d not supported\n",
+ ctr.switch_value));
+ goto done;
+ }
+
+ init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname,
+ &clnt_creds, &dummy_rtn_creds, logon_type,
+ &ctr);
+
+ /* Marshall data and send request */
+
+ if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ r.user = &user;
+
+ if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return results */
+
+ result = r.status;
+
+ done:
+ return result;
+}
diff --git a/source/libsmb/cli_samr.c b/source/libsmb/cli_samr.c
index 09bb599a194..4a04d678876 100644
--- a/source/libsmb/cli_samr.c
+++ b/source/libsmb/cli_samr.c
@@ -30,67 +30,18 @@
struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
struct ntuser_creds *creds)
{
- struct in_addr dest_ip;
- struct nmb_name calling, called;
- fstring dest_host;
- extern pstring global_myname;
- struct ntuser_creds anon;
-
- /* Initialise cli_state information */
-
- if (!cli_initialise(cli)) {
- return NULL;
- }
-
- if (!creds) {
- ZERO_STRUCT(anon);
- anon.pwd.null_pwd = 1;
- creds = &anon;
- }
-
- cli_init_creds(cli, creds);
-
- /* Establish a SMB connection */
-
- if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
- return NULL;
- }
-
- make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
- make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
-
- if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
- &called, "IPC$", "IPC", False, True)) {
- return NULL;
- }
-
- /* Open a NT session thingy */
-
- if (!cli_nt_session_open(cli, PIPE_SAMR)) {
- cli_shutdown(cli);
- return NULL;
- }
-
- return cli;
-}
-
-/* Shut down a SMB connection to the SAMR pipe */
-
-void cli_samr_shutdown(struct cli_state *cli)
-{
- if (cli->fd != -1) cli_ulogoff(cli);
- cli_shutdown(cli);
+ return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds);
}
/* Connect to SAMR database */
-uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol)
+NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 access_mask, POLICY_HND *connect_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_CONNECT q;
SAMR_R_CONNECT r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -117,7 +68,7 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*connect_pol = r.connect_pol;
}
@@ -130,13 +81,13 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Close SAMR handle */
-uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol)
+NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_CLOSE_HND q;
SAMR_R_CLOSE_HND r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -163,7 +114,7 @@ uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*connect_pol = r.pol;
}
@@ -176,14 +127,14 @@ uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Open handle on a domain */
-uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol, uint32 access_mask,
- DOM_SID *domain_sid, POLICY_HND *domain_pol)
+NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol, uint32 access_mask,
+ DOM_SID *domain_sid, POLICY_HND *domain_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_DOMAIN q;
SAMR_R_OPEN_DOMAIN r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -210,7 +161,7 @@ uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*domain_pol = r.domain_pol;
}
@@ -223,14 +174,14 @@ uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Open handle on a user */
-uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 user_rid, POLICY_HND *user_pol)
+NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 user_rid, POLICY_HND *user_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_USER q;
SAMR_R_OPEN_USER r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -257,7 +208,7 @@ uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*user_pol = r.user_pol;
}
@@ -270,14 +221,14 @@ uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Open handle on a group */
-uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 group_rid, POLICY_HND *group_pol)
+NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_GROUP q;
SAMR_R_OPEN_GROUP r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -304,7 +255,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*group_pol = r.pol;
}
@@ -317,14 +268,14 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query user info */
-uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR **ctr)
+NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ SAM_USERINFO_CTR **ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_USERINFO q;
SAMR_R_QUERY_USERINFO r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -363,14 +314,14 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query group info */
-uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 info_level,
- GROUP_INFO_CTR *ctr)
+NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 info_level,
+ GROUP_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_GROUPINFO q;
SAMR_R_QUERY_GROUPINFO r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -410,14 +361,14 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query user groups */
-uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint32 *num_groups,
- DOM_GID **gid)
+NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint32 *num_groups,
+ DOM_GID **gid)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_USERGROUPS q;
SAMR_R_QUERY_USERGROUPS r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -444,7 +395,7 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*num_groups = r.num_entries;
*gid = r.gid;
}
@@ -458,14 +409,14 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query user groups */
-uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 *num_mem,
- uint32 **rid, uint32 **attr)
+NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *group_pol, uint32 *num_mem,
+ uint32 **rid, uint32 **attr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_GROUPMEM q;
SAMR_R_QUERY_GROUPMEM r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -492,7 +443,7 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*num_mem = r.num_entries;
*rid = r.rid;
*attr = r.attr;
@@ -507,15 +458,16 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Enumerate domain groups */
-uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_groups,
- uint32 *num_dom_groups)
+NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **dom_groups,
+ uint32 *num_dom_groups)
{
prs_struct qbuf, rbuf;
SAMR_Q_ENUM_DOM_GROUPS q;
SAMR_R_ENUM_DOM_GROUPS r;
- uint32 result = NT_STATUS_UNSUCCESSFUL, name_idx, i;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 name_idx, i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -544,8 +496,8 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_OK &&
- result != STATUS_MORE_ENTRIES) {
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
goto done;
}
@@ -584,14 +536,15 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query alias members */
-uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, uint32 *num_mem,
- DOM_SID **sids)
+NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint32 *num_mem,
+ DOM_SID **sids)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_ALIASMEM q;
SAMR_R_QUERY_ALIASMEM r;
- uint32 result = NT_STATUS_UNSUCCESSFUL, i;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -618,7 +571,7 @@ uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -642,14 +595,14 @@ uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Open handle on an alias */
-uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 alias_rid, POLICY_HND *alias_pol)
+NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 alias_rid, POLICY_HND *alias_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_ALIAS q;
SAMR_R_OPEN_ALIAS r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -678,7 +631,7 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result = r.status)) {
*alias_pol = r.pol;
}
@@ -691,14 +644,14 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query domain info */
-uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint16 switch_value,
- SAM_UNK_CTR *ctr)
+NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_DOMAIN_INFO q;
SAMR_R_QUERY_DOMAIN_INFO r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -727,7 +680,7 @@ uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -740,15 +693,15 @@ uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query display info */
-uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 *start_idx,
- uint16 switch_value, uint32 *num_entries,
- uint32 max_entries, SAM_DISPINFO_CTR *ctr)
+NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 *start_idx,
+ uint16 switch_value, uint32 *num_entries,
+ uint32 max_entries, SAM_DISPINFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_DISPINFO q;
SAMR_R_QUERY_DISPINFO r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -780,8 +733,8 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_OK &&
- result != STATUS_MORE_ENTRIES) {
+ if (!NT_STATUS_IS_OK(result) &&
+ NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
goto done;
}
@@ -798,16 +751,17 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
looked up in one packet. */
-uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_rids, uint32 *rids,
- uint32 *num_names, char ***names,
- uint32 **name_types)
+NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types)
{
prs_struct qbuf, rbuf;
SAMR_Q_LOOKUP_RIDS q;
SAMR_R_LOOKUP_RIDS r;
- uint32 result = NT_STATUS_UNSUCCESSFUL, i;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 i;
if (num_rids > 1000) {
DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
@@ -840,7 +794,7 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -871,16 +825,17 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Lookup names */
-uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 flags,
- uint32 num_names, char **names,
- uint32 *num_rids, uint32 **rids,
- uint32 **rid_types)
+NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types)
{
prs_struct qbuf, rbuf;
SAMR_Q_LOOKUP_NAMES q;
SAMR_R_LOOKUP_NAMES r;
- uint32 result = NT_STATUS_UNSUCCESSFUL, i;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -908,7 +863,7 @@ uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -935,15 +890,15 @@ uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Create a domain user */
-uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, char *acct_name,
- uint32 acb_info, uint32 unknown,
- POLICY_HND *user_pol, uint32 *rid)
+NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, char *acct_name,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid)
{
prs_struct qbuf, rbuf;
SAMR_Q_CREATE_USER q;
SAMR_R_CREATE_USER r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -970,7 +925,7 @@ uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -989,14 +944,14 @@ uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Set userinfo */
-uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_SET_USERINFO q;
SAMR_R_SET_USERINFO r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1026,7 +981,7 @@ uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -1039,14 +994,14 @@ uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Set userinfo2 */
-uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_SET_USERINFO2 q;
SAMR_R_SET_USERINFO2 r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1073,7 +1028,7 @@ uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
@@ -1086,13 +1041,13 @@ uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Delete domain user */
-uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol)
+NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_DELETE_DOM_USER q;
SAMR_R_DELETE_DOM_USER r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
diff --git a/source/libsmb/cli_spoolss.c b/source/libsmb/cli_spoolss.c
index 6353365773d..16a95b69e17 100644
--- a/source/libsmb/cli_spoolss.c
+++ b/source/libsmb/cli_spoolss.c
@@ -33,61 +33,12 @@ struct cli_state *cli_spoolss_initialise(struct cli_state *cli,
char *system_name,
struct ntuser_creds *creds)
{
- struct in_addr dest_ip;
- struct nmb_name calling, called;
- fstring dest_host;
- extern pstring global_myname;
- struct ntuser_creds anon;
-
- /* Initialise cli_state information */
-
- if (!cli_initialise(cli)) {
- return NULL;
- }
-
- if (!creds) {
- ZERO_STRUCT(anon);
- anon.pwd.null_pwd = 1;
- creds = &anon;
- }
-
- cli_init_creds(cli, creds);
-
- /* Establish a SMB connection */
-
- if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
- return NULL;
- }
-
- make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
- make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
-
- if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
- &called, "IPC$", "IPC", False, True)) {
- return NULL;
- }
-
- /* Open a NT session thingy */
-
- if (!cli_nt_session_open(cli, PIPE_SPOOLSS)) {
- cli_shutdown(cli);
- return NULL;
- }
-
- return cli;
-}
-
-/* Shut down a SMB connection to the SPOOLSS pipe */
-
-void cli_spoolss_shutdown(struct cli_state *cli)
-{
- if (cli->fd != -1) cli_ulogoff(cli);
- cli_shutdown(cli);
+ return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds);
}
/* Open printer ex */
-uint32 cli_spoolss_open_printer_ex(
+NTSTATUS cli_spoolss_open_printer_ex(
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
char *printername,
@@ -101,7 +52,7 @@ uint32 cli_spoolss_open_printer_ex(
prs_struct qbuf, rbuf;
SPOOL_Q_OPEN_PRINTER_EX q;
SPOOL_R_OPEN_PRINTER_EX r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -133,8 +84,11 @@ uint32 cli_spoolss_open_printer_ex(
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (W_ERROR_IS_OK(r.status)) {
+ result = NT_STATUS_OK;
*pol = r.handle;
+ } else {
+ result = werror_to_ntstatus(r.status);
}
done:
@@ -146,7 +100,7 @@ uint32 cli_spoolss_open_printer_ex(
/* Close a printer handle */
-uint32 cli_spoolss_close_printer(
+NTSTATUS cli_spoolss_close_printer(
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol
@@ -155,7 +109,7 @@ uint32 cli_spoolss_close_printer(
prs_struct qbuf, rbuf;
SPOOL_Q_CLOSEPRINTER q;
SPOOL_R_CLOSEPRINTER r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -186,8 +140,11 @@ uint32 cli_spoolss_close_printer(
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
+ if (W_ERROR_IS_OK(r.status)) {
*pol = r.handle;
+ result = NT_STATUS_OK;
+ } else {
+ result = werror_to_ntstatus(r.status);
}
done:
@@ -221,7 +178,7 @@ static void decode_printer_info_0(
uint32 i;
PRINTER_INFO_0 *inf;
- inf=(PRINTER_INFO_0 *)talloc(mem_ctx,returned*sizeof(PRINTER_INFO_0));
+ inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0));
buffer->prs.data_offset=0;
@@ -429,7 +386,7 @@ static void decode_printerdriverdir_1 (
/* Enumerate printers */
-uint32 cli_spoolss_enum_printers(
+NTSTATUS cli_spoolss_enum_printers(
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 flags,
@@ -442,8 +399,8 @@ uint32 cli_spoolss_enum_printers(
SPOOL_Q_ENUMPRINTERS q;
SPOOL_R_ENUMPRINTERS r;
NEW_BUFFER buffer;
- uint32 needed = 100;
- uint32 result;
+ uint32 needed = 0x1068;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -476,11 +433,14 @@ uint32 cli_spoolss_enum_printers(
needed = r.needed;
}
+ result = werror_to_ntstatus(r.status);
+
+ if (NT_STATUS_V(result)==NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER) || !W_ERROR_IS_OK(result))
+ goto done;
+
/* Return output parameters */
- if (((result=r.status) == NT_STATUS_OK) && (*returned = r.returned))
- {
-
+ if ((*returned = r.returned)) {
switch (level) {
case 1:
decode_printer_info_1(mem_ctx, r.buffer, r.returned,
@@ -501,13 +461,13 @@ uint32 cli_spoolss_enum_printers(
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
/* Enumerate printer ports */
-uint32 cli_spoolss_enum_ports(
+NTSTATUS cli_spoolss_enum_ports(
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 level,
@@ -520,7 +480,7 @@ uint32 cli_spoolss_enum_ports(
SPOOL_R_ENUMPORTS r;
NEW_BUFFER buffer;
uint32 needed = 100;
- uint32 result;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -553,8 +513,9 @@ uint32 cli_spoolss_enum_ports(
}
/* Return output parameters */
+ result = werror_to_ntstatus(r.status);
- if ((result = r.status) == NT_STATUS_OK &&
+ if (NT_STATUS_IS_OK(result) &&
r.returned > 0) {
*returned = r.returned;
@@ -575,26 +536,21 @@ uint32 cli_spoolss_enum_ports(
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
/* Get printer info */
-uint32 cli_spoolss_getprinter(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- PRINTER_INFO_CTR *ctr
-)
+NTSTATUS cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTER q;
SPOOL_R_GETPRINTER r;
NEW_BUFFER buffer;
- uint32 needed = 100;
- uint32 result;
+ uint32 needed = 0x1068;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -623,8 +579,9 @@ uint32 cli_spoolss_getprinter(
}
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK) {
-
+ result = werror_to_ntstatus(r.status);
+
+ if (NT_STATUS_IS_OK(result)) {
switch (level) {
case 0:
decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0);
@@ -645,7 +602,7 @@ uint32 cli_spoolss_getprinter(
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
@@ -653,19 +610,14 @@ uint32 cli_spoolss_getprinter(
/**********************************************************************
* Set printer info
*/
-uint32 cli_spoolss_setprinter(
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- PRINTER_INFO_CTR *ctr,
- uint32 command
-)
+NTSTATUS cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr,
+ uint32 command)
{
prs_struct qbuf, rbuf;
SPOOL_Q_SETPRINTER q;
SPOOL_R_SETPRINTER r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_ACCESS_DENIED;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -680,7 +632,7 @@ uint32 cli_spoolss_setprinter(
if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
{
- result = NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_ACCESS_DENIED;
goto done;
}
@@ -690,7 +642,7 @@ uint32 cli_spoolss_setprinter(
goto done;
}
- result = r.status;
+ result = werror_to_ntstatus(r.status);
done:
prs_mem_free(&qbuf);
@@ -703,21 +655,16 @@ done:
/**********************************************************************
* Get installed printer drivers for a given printer
*/
-uint32 cli_spoolss_getprinterdriver (
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *pol,
- uint32 level,
- char* env,
- PRINTER_DRIVER_CTR *ctr
-)
+NTSTATUS cli_spoolss_getprinterdriver (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, uint32 level, char* env,
+ PRINTER_DRIVER_CTR *ctr)
{
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTERDRIVER2 q;
SPOOL_R_GETPRINTERDRIVER2 r;
NEW_BUFFER buffer;
- uint32 needed = 1024;
- uint32 result;
+ uint32 needed = 0x1068;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -754,9 +701,10 @@ uint32 cli_spoolss_getprinterdriver (
}
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_OK)
+ result = werror_to_ntstatus(r.status);
+
+ if (NT_STATUS_IS_OK(result))
{
-
switch (level)
{
case 1:
@@ -775,7 +723,7 @@ uint32 cli_spoolss_getprinterdriver (
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
@@ -783,7 +731,7 @@ uint32 cli_spoolss_getprinterdriver (
/**********************************************************************
* Get installed printer drivers for a given printer
*/
-uint32 cli_spoolss_enumprinterdrivers (
+NTSTATUS cli_spoolss_enumprinterdrivers (
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 level,
@@ -797,7 +745,7 @@ uint32 cli_spoolss_enumprinterdrivers (
SPOOL_R_ENUMPRINTERDRIVERS r;
NEW_BUFFER buffer;
uint32 needed = 0;
- uint32 result;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -833,7 +781,8 @@ uint32 cli_spoolss_enumprinterdrivers (
}
/* Return output parameters */
- if (((result=r.status) == NT_STATUS_OK) &&
+ result = werror_to_ntstatus(r.status);
+ if (NT_STATUS_IS_OK(result) &&
(r.returned != 0))
{
*returned = r.returned;
@@ -856,7 +805,7 @@ uint32 cli_spoolss_enumprinterdrivers (
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
@@ -865,7 +814,7 @@ uint32 cli_spoolss_enumprinterdrivers (
/**********************************************************************
* Get installed printer drivers for a given printer
*/
-uint32 cli_spoolss_getprinterdriverdir (
+NTSTATUS cli_spoolss_getprinterdriverdir (
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 level,
@@ -878,7 +827,7 @@ uint32 cli_spoolss_getprinterdriverdir (
SPOOL_R_GETPRINTERDRIVERDIR r;
NEW_BUFFER buffer;
uint32 needed = 100;
- uint32 result;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -914,7 +863,8 @@ uint32 cli_spoolss_getprinterdriverdir (
}
/* Return output parameters */
- if ((result=r.status) == NT_STATUS_OK)
+ result = werror_to_ntstatus(r.status);
+ if (NT_STATUS_IS_OK(result))
{
switch (level)
{
@@ -928,7 +878,7 @@ uint32 cli_spoolss_getprinterdriverdir (
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
- } while (result == ERROR_INSUFFICIENT_BUFFER);
+ } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
return result;
}
@@ -936,7 +886,7 @@ uint32 cli_spoolss_getprinterdriverdir (
/**********************************************************************
* Install a printer driver
*/
-uint32 cli_spoolss_addprinterdriver (
+NTSTATUS cli_spoolss_addprinterdriver (
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 level,
@@ -946,7 +896,7 @@ uint32 cli_spoolss_addprinterdriver (
prs_struct qbuf, rbuf;
SPOOL_Q_ADDPRINTERDRIVER q;
SPOOL_R_ADDPRINTERDRIVER r;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring server;
ZERO_STRUCT(q);
@@ -980,7 +930,7 @@ uint32 cli_spoolss_addprinterdriver (
}
/* Return output parameters */
- result = r.status;
+ result = werror_to_ntstatus(r.status);
done:
prs_mem_free(&qbuf);
@@ -992,7 +942,7 @@ done:
/**********************************************************************
* Install a printer
*/
-uint32 cli_spoolss_addprinterex (
+NTSTATUS cli_spoolss_addprinterex (
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
uint32 level,
@@ -1002,7 +952,7 @@ uint32 cli_spoolss_addprinterex (
prs_struct qbuf, rbuf;
SPOOL_Q_ADDPRINTEREX q;
SPOOL_R_ADDPRINTEREX r;
- uint32 result;
+ NTSTATUS result;
fstring server,
client,
user;
@@ -1042,7 +992,7 @@ uint32 cli_spoolss_addprinterex (
}
/* Return output parameters */
- result = r.status;
+ result = werror_to_ntstatus(r.status);
done:
prs_mem_free(&qbuf);
@@ -1055,7 +1005,7 @@ done:
* Delete a Printer Driver from the server (does not remove
* the driver files
*/
-uint32 cli_spoolss_deleteprinterdriver (
+NTSTATUS cli_spoolss_deleteprinterdriver (
struct cli_state *cli,
TALLOC_CTX *mem_ctx,
char *arch,
@@ -1065,7 +1015,7 @@ uint32 cli_spoolss_deleteprinterdriver (
prs_struct qbuf, rbuf;
SPOOL_Q_DELETEPRINTERDRIVER q;
SPOOL_R_DELETEPRINTERDRIVER r;
- uint32 result;
+ NTSTATUS result;
fstring server;
ZERO_STRUCT(q);
@@ -1099,7 +1049,7 @@ uint32 cli_spoolss_deleteprinterdriver (
}
/* Return output parameters */
- result = r.status;
+ result = werror_to_ntstatus(r.status);
done:
prs_mem_free(&qbuf);
@@ -1108,4 +1058,109 @@ done:
return result;
}
+/* Get print processor directory */
+
+NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ char *name,
+ char *environment,
+ fstring procdir)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_GETPRINTPROCESSORDIRECTORY q;
+ SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
+ NTSTATUS result;
+ int level = 1;
+ NEW_BUFFER buffer;
+ uint32 needed = 100;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+
+ /* Initialise input parameters */
+
+ do {
+ init_buffer(&buffer, needed, mem_ctx);
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ make_spoolss_q_getprintprocessordirectory(&q, name,
+ environment, level,
+ &buffer, needed);
+
+ /* Marshall data and send request */
+
+ if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ result = werror_to_ntstatus(r.status);
+
+ } while (NT_STATUS_V(result) ==
+ NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER));
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+
+/*****************************************************************************/
+
+NTSTATUS cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *pol, char* valname, char* value)
+{
+ prs_struct qbuf, rbuf;
+ SPOOL_Q_SETPRINTERDATA q;
+ SPOOL_R_SETPRINTERDATA r;
+ NTSTATUS result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise input parameters */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+
+ /* write the request */
+ make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value);
+
+ /* Marshall data and send request */
+ if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
+ {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+ if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0)) {
+ result = werror_to_ntstatus(r.status);
+ }
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source/libsmb/cli_srvsvc.c b/source/libsmb/cli_srvsvc.c
index 8209d9301f1..c9bd4643622 100644
--- a/source/libsmb/cli_srvsvc.c
+++ b/source/libsmb/cli_srvsvc.c
@@ -29,65 +29,17 @@ struct cli_state *cli_svrsvc_initialise(struct cli_state *cli,
char *system_name,
struct ntuser_creds *creds)
{
- struct in_addr dest_ip;
- struct nmb_name calling, called;
- fstring dest_host;
- extern pstring global_myname;
- struct ntuser_creds anon;
-
- /* Initialise cli_state information */
-
- if (!cli_initialise(cli)) {
- return NULL;
- }
-
- if (!creds) {
- ZERO_STRUCT(anon);
- anon.pwd.null_pwd = 1;
- creds = &anon;
- }
-
- cli_init_creds(cli, creds);
-
- /* Establish a SMB connection */
-
- if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
- return NULL;
- }
-
- make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
- make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
-
- if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
- &called, "IPC$", "IPC", False, True)) {
- return NULL;
- }
-
- /* Open a NT session thingy */
-
- if (!cli_nt_session_open(cli, PIPE_SRVSVC)) {
- cli_shutdown(cli);
- return NULL;
- }
-
- return cli;
-}
-
-/* Shut down a SMB connection to the srvsvc pipe */
-
-void cli_srvsvc_shutdown(struct cli_state *cli)
-{
- if (cli->fd != -1) cli_ulogoff(cli);
- cli_shutdown(cli);
+ return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds);
}
-uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 switch_value, SRV_INFO_CTR *ctr)
+NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ uint32 switch_value, SRV_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SRV_GET_INFO q;
SRV_R_NET_SRV_GET_INFO r;
- uint32 result;
+ NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 67eef52583f..16da673e73c 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -24,9 +24,9 @@
#include "includes.h"
-static struct {
+static const struct {
int prot;
- char *name;
+ const char *name;
}
prots[] =
{
@@ -43,11 +43,282 @@ prots[] =
/****************************************************************************
+do an old lanman2 style session setup
+****************************************************************************/
+static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user,
+ char *pass, int passlen)
+{
+ fstring pword;
+ char *p;
+
+ if (passlen > sizeof(pword)-1) {
+ return False;
+ }
+
+ /* if in share level security then don't send a password now */
+ if (!(cli->sec_mode & 1)) {
+ passlen = 0;
+ }
+
+ if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) {
+ /* Encrypted mode needed, and non encrypted password supplied. */
+ passlen = 24;
+ clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
+ SMBencrypt((uchar *)pword,cli->cryptkey,(uchar *)pword);
+ } else if ((cli->sec_mode & 2) && passlen == 24) {
+ /* Encrypted mode needed, and encrypted password supplied. */
+ memcpy(pword, pass, passlen);
+ } else if (passlen > 0) {
+ /* Plaintext mode needed, assume plaintext supplied. */
+ passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
+ }
+
+ /* send a session setup command */
+ memset(cli->outbuf,'\0',smb_size);
+ set_message(cli->outbuf,10, 0, True);
+ SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
+ cli_setup_packet(cli);
+
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
+ SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
+ SSVAL(cli->outbuf,smb_vwv3,2);
+ SSVAL(cli->outbuf,smb_vwv4,1);
+ SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
+
+ p = smb_buf(cli->outbuf);
+ memcpy(p,pword,passlen);
+ p += passlen;
+ p += clistr_push(cli, p, user, -1, STR_TERMINATE);
+ cli_setup_bcc(cli, p);
+
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli))
+ return False;
+
+ show_msg(cli->inbuf);
+
+ if (cli_is_error(cli)) {
+ return False;
+ }
+
+ /* use the returned vuid from now on */
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
+ fstrcpy(cli->user_name, user);
+
+ return True;
+}
+
+
+/****************************************************************************
+work out suitable capabilities to offer the server
+****************************************************************************/
+static uint32 cli_session_setup_capabilities(struct cli_state *cli)
+{
+ uint32 capabilities = CAP_NT_SMBS;
+
+ if (!cli->force_dos_errors) {
+ capabilities |= CAP_STATUS32;
+ }
+
+ if (cli->use_level_II_oplocks) {
+ capabilities |= CAP_LEVEL_II_OPLOCKS;
+ }
+
+ if (cli->capabilities & CAP_UNICODE) {
+ capabilities |= CAP_UNICODE;
+ }
+
+ return capabilities;
+}
+
+
+/****************************************************************************
+do a NT1 guest session setup
+****************************************************************************/
+static BOOL cli_session_setup_guest(struct cli_state *cli)
+{
+ char *p;
+ uint32 capabilities = cli_session_setup_capabilities(cli);
+
+ set_message(cli->outbuf,13,0,True);
+ SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
+ cli_setup_packet(cli);
+
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
+ SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
+ SSVAL(cli->outbuf,smb_vwv3,2);
+ SSVAL(cli->outbuf,smb_vwv4,cli->pid);
+ SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,0);
+ SSVAL(cli->outbuf,smb_vwv8,0);
+ SIVAL(cli->outbuf,smb_vwv11,capabilities);
+ p = smb_buf(cli->outbuf);
+ p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
+ p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
+ 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 False;
+
+ show_msg(cli->inbuf);
+
+ if (cli_is_error(cli)) {
+ return False;
+ }
+
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
+
+ p = smb_buf(cli->inbuf);
+ p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
+
+ fstrcpy(cli->user_name, "");
+
+ return True;
+}
+
+
+/****************************************************************************
+do a NT1 plaintext session setup
+****************************************************************************/
+static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
+ char *pass, char *workgroup)
+{
+ uint32 capabilities = cli_session_setup_capabilities(cli);
+ fstring pword;
+ int passlen;
+ char *p;
+
+ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+
+ set_message(cli->outbuf,13,0,True);
+ SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
+ cli_setup_packet(cli);
+
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
+ SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
+ SSVAL(cli->outbuf,smb_vwv3,2);
+ SSVAL(cli->outbuf,smb_vwv4,cli->pid);
+ SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
+ SSVAL(cli->outbuf,smb_vwv8,0);
+ SIVAL(cli->outbuf,smb_vwv11,capabilities);
+ p = smb_buf(cli->outbuf);
+ memcpy(p, pword, passlen);
+ p += passlen;
+ p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
+ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
+ 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 False;
+
+ show_msg(cli->inbuf);
+
+ if (cli_is_error(cli)) {
+ return False;
+ }
+
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
+ p = smb_buf(cli->inbuf);
+ p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
+ fstrcpy(cli->user_name, user);
+
+ return True;
+}
+
+
+/****************************************************************************
+do a NT1 NTLM/LM encrypted session setup
+****************************************************************************/
+static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *workgroup)
+{
+ uint32 capabilities = cli_session_setup_capabilities(cli);
+ fstring pword, ntpword;
+ char *p;
+
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+ return False;
+ }
+
+ if (passlen != 24) {
+ /* non encrypted password supplied. */
+ passlen = 24;
+ ntpasslen = 24;
+ clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+ clistr_push(cli, ntpword, ntpass, sizeof(ntpword), STR_TERMINATE);
+ SMBencrypt((uchar *)pword,cli->cryptkey,(uchar *)pword);
+ SMBNTencrypt((uchar *)ntpword,cli->cryptkey,(uchar *)ntpword);
+ } else {
+ memcpy(pword, pass, passlen);
+ memcpy(ntpword, ntpass, ntpasslen);
+ }
+
+ /* send a session setup command */
+ memset(cli->outbuf,'\0',smb_size);
+
+ set_message(cli->outbuf,13,0,True);
+ SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
+ cli_setup_packet(cli);
+
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
+ SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
+ SSVAL(cli->outbuf,smb_vwv3,2);
+ SSVAL(cli->outbuf,smb_vwv4,cli->pid);
+ SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
+ SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
+ SIVAL(cli->outbuf,smb_vwv11,capabilities);
+ 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, "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 False;
+
+ show_msg(cli->inbuf);
+
+ if (cli_is_error(cli)) {
+ return False;
+ }
+
+ /* use the returned vuid from now on */
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
+
+ p = smb_buf(cli->inbuf);
+ p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
+ p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
+
+ fstrcpy(cli->user_name, user);
+
+ return True;
+}
+
+/****************************************************************************
Send a session setup. The username and workgroup is in UNIX character
format and must be converted to DOS codepage format before sending. If the
password is in plaintext, the same should be done.
****************************************************************************/
-
BOOL cli_session_setup(struct cli_state *cli,
char *user,
char *pass, int passlen,
@@ -55,12 +326,11 @@ BOOL cli_session_setup(struct cli_state *cli,
char *workgroup)
{
char *p;
- fstring pword, ntpword;
fstring user2;
/* allow for workgroups as part of the username */
fstrcpy(user2, user);
- if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/'))) {
+ if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/')) || (p=strchr(user2,*lp_winbind_separator())) ) {
*p = 0;
user = p+1;
workgroup = user2;
@@ -69,138 +339,38 @@ BOOL cli_session_setup(struct cli_state *cli,
if (cli->protocol < PROTOCOL_LANMAN1)
return True;
- if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
- return False;
- }
+ /* now work out what sort of session setup we are going to
+ do. I have split this into separate functions to make the
+ flow a bit easier to understand (tridge) */
- if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) {
- /* Null session connect. */
- pword[0] = '\0';
- ntpword[0] = '\0';
- } else {
- if ((cli->sec_mode & 2) && passlen != 24) {
- /*
- * Encrypted mode needed, and non encrypted password supplied.
- */
- passlen = 24;
- ntpasslen = 24;
- fstrcpy(pword, pass);
- unix_to_dos(pword,True);
- fstrcpy(ntpword, ntpass);;
- SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword);
- SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword);
- } else if ((cli->sec_mode & 2) && passlen == 24) {
- /*
- * Encrypted mode needed, and encrypted password supplied.
- */
- memcpy(pword, pass, passlen);
- if(ntpasslen == 24) {
- memcpy(ntpword, ntpass, ntpasslen);
- } else {
- fstrcpy(ntpword, "");
- ntpasslen = 0;
- }
- } else {
- /*
- * Plaintext mode needed, assume plaintext supplied.
- */
- passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE);
- fstrcpy(ntpword, "");
- ntpasslen = 0;
- }
+ /* if its an older server then we have to use the older request format */
+ if (cli->protocol < PROTOCOL_NT1) {
+ return cli_session_setup_lanman2(cli, user, pass, passlen);
}
- /* if in share level security then don't send a password now */
- if (!(cli->sec_mode & 1)) {
- fstrcpy(pword, "");
- passlen=1;
- fstrcpy(ntpword, "");
- ntpasslen=1;
- }
-
- /* send a session setup command */
- memset(cli->outbuf,'\0',smb_size);
-
- if (cli->protocol < PROTOCOL_NT1)
- {
- set_message(cli->outbuf,10, 0, True);
- CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
- cli_setup_packet(cli);
-
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
- SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
- SSVAL(cli->outbuf,smb_vwv3,2);
- SSVAL(cli->outbuf,smb_vwv4,1);
- SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
- SSVAL(cli->outbuf,smb_vwv7,passlen);
- p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
- p += passlen;
- p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_UPPER|STR_TERMINATE);
- cli_setup_bcc(cli, p);
+ /* if no user is supplied then we have to do an anonymous connection.
+ passwords are ignored */
+ if (!user || !*user) {
+ return cli_session_setup_guest(cli);
}
- else
- {
- uint32 capabilities;
-
- capabilities = CAP_NT_SMBS;
- if (cli->use_level_II_oplocks) {
- capabilities |= CAP_LEVEL_II_OPLOCKS;
- }
- if (cli->capabilities & CAP_UNICODE) {
- capabilities |= CAP_UNICODE;
- }
- set_message(cli->outbuf,13,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
- cli_setup_packet(cli);
-
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
- SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
- SSVAL(cli->outbuf,smb_vwv3,2);
- SSVAL(cli->outbuf,smb_vwv4,cli->pid);
- SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
- SSVAL(cli->outbuf,smb_vwv7,passlen);
- SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
- SIVAL(cli->outbuf,smb_vwv11,capabilities);
- p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
- p += SVAL(cli->outbuf,smb_vwv7);
- memcpy(p,ntpword,ntpasslen);
- p += SVAL(cli->outbuf,smb_vwv8);
- p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
- p += clistr_push(cli, p, workgroup, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
- p += clistr_push(cli, p, "Unix", -1, STR_CONVERT|STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_CONVERT|STR_TERMINATE);
- cli_setup_bcc(cli, p);
- }
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
-
- show_msg(cli->inbuf);
-
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- return False;
- }
- /* use the returned vuid from now on */
- cli->vuid = SVAL(cli->inbuf,smb_uid);
-
- if (cli->protocol >= PROTOCOL_NT1) {
- /*
- * Save off some of the connected server
- * info.
- */
- char *q = smb_buf(cli->inbuf);
- q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
- q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
- q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT);
- }
+ /* 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 & 1) == 0) {
+ return cli_session_setup_plaintext(cli, user, "", workgroup);
+ }
- fstrcpy(cli->user_name, user);
+ /* if the server doesn't support encryption then we have to use plaintext. The
+ second password is ignored */
+ if ((cli->sec_mode & 2) == 0) {
+ return cli_session_setup_plaintext(cli, user, pass, workgroup);
+ }
- return True;
+ /* Do a NT1 style session setup */
+ return cli_session_setup_nt1(cli, user,
+ pass, passlen, ntpass, ntpasslen,
+ workgroup);
}
/****************************************************************************
@@ -211,7 +381,7 @@ BOOL cli_ulogoff(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
- CVAL(cli->outbuf,smb_com) = SMBulogoffX;
+ SCVAL(cli->outbuf,smb_com,SMBulogoffX);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
@@ -220,14 +390,14 @@ BOOL cli_ulogoff(struct cli_state *cli)
if (!cli_receive_smb(cli))
return False;
- return CVAL(cli->inbuf,smb_rcls) == 0;
+ return !cli_is_error(cli);
}
/****************************************************************************
send a tconX
****************************************************************************/
BOOL cli_send_tconX(struct cli_state *cli,
- char *share, char *dev, char *pass, int passlen)
+ const char *share, const char *dev, const char *pass, int passlen)
{
fstring fullshare, pword, dos_pword;
char *p;
@@ -247,9 +417,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
* Non-encrypted passwords - convert to DOS codepage before encryption.
*/
passlen = 24;
- fstrcpy(dos_pword,pass);
- unix_to_dos(dos_pword,True);
- SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword);
+ clistr_push(cli, dos_pword, pass, -1, STR_CONVERT|STR_TERMINATE);
+ SMBencrypt((uchar *)dos_pword,cli->cryptkey,(uchar *)pword);
} else {
if((cli->sec_mode & 3) == 0) {
/*
@@ -261,13 +430,16 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
}
- slprintf(fullshare, sizeof(fullshare)-1,
- "\\\\%s\\%s", cli->desthost, share);
- unix_to_dos(fullshare, True);
- strupper(fullshare);
+ if (cli->port == 445) {
+ slprintf(fullshare, sizeof(fullshare)-1,
+ "%s", share);
+ } else {
+ slprintf(fullshare, sizeof(fullshare)-1,
+ "\\\\%s\\%s", cli->desthost, share);
+ }
set_message(cli->outbuf,4, 0, True);
- CVAL(cli->outbuf,smb_com) = SMBtconX;
+ SCVAL(cli->outbuf,smb_com,SMBtconX);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
@@ -276,25 +448,23 @@ BOOL cli_send_tconX(struct cli_state *cli,
p = smb_buf(cli->outbuf);
memcpy(p,pword,passlen);
p += passlen;
- p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE);
+ p += clistr_push(cli, p, fullshare, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER);
fstrcpy(p, dev); p += strlen(dev)+1;
cli_setup_bcc(cli, p);
- SCVAL(cli->inbuf,smb_rcls, 1);
-
cli_send_smb(cli);
if (!cli_receive_smb(cli))
return False;
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
fstrcpy(cli->dev, "A:");
if (cli->protocol >= PROTOCOL_NT1) {
- clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE | STR_CONVERT);
+ clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE);
}
if (strcasecmp(share,"IPC$")==0) {
@@ -320,7 +490,7 @@ BOOL cli_tdis(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
- CVAL(cli->outbuf,smb_com) = SMBtdis;
+ SCVAL(cli->outbuf,smb_com,SMBtdis);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -328,7 +498,7 @@ BOOL cli_tdis(struct cli_state *cli)
if (!cli_receive_smb(cli))
return False;
- return CVAL(cli->inbuf,smb_rcls) == 0;
+ return !cli_is_error(cli);
}
@@ -350,16 +520,14 @@ void cli_negprot_send(struct cli_state *cli)
prots[numprots].name && prots[numprots].prot<=cli->protocol;
numprots++) {
*p++ = 2;
- pstrcpy(p,prots[numprots].name);
- unix_to_dos(p,True);
- p += strlen(p) + 1;
+ p += clistr_push(cli, p, prots[numprots].name, -1, STR_CONVERT|STR_TERMINATE);
}
- CVAL(cli->outbuf,smb_com) = SMBnegprot;
+ SCVAL(cli->outbuf,smb_com,SMBnegprot);
cli_setup_bcc(cli, p);
cli_setup_packet(cli);
- CVAL(smb_buf(cli->outbuf),0) = 2;
+ SCVAL(smb_buf(cli->outbuf),0,2);
cli_send_smb(cli);
}
@@ -389,15 +557,13 @@ BOOL cli_negprot(struct cli_state *cli)
prots[numprots].name && prots[numprots].prot<=cli->protocol;
numprots++) {
*p++ = 2;
- pstrcpy(p,prots[numprots].name);
- unix_to_dos(p,True);
- p += strlen(p) + 1;
+ p += clistr_push(cli, p, prots[numprots].name, -1, STR_CONVERT|STR_TERMINATE);
}
- CVAL(cli->outbuf,smb_com) = SMBnegprot;
+ SCVAL(cli->outbuf,smb_com,SMBnegprot);
cli_setup_packet(cli);
- CVAL(smb_buf(cli->outbuf),0) = 2;
+ SCVAL(smb_buf(cli->outbuf),0,2);
cli_send_smb(cli);
if (!cli_receive_smb(cli))
@@ -405,14 +571,13 @@ BOOL cli_negprot(struct cli_state *cli)
show_msg(cli->inbuf);
- if (CVAL(cli->inbuf,smb_rcls) != 0 ||
+ if (cli_is_error(cli) ||
((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
return(False);
}
cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
-
if (cli->protocol >= PROTOCOL_NT1) {
/* NT protocol */
cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
@@ -433,7 +598,7 @@ BOOL cli_negprot(struct cli_state *cli)
if (smb_buflen(cli->inbuf) > 8) {
clistr_pull(cli, cli->server_domain,
smb_buf(cli->inbuf)+8, sizeof(cli->server_domain),
- smb_buflen(cli->inbuf)-8, STR_CONVERT|STR_UNICODE|STR_NOALIGN);
+ smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
}
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
@@ -473,8 +638,10 @@ BOOL cli_session_request(struct cli_state *cli,
int len = 4;
extern pstring user_socket_options;
- /* send a session request (RFC 1002) */
+ /* 445 doesn't have session request */
+ if (cli->port == 445) return True;
+ /* send a session request (RFC 1002) */
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
@@ -490,7 +657,7 @@ BOOL cli_session_request(struct cli_state *cli,
/* setup the packet length */
_smb_setlen(cli->outbuf,len);
- CVAL(cli->outbuf,0) = 0x81;
+ SCVAL(cli->outbuf,0,0x81);
#ifdef WITH_SSL
retry:
@@ -565,28 +732,50 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
extern struct in_addr ipzero;
extern pstring user_socket_options;
+ int name_type = 0x20;
+ char *p;
+
+ /* reasonable default hostname */
+ if (!host)
+ host = "*SMBSERVER";
fstrcpy(cli->desthost, host);
+ /* allow hostnames of the form NAME#xx and do a netbios lookup */
+ if ((p = strchr(cli->desthost, '#'))) {
+ name_type = strtol(p+1, NULL, 16);
+ *p = 0;
+ }
+
if (!ip || ip_equal(*ip, ipzero)) {
- if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) {
- return False;
- }
- if (ip) *ip = cli->dest_ip;
+ if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
+ return False;
+ }
+ if (ip)
+ *ip = cli->dest_ip;
} else {
cli->dest_ip = *ip;
}
- if (cli->port == 0) cli->port = 139; /* Set to default */
-
if (getenv("LIBSMB_PROG")) {
cli->fd = sock_exec(getenv("LIBSMB_PROG"));
} else {
+ /* try 445 first, then 139 */
+ int port = cli->port?cli->port:445;
cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
- cli->port, cli->timeout);
+ port, cli->timeout);
+ if (cli->fd == -1 && cli->port == 0) {
+ port = 139;
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
+ port, cli->timeout);
+ }
+ if (cli->fd != -1) cli->port = port;
}
- if (cli->fd == -1)
+ if (cli->fd == -1) {
+ DEBUG(1,("Error connecting to %s (%s)\n",
+ inet_ntoa(*ip),strerror(errno)));
return False;
+ }
set_socket_options(cli->fd,user_socket_options);
@@ -594,57 +783,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
}
/****************************************************************************
-re-establishes a connection
-****************************************************************************/
-BOOL cli_reestablish_connection(struct cli_state *cli)
-{
- struct nmb_name calling;
- struct nmb_name called;
- fstring dest_host;
- fstring share;
- fstring dev;
- BOOL do_tcon = False;
- int oldfd = cli->fd;
-
- if (!cli->initialised || cli->fd == -1)
- {
- DEBUG(3,("cli_reestablish_connection: not connected\n"));
- return False;
- }
-
- /* copy the parameters necessary to re-establish the connection */
-
- if (cli->cnum != 0)
- {
- fstrcpy(share, cli->share);
- fstrcpy(dev , cli->dev);
- do_tcon = True;
- }
-
- memcpy(&called , &(cli->called ), sizeof(called ));
- memcpy(&calling, &(cli->calling), sizeof(calling));
- fstrcpy(dest_host, cli->full_dest_host_name);
-
- DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
- nmb_namestr(&calling), nmb_namestr(&called),
- inet_ntoa(cli->dest_ip),
- cli->user_name, cli->domain));
-
- cli->fd = -1;
-
- if (cli_establish_connection(cli,
- dest_host, &cli->dest_ip,
- &calling, &called,
- share, dev, False, do_tcon)) {
- if ((cli->fd != oldfd) && (oldfd != -1)) {
- close( oldfd );
- }
- return True;
- }
- return False;
-}
-
-/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
BOOL cli_establish_connection(struct cli_state *cli,
@@ -669,7 +807,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
if (!cli_connect(cli, dest_host, dest_ip))
{
DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
- nmb_namestr(calling), inet_ntoa(*dest_ip)));
+ nmb_namestr(called), inet_ntoa(*dest_ip)));
return False;
}
}
@@ -742,8 +880,8 @@ BOOL cli_establish_connection(struct cli_state *cli,
unsigned char lm_sess_pwd[24];
/* creates (storing a copy of) and then obtains a 24 byte password OWF */
- pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
- pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
+ pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey);
+ pwd_get_lm_nt_owf(&cli->pwd, lm_sess_pwd, nt_sess_pwd);
/* attempt encrypted session */
if (!cli_session_setup(cli, cli->user_name,
@@ -762,9 +900,9 @@ BOOL cli_establish_connection(struct cli_state *cli,
if (*cli->server_domain || *cli->server_os || *cli->server_type)
{
DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
- cli->server_domain,
- cli->server_os,
- cli->server_type));
+ cli->server_domain,
+ cli->server_os,
+ cli->server_type));
}
if (do_tcon)
@@ -781,7 +919,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
}
if (do_shutdown)
- cli_shutdown(cli);
+ cli_shutdown(cli);
return True;
}
diff --git a/source/libsmb/clidgram.c b/source/libsmb/clidgram.c
index fc1453dce14..ded47b7d068 100644
--- a/source/libsmb/clidgram.c
+++ b/source/libsmb/clidgram.c
@@ -41,7 +41,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot,
char *ptr, *p2;
char tmp[4];
- bzero((char *)&p, sizeof(p));
+ memset((char *)&p, '\0', sizeof(p));
/*
* Next, build the DGRAM ...
@@ -71,7 +71,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot,
set_message(ptr,17,17 + len,True);
memcpy(ptr,tmp,4);
- CVAL(ptr,smb_com) = SMBtrans;
+ SCVAL(ptr,smb_com,SMBtrans);
SSVAL(ptr,smb_vwv1,len);
SSVAL(ptr,smb_vwv11,len);
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
@@ -183,7 +183,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
/* Now, bind a local addr to it ... Try port 138 first ... */
- bzero((char *)&sock_out, sizeof(sock_out));
+ memset((char *)&sock_out, '\0', sizeof(sock_out));
sock_out.sin_addr.s_addr = INADDR_ANY;
sock_out.sin_port = htons(138);
sock_out.sin_family = AF_INET;
@@ -213,8 +213,8 @@ int cli_get_backup_list(const char *myname, const char *send_to_name)
/* Now, build the request */
- bzero(cli_backup_list, sizeof(cli_backup_list));
- bzero(outbuf, sizeof(outbuf));
+ memset(cli_backup_list, '\0', sizeof(cli_backup_list));
+ memset(outbuf, '\0', sizeof(outbuf));
p = outbuf;
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 8d4a025fcc0..ca78ad8dde5 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -23,19 +23,13 @@
#include "includes.h"
-
-extern int DEBUGLEVEL;
-static void cli_process_oplock(struct cli_state *cli);
-
/*
* Change the port number used to call on
*/
int cli_set_port(struct cli_state *cli, int port)
{
- if (port > 0)
- cli->port = port;
-
- return cli->port;
+ cli->port = port;
+ return port;
}
/****************************************************************************
@@ -44,6 +38,10 @@ 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;
+
again:
ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
@@ -53,38 +51,47 @@ BOOL cli_receive_smb(struct cli_state *cli)
CVAL(cli->inbuf,smb_com) == SMBlockingX &&
SVAL(cli->inbuf,smb_vwv6) == 0 &&
SVAL(cli->inbuf,smb_vwv7) == 0) {
- if (cli->use_oplocks) cli_process_oplock(cli);
+ if (cli->oplock_handler) {
+ int fnum = SVAL(cli->inbuf,smb_vwv2);
+ unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
+ if (!cli->oplock_handler(cli, fnum, level)) return False;
+ }
/* try to prevent loops */
- CVAL(cli->inbuf,smb_com) = 0xFF;
+ SCVAL(cli->inbuf,smb_com,0xFF);
goto again;
}
}
+ /* If the server is not responding, note that now */
+
+ if (!ret) {
+ close(cli->fd);
+ cli->fd = -1;
+ }
+
return ret;
}
/****************************************************************************
- send an smb to a fd and re-establish if necessary
+ send an smb to a fd.
****************************************************************************/
+
BOOL cli_send_smb(struct cli_state *cli)
{
size_t len;
size_t nwritten=0;
ssize_t ret;
- BOOL reestablished=False;
+
+ /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
+ if (cli->fd == -1) return False;
len = smb_len(cli->outbuf) + 4;
while (nwritten < len) {
ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
- if (ret <= 0 && errno == EPIPE && !reestablished) {
- if (cli_reestablish_connection(cli)) {
- reestablished = True;
- nwritten=0;
- continue;
- }
- }
if (ret <= 0) {
+ close(cli->fd);
+ cli->fd = -1;
DEBUG(0,("Error writing %d bytes to client. %d\n",
(int)len,(int)ret));
return False;
@@ -101,7 +108,6 @@ setup basics in a outgoing packet
void cli_setup_packet(struct cli_state *cli)
{
cli->rap_error = 0;
- cli->nt_error = 0;
SSVAL(cli->outbuf,smb_pid,cli->pid);
SSVAL(cli->outbuf,smb_uid,cli->vuid);
SSVAL(cli->outbuf,smb_mid,cli->mid);
@@ -112,6 +118,9 @@ void cli_setup_packet(struct cli_state *cli)
if (cli->capabilities & CAP_UNICODE) {
flags2 |= FLAGS2_UNICODE_STRINGS;
}
+ if (cli->capabilities & CAP_STATUS32) {
+ flags2 |= FLAGS2_32_BIT_ERROR_CODES;
+ }
SSVAL(cli->outbuf,smb_flg2, flags2);
}
}
@@ -125,51 +134,6 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
}
-/****************************************************************************
-process an oplock break request from the server
-****************************************************************************/
-static void cli_process_oplock(struct cli_state *cli)
-{
- char *oldbuf = cli->outbuf;
- pstring buf;
- int fnum;
- unsigned char level;
-
- fnum = SVAL(cli->inbuf,smb_vwv2);
- level = CVAL(cli->inbuf,smb_vwv3+1);
-
- /* damn, we really need to keep a record of open files so we
- can detect a oplock break and a close crossing on the
- wire. for now this swallows the errors */
- if (fnum == 0) return;
-
- /* Ignore level II break to none's. */
- if (level == OPLOCKLEVEL_NONE)
- return;
-
- cli->outbuf = buf;
-
- memset(buf,'\0',smb_size);
- set_message(buf,8,0,True);
-
- CVAL(buf,smb_com) = SMBlockingX;
- SSVAL(buf,smb_tid, cli->cnum);
- cli_setup_packet(cli);
- SSVAL(buf,smb_vwv0,0xFF);
- SSVAL(buf,smb_vwv1,0);
- SSVAL(buf,smb_vwv2,fnum);
- if (cli->use_level_II_oplocks)
- SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */
- else
- SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */
- SIVAL(buf,smb_vwv4,0); /* timoeut */
- SSVAL(buf,smb_vwv6,0); /* unlockcount */
- SSVAL(buf,smb_vwv7,0); /* lockcount */
-
- cli_send_smb(cli);
-
- cli->outbuf = oldbuf;
-}
/****************************************************************************
initialise a client structure
@@ -194,11 +158,20 @@ initialise a client structure
****************************************************************************/
struct cli_state *cli_initialise(struct cli_state *cli)
{
+ BOOL alloced_cli = False;
+
+ /* Check the effective uid - make sure we are not setuid */
+ if (is_setuid_root()) {
+ DEBUG(0,("libsmb based programs must *NOT* be setuid root.\n"));
+ return NULL;
+ }
+
if (!cli) {
cli = (struct cli_state *)malloc(sizeof(*cli));
if (!cli)
return NULL;
ZERO_STRUCTP(cli);
+ alloced_cli = True;
}
if (cli->initialised) {
@@ -219,23 +192,41 @@ struct cli_state *cli_initialise(struct cli_state *cli)
cli->max_xmit = cli->bufsize;
cli->outbuf = (char *)malloc(cli->bufsize);
cli->inbuf = (char *)malloc(cli->bufsize);
- if (!cli->outbuf || !cli->inbuf)
- {
- return NULL;
+ cli->oplock_handler = cli_oplock_ack;
+ /* Set the CLI_FORCE_DOSERR environment variable to test
+ client routines using DOS errors instead of STATUS32
+ ones. This intended only as a temporary hack. */
+ if (getenv("CLI_FORCE_DOSERR")) {
+ cli->force_dos_errors = True;
}
- if ((cli->mem_ctx = talloc_init()) == NULL) {
- free(cli->outbuf);
- free(cli->inbuf);
- return NULL;
- }
+ if (!cli->outbuf || !cli->inbuf)
+ goto error;
+
+ if ((cli->mem_ctx = talloc_init()) == NULL)
+ goto error;
+
+ memset(cli->outbuf, 0, cli->bufsize);
+ memset(cli->inbuf, 0, cli->bufsize);
- memset(cli->outbuf, '\0', cli->bufsize);
- memset(cli->inbuf, '\0', cli->bufsize);
+ cli->nt_pipe_fnum = 0;
cli->initialised = 1;
+ cli->allocated = alloced_cli;
return cli;
+
+ /* Clean up after malloc() error */
+
+ error:
+
+ SAFE_FREE(cli->inbuf);
+ SAFE_FREE(cli->outbuf);
+
+ if (alloced_cli)
+ SAFE_FREE(cli);
+
+ return NULL;
}
/****************************************************************************
@@ -243,25 +234,24 @@ shutdown a client structure
****************************************************************************/
void cli_shutdown(struct cli_state *cli)
{
- if (cli->outbuf)
- {
- free(cli->outbuf);
- }
- if (cli->inbuf)
- {
- free(cli->inbuf);
- }
+ BOOL allocated;
+ SAFE_FREE(cli->outbuf);
+ SAFE_FREE(cli->inbuf);
if (cli->mem_ctx)
talloc_destroy(cli->mem_ctx);
#ifdef WITH_SSL
- if (cli->fd != -1)
- sslutil_disconnect(cli->fd);
+ if (cli->fd != -1)
+ sslutil_disconnect(cli->fd);
#endif /* WITH_SSL */
if (cli->fd != -1)
- close(cli->fd);
- memset(cli, 0, sizeof(*cli));
+ close(cli->fd);
+ allocated = cli->allocated;
+ ZERO_STRUCTP(cli);
+ if (allocated) {
+ SAFE_FREE(cli);
+ }
}
@@ -282,4 +272,3 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid)
cli->pid = pid;
return ret;
}
-
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index 2f0c0e66184..6957c2cec29 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -23,36 +23,36 @@
#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-
/*****************************************************
RAP error codes - a small start but will be extended.
*******************************************************/
-static struct
-{
- int err;
- char *message;
-} rap_errmap[] =
+static const struct
{
- {5, "User has insufficient privilege" },
- {86, "The specified password is invalid" },
- {2226, "Operation only permitted on a Primary Domain Controller" },
- {2242, "The password of this user has expired." },
- {2243, "The password of this user cannot change." },
- {2244, "This password cannot be used now (password history conflict)." },
- {2245, "The password is shorter than required." },
- {2246, "The password of this user is too recent to change."},
-
- /* these really shouldn't be here ... */
- {0x80, "Not listening on called name"},
- {0x81, "Not listening for calling name"},
- {0x82, "Called name not present"},
- {0x83, "Called name present, but insufficient resources"},
-
- {0, NULL}
+ int err;
+ char *message;
+} rap_errmap[] = {
+ {5, "RAP5: User has insufficient privilege" },
+ {50, "RAP50: Not supported by server" },
+ {65, "RAP65: Access denied" },
+ {86, "RAP86: The specified password is invalid" },
+ {2220, "RAP2220: Group does not exist" },
+ {2221, "RAP2221: User does not exist" },
+ {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" },
+ {2237, "RAP2237: User is not in group" },
+ {2242, "RAP2242: The password of this user has expired." },
+ {2243, "RAP2243: The password of this user cannot change." },
+ {2244, "RAP2244: This password cannot be used now (password history conflict)." },
+ {2245, "RAP2245: The password is shorter than required." },
+ {2246, "RAP2246: The password of this user is too recent to change."},
+
+ /* these really shouldn't be here ... */
+ {0x80, "Not listening on called name"},
+ {0x81, "Not listening for calling name"},
+ {0x82, "Called name not present"},
+ {0x83, "Called name present, but insufficient resources"},
+
+ {0, NULL}
};
/****************************************************************************
@@ -60,136 +60,97 @@ static struct
****************************************************************************/
static char *cli_smb_errstr(struct cli_state *cli)
{
- return smb_errstr(cli->inbuf);
+ return smb_dos_errstr(cli->inbuf);
}
-/******************************************************
- Return an error message - either an SMB error or a RAP
- error.
-*******************************************************/
+/***************************************************************************
+ Return an error message - either an NT error, SMB error or a RAP error.
+ Note some of the NT errors are actually warnings or "informational" errors
+ in which case they can be safely ignored.
+****************************************************************************/
char *cli_errstr(struct cli_state *cli)
{
- static fstring error_message;
- uint8 errclass;
- uint32 errnum;
- uint32 nt_rpc_error;
- int i;
-
- /*
- * Errors are of three kinds - smb errors,
- * dealt with by cli_smb_errstr, NT errors,
- * whose code is in cli.nt_error, and rap
- * errors, whose error code is in cli.rap_error.
- */
-
- cli_error(cli, &errclass, &errnum, &nt_rpc_error);
-
- if (errclass != 0)
- {
- return cli_smb_errstr(cli);
+ static fstring cli_error_message;
+ uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum;
+ uint8 errclass;
+ int i;
+
+ /* Case #1: RAP error */
+ if (cli->rap_error) {
+ for (i = 0; rap_errmap[i].message != NULL; i++) {
+ if (rap_errmap[i].err == cli->rap_error) {
+ return rap_errmap[i].message;
+ }
+ }
+
+ slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d",
+ cli->rap_error);
+
+ return cli_error_message;
}
- /*
- * Was it an NT error ?
- */
+ /* Case #2: 32-bit NT errors */
+ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
+ NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls));
- if (nt_rpc_error)
- {
- char *nt_msg = (char *)get_nt_error_msg(nt_rpc_error);
+ return get_nt_error_msg(status);
+ }
- if (nt_msg == NULL)
- {
- slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error);
- }
- else
- {
- fstrcpy(error_message, nt_msg);
- }
+ cli_dos_error(cli, &errclass, &errnum);
- return error_message;
- }
+ /* Case #3: SMB error */
- /*
- * Must have been a rap error.
- */
+ return cli_smb_errstr(cli);
+}
- slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error);
- for (i = 0; rap_errmap[i].message != NULL; i++)
- {
- if (rap_errmap[i].err == cli->rap_error)
- {
- fstrcpy( error_message, rap_errmap[i].message);
- break;
- }
- }
-
- return error_message;
-}
+/* Return the 32-bit NT status code from the last packet */
+NTSTATUS cli_nt_error(struct cli_state *cli)
+{
+ int flgs2 = SVAL(cli->inbuf,smb_flg2);
+ if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) {
+ int class = CVAL(cli->inbuf,smb_rcls);
+ int code = SVAL(cli->inbuf,smb_err);
+ return dos_to_ntstatus(class, code);
+ }
-/****************************************************************************
- return error codes for the last packet
- returns 0 if there was no error and the best approx of a unix errno
- otherwise
+ return NT_STATUS(IVAL(cli->inbuf,smb_rcls));
+}
- for 32 bit "warnings", a return code of 0 is expected.
-****************************************************************************/
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error)
+/* Return the DOS error from the last packet - an error class and an error
+ code. */
+void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)
{
int flgs2;
char rcls;
int code;
- if (eclass) *eclass = 0;
- if (num ) *num = 0;
- if (nt_rpc_error) *nt_rpc_error = 0;
-
- if(!cli->initialised)
- return EINVAL;
-
- if(!cli->inbuf)
- return ENOMEM;
+ if(!cli->initialised) return;
flgs2 = SVAL(cli->inbuf,smb_flg2);
- if (nt_rpc_error) *nt_rpc_error = cli->nt_error;
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
- /* 32 bit error codes detected */
- uint32 nt_err = IVAL(cli->inbuf,smb_rcls);
- if (num) *num = nt_err;
- DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err));
- if (!(nt_err & 0xc0000000))
- return 0;
-
- switch (nt_err) {
- case NT_STATUS_ACCESS_VIOLATION: return EACCES;
- case NT_STATUS_NO_SUCH_FILE: return ENOENT;
- case NT_STATUS_NO_SUCH_DEVICE: return ENODEV;
- case NT_STATUS_INVALID_HANDLE: return EBADF;
- case NT_STATUS_NO_MEMORY: return ENOMEM;
- case NT_STATUS_ACCESS_DENIED: return EACCES;
- case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
- case NT_STATUS_SHARING_VIOLATION: return EBUSY;
- case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR;
- case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
- }
-
- /* for all other cases - a default code */
- return EINVAL;
- }
+ NTSTATUS ntstatus = NT_STATUS(IVAL(cli->inbuf, smb_rcls));
+ ntstatus_to_dos(ntstatus, eclass, ecode);
+ return;
+ }
rcls = CVAL(cli->inbuf,smb_rcls);
code = SVAL(cli->inbuf,smb_err);
- if (rcls == 0) return 0;
if (eclass) *eclass = rcls;
- if (num ) *num = code;
+ if (ecode) *ecode = code;
+}
- if (rcls == ERRDOS) {
- switch (code) {
+/* Return a UNIX errno from a dos error class, error number tuple */
+
+int cli_errno_from_dos(uint8 eclass, uint32 num)
+{
+ if (eclass == ERRDOS) {
+ switch (num) {
case ERRbadfile: return ENOENT;
case ERRbadpath: return ENOTDIR;
case ERRnoaccess: return EACCES;
@@ -201,8 +162,9 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_
case ERRnosuchshare: return ENODEV;
}
}
- if (rcls == ERRSRV) {
- switch (code) {
+
+ if (eclass == ERRSRV) {
+ switch (num) {
case ERRbadpw: return EPERM;
case ERRaccess: return EACCES;
case ERRnoresource: return ENOMEM;
@@ -210,7 +172,101 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_
case ERRinvnetname: return ENODEV;
}
}
+
/* for other cases */
return EINVAL;
}
+/* Return a UNIX errno from a NT status code */
+static struct {
+ NTSTATUS status;
+ int error;
+} nt_errno_map[] = {
+ {NT_STATUS_ACCESS_VIOLATION, EACCES},
+ {NT_STATUS_NO_SUCH_FILE, ENOENT},
+ {NT_STATUS_NO_SUCH_DEVICE, ENODEV},
+ {NT_STATUS_INVALID_HANDLE, EBADF},
+ {NT_STATUS_NO_MEMORY, ENOMEM},
+ {NT_STATUS_ACCESS_DENIED, EACCES},
+ {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT},
+ {NT_STATUS_SHARING_VIOLATION, EBUSY},
+ {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR},
+ {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST},
+ {NT_STATUS_PATH_NOT_COVERED, ENOENT},
+ {NT_STATUS(0), 0}
+};
+
+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)));
+
+ /* Status codes without this bit set are not errors */
+
+ if (!(NT_STATUS_V(status) & 0xc0000000))
+ return 0;
+
+ for (i=0;nt_errno_map[i].error;i++) {
+ if (NT_STATUS_V(nt_errno_map[i].status) ==
+ NT_STATUS_V(status)) return nt_errno_map[i].error;
+ }
+
+ /* for all other cases - a default code */
+ return EINVAL;
+}
+
+/* Return a UNIX errno appropriate for the error received in the last
+ packet. */
+
+int cli_errno(struct cli_state *cli)
+{
+ NTSTATUS status;
+
+ if (cli_is_dos_error(cli)) {
+ uint8 eclass;
+ uint32 ecode;
+
+ cli_dos_error(cli, &eclass, &ecode);
+ return cli_errno_from_dos(eclass, ecode);
+ }
+
+ status = cli_nt_error(cli);
+
+ return cli_errno_from_nt(status);
+}
+
+/* Return true if the last packet was in error */
+
+BOOL cli_is_error(struct cli_state *cli)
+{
+ uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0;
+
+ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
+ /* Return error is error bits are set */
+ rcls = IVAL(cli->inbuf, smb_rcls);
+ return (rcls & 0xF0000000) == 0xC0000000;
+ }
+
+ /* Return error if error class in non-zero */
+
+ rcls = CVAL(cli->inbuf, smb_rcls);
+ return rcls != 0;
+}
+
+/* Return true if the last error was an NT error */
+
+BOOL cli_is_nt_error(struct cli_state *cli)
+{
+ uint32 flgs2 = SVAL(cli->inbuf,smb_flg2);
+
+ return cli_is_error(cli) && (flgs2 & FLAGS2_32_BIT_ERROR_CODES);
+}
+
+/* Return true if the last error was a DOS error */
+
+BOOL cli_is_dos_error(struct cli_state *cli)
+{
+ uint32 flgs2 = SVAL(cli->inbuf,smb_flg2);
+
+ return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES);
+}
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index d63b4817a47..52c553c1cdc 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -3,6 +3,7 @@
Version 3.0
client file operations
Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Jeremy Allison 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
@@ -24,49 +25,210 @@
#include "includes.h"
/****************************************************************************
-rename a file
+ Hard/Symlink a file (UNIX extensions).
****************************************************************************/
-BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
+
+static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link)
{
- char *p;
+ int data_len = 0;
+ int param_len = 0;
+ uint16 setup = TRANSACT2_SETPATHINFO;
+ char param[sizeof(pstring)+6];
+ pstring data;
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ memset(param, 0, sizeof(param));
+ SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
+ p = &param[6];
- set_message(cli->outbuf,1, 0, True);
+ p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
- CVAL(cli->outbuf,smb_com) = SMBmv;
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ p = data;
+ p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
+ data_len = PTR_DIFF(p, data);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
- SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+/****************************************************************************
+ Map standard UNIX permissions onto wire representations.
+****************************************************************************/
+
+uint32 unix_perms_to_wire(mode_t perms)
+{
+ uint ret = 0;
+
+ ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
+ ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
+ ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
+ ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
+ ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
+ ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
+ ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
+ ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
+ ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
+#ifdef S_ISVTX
+ ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
+#endif
+#ifdef S_ISGID
+ ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
+#endif
+#ifdef S_ISUID
+ ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0);
+#endif
+ return ret;
+}
+
+/****************************************************************************
+ Symlink a file (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+{
+ return cli_link_internal(cli, fname_src, fname_dst, False);
+}
+
+/****************************************************************************
+ Hard a file (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+{
+ return cli_link_internal(cli, fname_src, fname_dst, True);
+}
+
+/****************************************************************************
+ Chmod or chown a file internal (UNIX extensions).
+****************************************************************************/
- p = smb_buf(cli->outbuf);
- *p++ = 4;
- p += clistr_push(cli, p, fname_src, -1,
- STR_TERMINATE | STR_CONVERT);
- *p++ = 4;
- p += clistr_push(cli, p, fname_dst, -1,
- STR_TERMINATE | STR_CONVERT);
+static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid)
+{
+ int data_len = 0;
+ int param_len = 0;
+ uint16 setup = TRANSACT2_SETPATHINFO;
+ char param[sizeof(pstring)+6];
+ char data[100];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ memset(param, 0, sizeof(param));
+ memset(data, 0, sizeof(data));
+ SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC);
+ p = &param[6];
+
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ SIVAL(data,40,uid);
+ SIVAL(data,48,gid);
+ SIVAL(data,84,mode);
+
+ data_len = 100;
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+/****************************************************************************
+ chmod a file (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
+{
+ return cli_unix_chmod_chown_internal(cli, fname,
+ unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE);
+}
+
+/****************************************************************************
+ chown a file (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid)
+{
+ return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid);
+}
+
+/****************************************************************************
+ Rename a file.
+****************************************************************************/
+
+BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
+{
+ char *p;
+
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
+
+ set_message(cli->outbuf,1, 0, True);
+
+ SCVAL(cli->outbuf,smb_com,SMBmv);
+ SSVAL(cli->outbuf,smb_tid,cli->cnum);
+ cli_setup_packet(cli);
+
+ SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
+
+ p = smb_buf(cli->outbuf);
+ *p++ = 4;
+ p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
+ *p++ = 4;
+ p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return False;
- }
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli))
+ return False;
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- return False;
- }
+ if (cli_is_error(cli))
+ return False;
- return True;
+ return True;
}
/****************************************************************************
-delete a file
+ Delete a file.
****************************************************************************/
-BOOL cli_unlink(struct cli_state *cli, char *fname)
+
+BOOL cli_unlink(struct cli_state *cli, const char *fname)
{
char *p;
@@ -75,7 +237,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
set_message(cli->outbuf,1, 0,True);
- CVAL(cli->outbuf,smb_com) = SMBunlink;
+ SCVAL(cli->outbuf,smb_com,SMBunlink);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -83,7 +245,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
@@ -91,7 +253,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -99,9 +261,10 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
}
/****************************************************************************
-create a directory
+ Create a directory.
****************************************************************************/
-BOOL cli_mkdir(struct cli_state *cli, char *dname)
+
+BOOL cli_mkdir(struct cli_state *cli, const char *dname)
{
char *p;
@@ -110,13 +273,13 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
set_message(cli->outbuf,0, 0,True);
- CVAL(cli->outbuf,smb_com) = SMBmkdir;
+ SCVAL(cli->outbuf,smb_com,SMBmkdir);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, dname, -1, STR_CONVERT|STR_TERMINATE);
+ p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -125,7 +288,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -133,9 +296,10 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
}
/****************************************************************************
-remove a directory
+ Remove a directory.
****************************************************************************/
-BOOL cli_rmdir(struct cli_state *cli, char *dname)
+
+BOOL cli_rmdir(struct cli_state *cli, const char *dname)
{
char *p;
@@ -144,13 +308,13 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
set_message(cli->outbuf,0, 0, True);
- CVAL(cli->outbuf,smb_com) = SMBrmdir;
+ SCVAL(cli->outbuf,smb_com,SMBrmdir);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -159,7 +323,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -176,7 +340,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
int param_len = 6;
uint16 setup = TRANSACT2_SETFILEINFO;
pstring param;
- char data;
+ unsigned char data;
char *rparam=NULL, *rdata=NULL;
memset(param, 0, param_len);
@@ -186,33 +350,33 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
data = flag ? 1 : 0;
if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- &data, data_len, cli->max_xmit /* data, length, max */
- )) {
- return False;
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ (char *)&data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
}
if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return False;
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
}
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
/****************************************************************************
- open a file - exposing the full horror of the NT API :-).
+ Open a file - exposing the full horror of the NT API :-).
Used in smbtorture.
****************************************************************************/
-int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
+int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess,
uint32 FileAttributes, uint32 ShareAccess,
uint32 CreateDisposition, uint32 CreateOptions)
{
@@ -224,7 +388,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
set_message(cli->outbuf,24,0,True);
- CVAL(cli->outbuf,smb_com) = SMBntcreateX;
+ SCVAL(cli->outbuf,smb_com,SMBntcreateX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -243,8 +407,8 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
p = smb_buf(cli->outbuf);
/* this alignment and termination is critical for netapp filers. Don't change */
- p += clistr_align_out(cli, p, STR_CONVERT);
- len = clistr_push(cli, p, fname, -1, STR_CONVERT);
+ p += clistr_align_out(cli, p, 0);
+ len = clistr_push(cli, p, fname, -1, 0);
p += len;
SSVAL(cli->outbuf,smb_ntcreate_NameLength, len);
/* sigh. this copes with broken netapp filer behaviour */
@@ -257,7 +421,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
return -1;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return -1;
}
@@ -265,20 +429,21 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess,
}
/****************************************************************************
-open a file
+ Open a file.
****************************************************************************/
-int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess)
+int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)
{
return cli_nt_create_full(cli, fname, DesiredAccess, 0,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0);
}
/****************************************************************************
-open a file
-WARNING: if you open with O_WRONLY then getattrE won't work!
+ Open a file
+ WARNING: if you open with O_WRONLY then getattrE won't work!
****************************************************************************/
-int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
+
+int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode)
{
char *p;
unsigned openfn=0;
@@ -316,7 +481,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
set_message(cli->outbuf,15,0,True);
- CVAL(cli->outbuf,smb_com) = SMBopenX;
+ SCVAL(cli->outbuf,smb_com,SMBopenX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -330,13 +495,13 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
if (cli->use_oplocks) {
/* if using oplocks then ask for a batch oplock via
core and extended methods */
- CVAL(cli->outbuf,smb_flg) |=
- FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
+ SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)|
+ FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK);
SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
}
p = smb_buf(cli->outbuf);
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -345,19 +510,17 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
return -1;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return -1;
}
return SVAL(cli->inbuf,smb_vwv2);
}
-
-
-
/****************************************************************************
- close a file
+ Close a file.
****************************************************************************/
+
BOOL cli_close(struct cli_state *cli, int fnum)
{
memset(cli->outbuf,'\0',smb_size);
@@ -365,7 +528,7 @@ BOOL cli_close(struct cli_state *cli, int fnum)
set_message(cli->outbuf,3,0,True);
- CVAL(cli->outbuf,smb_com) = SMBclose;
+ SCVAL(cli->outbuf,smb_com,SMBclose);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -377,35 +540,31 @@ BOOL cli_close(struct cli_state *cli, int fnum)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- return False;
- }
-
- return True;
+ return !cli_is_error(cli);
}
-
/****************************************************************************
- lock a file
+ Lock a file.
****************************************************************************/
+
BOOL cli_lock(struct cli_state *cli, int fnum,
uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
{
char *p;
- int saved_timeout = cli->timeout;
+ int saved_timeout = cli->timeout;
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0', smb_size);
set_message(cli->outbuf,8,0,True);
- CVAL(cli->outbuf,smb_com) = SMBlockingX;
+ SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
- CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0);
+ SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0));
SIVALS(cli->outbuf, smb_vwv4, timeout);
SSVAL(cli->outbuf,smb_vwv6,0);
SSVAL(cli->outbuf,smb_vwv7,1);
@@ -421,16 +580,16 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
cli_send_smb(cli);
- cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
if (!cli_receive_smb(cli)) {
- cli->timeout = saved_timeout;
+ cli->timeout = saved_timeout;
return False;
}
cli->timeout = saved_timeout;
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -438,8 +597,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
}
/****************************************************************************
- unlock a file
+ Unlock a file.
****************************************************************************/
+
BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
{
char *p;
@@ -449,13 +609,13 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
set_message(cli->outbuf,8,0,True);
- CVAL(cli->outbuf,smb_com) = SMBlockingX;
+ SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
- CVAL(cli->outbuf,smb_vwv3) = 0;
+ SCVAL(cli->outbuf,smb_vwv3,0);
SIVALS(cli->outbuf, smb_vwv4, 0);
SSVAL(cli->outbuf,smb_vwv6,1);
SSVAL(cli->outbuf,smb_vwv7,0);
@@ -471,17 +631,17 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
return True;
}
-
/****************************************************************************
- lock a file with 64 bit offsets
+ Lock a file with 64 bit offsets.
****************************************************************************/
+
BOOL cli_lock64(struct cli_state *cli, int fnum,
SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type)
{
@@ -501,13 +661,13 @@ BOOL cli_lock64(struct cli_state *cli, int fnum,
set_message(cli->outbuf,8,0,True);
- CVAL(cli->outbuf,smb_com) = SMBlockingX;
+ SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
- CVAL(cli->outbuf,smb_vwv3) = ltype;
+ SCVAL(cli->outbuf,smb_vwv3,ltype);
SIVALS(cli->outbuf, smb_vwv4, timeout);
SSVAL(cli->outbuf,smb_vwv6,0);
SSVAL(cli->outbuf,smb_vwv7,1);
@@ -530,7 +690,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum,
cli->timeout = saved_timeout;
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -538,8 +698,9 @@ BOOL cli_lock64(struct cli_state *cli, int fnum,
}
/****************************************************************************
- unlock a file with 64 bit offsets
+ Unlock a file with 64 bit offsets.
****************************************************************************/
+
BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
{
char *p;
@@ -553,13 +714,13 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
set_message(cli->outbuf,8,0,True);
- CVAL(cli->outbuf,smb_com) = SMBlockingX;
+ SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
- CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES;
+ SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES);
SIVALS(cli->outbuf, smb_vwv4, 0);
SSVAL(cli->outbuf,smb_vwv6,1);
SSVAL(cli->outbuf,smb_vwv7,0);
@@ -575,20 +736,17 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
return True;
}
-
-
-
-
/****************************************************************************
-do a SMBgetattrE call
+ Do a SMBgetattrE call.
****************************************************************************/
+
BOOL cli_getattrE(struct cli_state *cli, int fd,
uint16 *attr, size_t *size,
time_t *c_time, time_t *a_time, time_t *m_time)
@@ -598,7 +756,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
set_message(cli->outbuf,1,0,True);
- CVAL(cli->outbuf,smb_com) = SMBgetattrE;
+ SCVAL(cli->outbuf,smb_com,SMBgetattrE);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -609,7 +767,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -636,11 +794,11 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
return True;
}
-
/****************************************************************************
-do a SMBgetatr call
+ Do a SMBgetatr call
****************************************************************************/
-BOOL cli_getatr(struct cli_state *cli, char *fname,
+
+BOOL cli_getatr(struct cli_state *cli, const char *fname,
uint16 *attr, size_t *size, time_t *t)
{
char *p;
@@ -650,13 +808,13 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
set_message(cli->outbuf,0,0,True);
- CVAL(cli->outbuf,smb_com) = SMBgetatr;
+ SCVAL(cli->outbuf,smb_com,SMBgetatr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -665,7 +823,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
@@ -685,11 +843,11 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
return True;
}
-
/****************************************************************************
-do a SMBsetatr call
+ Do a SMBsetatr call.
****************************************************************************/
-BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
+
+BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
{
char *p;
@@ -698,7 +856,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
set_message(cli->outbuf,8,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsetatr;
+ SCVAL(cli->outbuf,smb_com,SMBsetatr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -707,7 +865,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
*p++ = 4;
cli_setup_bcc(cli, p);
@@ -717,18 +875,18 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
return False;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return False;
}
return True;
}
-
/****************************************************************************
-check for existance of a dir
+ Check for existance of a dir.
****************************************************************************/
-BOOL cli_chkpath(struct cli_state *cli, char *path)
+
+BOOL cli_chkpath(struct cli_state *cli, const char *path)
{
pstring path2;
char *p;
@@ -744,7 +902,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path)
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, path2, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, path2, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -753,21 +911,20 @@ BOOL cli_chkpath(struct cli_state *cli, char *path)
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_is_error(cli)) return False;
return True;
}
-
-
/****************************************************************************
-query disk space
+ Query disk space.
****************************************************************************/
+
BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
- CVAL(cli->outbuf,smb_com) = SMBdskattr;
+ SCVAL(cli->outbuf,smb_com,SMBdskattr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -783,42 +940,53 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
return True;
}
-
/****************************************************************************
-create and open a temporary file
+ Create and open a temporary file.
****************************************************************************/
-int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path)
+
+int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
{
+ int len;
char *p;
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,1,strlen(path)+2,True);
+ set_message(cli->outbuf,3,0,True);
- CVAL(cli->outbuf,smb_com) = SMBctemp;
+ SCVAL(cli->outbuf,smb_com,SMBctemp);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0);
+ SIVALS(cli->outbuf,smb_vwv1,-1);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, path, -1, STR_TERMINATE);
+
+ cli_setup_bcc(cli, p);
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return -1;
}
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_is_error(cli)) {
return -1;
}
+ /* despite the spec, the result has a -1, followed by
+ length, followed by name */
+ p = smb_buf(cli->inbuf);
+ p += 4;
+ len = smb_buflen(cli->inbuf) - 4;
+ if (len <= 0) return -1;
+
if (tmp_path) {
pstring path2;
- clistr_pull(cli, path2, smb_buf(cli->inbuf)+1,
- sizeof(path2), -1, STR_TERMINATE | STR_CONVERT);
+ clistr_pull(cli, path2, p,
+ sizeof(path2), len, STR_ASCII);
*tmp_path = strdup(path2);
}
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index a04c691fa49..0c80044b68f 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -34,121 +34,95 @@ static int interpret_long_filename(struct cli_state *cli,
int level,char *p,file_info *finfo)
{
extern file_info def_finfo;
+ file_info finfo2;
+ int len;
+ char *base = p;
- if (finfo)
- memcpy(finfo,&def_finfo,sizeof(*finfo));
+ if (!finfo) finfo = &finfo2;
+
+ memcpy(finfo,&def_finfo,sizeof(*finfo));
switch (level)
{
case 1: /* OS/2 understands this */
- if (finfo) {
- /* these dates are converted to GMT by make_unix_date */
- finfo->ctime = make_unix_date2(p+4);
- finfo->atime = make_unix_date2(p+8);
- finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- clistr_pull(cli, finfo->name, p+27,
- sizeof(finfo->name),
- -1,
- STR_TERMINATE | STR_CONVERT);
- }
- return(28 + CVAL(p,26));
+ /* these dates are converted to GMT by
+ make_unix_date */
+ finfo->ctime = make_unix_date2(p+4);
+ finfo->atime = make_unix_date2(p+8);
+ finfo->mtime = make_unix_date2(p+12);
+ finfo->size = IVAL(p,16);
+ finfo->mode = CVAL(p,24);
+ len = CVAL(p, 26);
+ p += 27;
+ p += clistr_align_in(cli, p, 0);
+ p += clistr_pull(cli, finfo->name, p,
+ sizeof(finfo->name),
+ len,
+ STR_TERMINATE);
+ return PTR_DIFF(p, base);
case 2: /* this is what OS/2 uses mostly */
- if (finfo) {
- /* these dates are converted to GMT by make_unix_date */
- finfo->ctime = make_unix_date2(p+4);
- finfo->atime = make_unix_date2(p+8);
- finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- clistr_pull(cli, finfo->name, p+31,
- sizeof(finfo->name),
- -1,
- STR_TERMINATE | STR_CONVERT);
- }
- return(32 + CVAL(p,30));
-
- /* levels 3 and 4 are untested */
- case 3:
- if (finfo) {
- /* these dates are probably like the other ones */
- finfo->ctime = make_unix_date2(p+8);
- finfo->atime = make_unix_date2(p+12);
- finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- clistr_pull(cli, finfo->name, p+33,
- sizeof(finfo->name),
- -1,
- STR_TERMINATE | STR_CONVERT);
- }
- return(SVAL(p,4)+4);
-
- case 4:
- if (finfo) {
- /* these dates are probably like the other ones */
- finfo->ctime = make_unix_date2(p+8);
- finfo->atime = make_unix_date2(p+12);
- finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- clistr_pull(cli, finfo->name, p+37,
- sizeof(finfo->name),
- -1,
- STR_TERMINATE | STR_CONVERT);
- }
- return(SVAL(p,4)+4);
+ /* these dates are converted to GMT by
+ make_unix_date */
+ finfo->ctime = make_unix_date2(p+4);
+ finfo->atime = make_unix_date2(p+8);
+ finfo->mtime = make_unix_date2(p+12);
+ finfo->size = IVAL(p,16);
+ finfo->mode = CVAL(p,24);
+ len = CVAL(p, 30);
+ p += 31;
+ /* check for unisys! */
+ p += clistr_pull(cli, finfo->name, p,
+ sizeof(finfo->name),
+ len,
+ STR_NOALIGN);
+ return PTR_DIFF(p, base) + 1;
case 260: /* NT uses this, but also accepts 2 */
- if (finfo) {
- int ret = SVAL(p,0);
- int namelen;
- p += 4; /* next entry offset */
- p += 4; /* fileindex */
+ {
+ int namelen, slen;
+ p += 4; /* next entry offset */
+ p += 4; /* fileindex */
- /* these dates appear to arrive in a
- weird way. It seems to be localtime
- plus the serverzone given in the
- initial connect. This is GMT when
- DST is not in effect and one hour
- from GMT otherwise. Can this really
- be right??
-
- I suppose this could be called
- kludge-GMT. Is is the GMT you get
- by using the current DST setting on
- a different localtime. It will be
- cheap to calculate, I suppose, as
- no DST tables will be needed */
-
- finfo->ctime = interpret_long_date(p); p += 8;
- finfo->atime = interpret_long_date(p); p += 8;
- finfo->mtime = interpret_long_date(p); p += 8; p += 8;
- finfo->size = IVAL(p,0); p += 8;
- p += 8; /* alloc size */
- finfo->mode = CVAL(p,0); p += 4;
- namelen = IVAL(p,0); p += 4;
- p += 4; /* EA size */
- /* slen = SVAL(p, 0); */
- p += 2;
- {
- /* stupid NT bugs. grr */
- int flags = STR_CONVERT;
- if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
- clistr_pull(cli, finfo->short_name, p,
- sizeof(finfo->short_name),
- 24, flags);
- }
- p += 24; /* short name? */
- clistr_pull(cli, finfo->name, p,
- sizeof(finfo->name),
- namelen,
- STR_CONVERT);
- return(ret);
+ /* these dates appear to arrive in a
+ weird way. It seems to be localtime
+ plus the serverzone given in the
+ initial connect. This is GMT when
+ DST is not in effect and one hour
+ from GMT otherwise. Can this really
+ be right??
+
+ I suppose this could be called
+ kludge-GMT. Is is the GMT you get
+ by using the current DST setting on
+ a different localtime. It will be
+ cheap to calculate, I suppose, as
+ no DST tables will be needed */
+
+ finfo->ctime = interpret_long_date(p); p += 8;
+ finfo->atime = interpret_long_date(p); p += 8;
+ finfo->mtime = interpret_long_date(p); p += 8; p += 8;
+ finfo->size = IVAL(p,0); p += 8;
+ p += 8; /* alloc size */
+ finfo->mode = CVAL(p,0); p += 4;
+ namelen = IVAL(p,0); p += 4;
+ p += 4; /* EA size */
+ slen = SVAL(p, 0);
+ p += 2;
+ {
+ /* stupid NT bugs. grr */
+ int flags = 0;
+ if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE;
+ clistr_pull(cli, finfo->short_name, p,
+ sizeof(finfo->short_name),
+ slen, flags);
}
- return(SVAL(p,0));
+ p += 24; /* short name? */
+ clistr_pull(cli, finfo->name, p,
+ sizeof(finfo->name),
+ namelen, 0);
+ return SVAL(base, 0);
+ }
}
DEBUG(1,("Unknown long filename format %d\n",level));
@@ -168,7 +142,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
pstring mask;
file_info finfo;
int i;
- char *dirlist = NULL;
+ char *tdl, *dirlist = NULL;
int dirlist_len = 0;
int total_received = -1;
BOOL First = True;
@@ -203,7 +177,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SIVAL(param,8,0);
p = param+12;
p += clistr_push(cli, param+12, mask, -1,
- STR_TERMINATE | STR_CONVERT);
+ STR_TERMINATE);
} else {
setup = TRANSACT2_FINDNEXT;
SSVAL(param,0,ff_dir_handle);
@@ -213,7 +187,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,10,8+4+2); /* continue + resume required + close on end */
p = param+12;
p += clistr_push(cli, param+12, mask, -1,
- STR_TERMINATE | STR_CONVERT);
+ STR_TERMINATE);
}
param_len = PTR_DIFF(p, param);
@@ -231,17 +205,21 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
if (!cli_receive_trans(cli, SMBtrans2,
&rparam, &param_len,
- &rdata, &data_len)) {
+ &rdata, &data_len) &&
+ cli_is_dos_error(cli)) {
/* we need to work around a Win95 bug - sometimes
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode, NULL);
+ cli_dos_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
continue;
}
+ if (cli_is_error(cli) || !rdata || !rparam)
+ break;
+
if (total_received == -1) total_received = 0;
/* parse out some important return info */
@@ -271,15 +249,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
clistr_pull(cli, mask, p+ff_lastname,
sizeof(mask),
data_len-ff_lastname,
- STR_TERMINATE |
- STR_CONVERT);
+ STR_TERMINATE);
break;
case 1:
clistr_pull(cli, mask, p+ff_lastname+1,
sizeof(mask),
-1,
- STR_TERMINATE |
- STR_CONVERT);
+ STR_TERMINATE);
break;
}
} else {
@@ -287,12 +263,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
}
/* and add them to the dirlist pool */
- dirlist = Realloc(dirlist,dirlist_len + data_len);
+ tdl = Realloc(dirlist,dirlist_len + data_len);
- if (!dirlist) {
- DEBUG(0,("Failed to expand dirlist\n"));
+ if (!tdl) {
+ DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
break;
}
+ else dirlist = tdl;
/* put in a length for the last entry, to ensure we can chain entries
into the next packet */
@@ -306,9 +283,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
total_received += ff_searchcount;
- if (rdata) free(rdata); rdata = NULL;
- if (rparam) free(rparam); rparam = NULL;
-
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
DEBUG(3,("received %d entries (eos=%d)\n",
ff_searchcount,ff_eos));
@@ -323,7 +300,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
}
/* free up the dirlist buffer */
- if (dirlist) free(dirlist);
+ SAFE_FREE(dirlist);
return(total_received);
}
@@ -345,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi
finfo->ctime = make_unix_date(p+22);
finfo->mtime = finfo->atime = finfo->ctime;
finfo->size = IVAL(p,26);
- clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII);
+ clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII);
if (strcmp(finfo->name, "..") && strcmp(finfo->name, "."))
fstrcpy(finfo->short_name,finfo->name);
@@ -368,7 +345,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE;
int num_received = 0;
int i;
- char *dirlist = NULL;
+ char *tdl, *dirlist = NULL;
pstring mask;
ZERO_ARRAY(status);
@@ -381,7 +358,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
set_message(cli->outbuf,2,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsearch;
+ SCVAL(cli->outbuf,smb_com,SMBsearch);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -392,7 +369,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE);
*p++ = 5;
if (first) {
SSVAL(p,0,0);
@@ -413,10 +390,14 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
first = False;
- dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
+ tdl = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
- if (!dirlist)
+ if (!tdl) {
+ DEBUG(0,("cli_list_old: failed to expand dirlist"));
+ SAFE_FREE(dirlist);
return 0;
+ }
+ else dirlist = tdl;
p = smb_buf(cli->inbuf) + 3;
@@ -427,7 +408,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
num_received += received;
- if (CVAL(cli->inbuf,smb_rcls) != 0) break;
+ if (cli_is_error(cli)) break;
}
if (!first) {
@@ -435,7 +416,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
- CVAL(cli->outbuf,smb_com) = SMBfclose;
+ SCVAL(cli->outbuf,smb_com,SMBfclose);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -455,7 +436,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
cli_setup_bcc(cli, p);
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
- DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf)));
+ DEBUG(0,("Error closing search: %s\n",cli_errstr(cli)));
}
}
@@ -465,7 +446,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
fn(&finfo, Mask, state);
}
- if (dirlist) free(dirlist);
+ SAFE_FREE(dirlist);
return(num_received);
}
diff --git a/source/libsmb/climessage.c b/source/libsmb/climessage.c
index 87f81754599..5ded79de96c 100644
--- a/source/libsmb/climessage.c
+++ b/source/libsmb/climessage.c
@@ -35,17 +35,15 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
/* send a SMBsendstrt command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsendstrt;
+ SCVAL(cli->outbuf,smb_com,SMBsendstrt);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
p = smb_buf(cli->outbuf);
*p++ = 4;
- p += clistr_push(cli, p, username, -1,
- STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, username, -1, STR_TERMINATE);
*p++ = 4;
- p += clistr_push(cli, p, host, -1,
- STR_TERMINATE|STR_CONVERT);
+ p += clistr_push(cli, p, host, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
@@ -55,7 +53,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_is_error(cli)) return False;
*grp = SVAL(cli->inbuf,smb_vwv0);
@@ -71,24 +69,27 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
char *p;
memset(cli->outbuf,'\0',smb_size);
- set_message(cli->outbuf,1,len+3,True);
- CVAL(cli->outbuf,smb_com) = SMBsendtxt;
+ set_message(cli->outbuf,1,0,True);
+ SCVAL(cli->outbuf,smb_com,SMBsendtxt);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,grp);
p = smb_buf(cli->outbuf);
- *p = 1;
- SSVAL(p,1,len);
- memcpy(p+3,msg,len);
+ *p++ = 1;
+ SSVAL(p,0,len); p += 2;
+ memcpy(p,msg,len);
+ p += len;
+
+ cli_setup_bcc(cli, p);
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_is_error(cli)) return False;
return True;
}
@@ -100,7 +101,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsendend;
+ SCVAL(cli->outbuf,smb_com,SMBsendend);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
SSVAL(cli->outbuf,smb_vwv0,grp);
@@ -113,7 +114,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_is_error(cli)) return False;
return True;
}
diff --git a/source/libsmb/cliprint.c b/source/libsmb/cliprint.c
index eb9c8598066..57e2c049d8f 100644
--- a/source/libsmb/cliprint.c
+++ b/source/libsmb/cliprint.c
@@ -112,8 +112,8 @@ int cli_print_queue(struct cli_state *cli,
}
/* If any parameters or data were returned, free the storage. */
- if(rparam) free(rparam);
- if(rdata) free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return i;
}
@@ -149,8 +149,8 @@ int cli_printjob_del(struct cli_state *cli, int job)
ret = SVAL(rparam,0);
}
- if (rparam) free(rparam);
- if (rdata) free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return ret;
}
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index 5050caf0732..2c24e5c8645 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -124,10 +124,8 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
}
}
- if (rparam)
- free(rparam);
- if (rdata)
- free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return (cli->rap_error == 0);
}
@@ -193,21 +191,19 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
DEBUG(4,("NetShareEnum failed\n"));
}
- if (rparam)
- free(rparam);
- if (rdata)
- free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return count;
}
/****************************************************************************
-call a NetServerEnum for the specified workgroup and servertype mask.
-This function then calls the specified callback function for each name returned.
+call a NetServerEnum for the specified workgroup and servertype mask. This
+function then calls the specified callback function for each name returned.
-The callback function takes 3 arguments: the machine name, the server type and
-the comment.
+The callback function takes 4 arguments: the machine name, the server type,
+the comment and a state pointer.
****************************************************************************/
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
void (*fn)(const char *, uint32, const char *, void *),
@@ -237,9 +233,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
SIVAL(p,0,stype);
p += 4;
- p += clistr_push(cli, p, workgroup, -1,
- STR_TERMINATE | STR_CONVERT | STR_ASCII);
-
+ p += clistr_push(cli, p, workgroup, -1,
+ STR_TERMINATE | STR_CONVERT | STR_ASCII);
+
if (cli_api(cli,
param, PTR_DIFF(p,param), 8, /* params, length, max */
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
@@ -272,10 +268,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
}
}
- if (rparam)
- free(rparam);
- if (rdata)
- free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return(count > 0);
}
@@ -325,13 +319,10 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
* use this as the key to make_oem_passwd_hash().
*/
memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
- fstrcpy(upper_case_old_pw, old_password);
- unix_to_dos(upper_case_old_pw,True);
- strupper(upper_case_old_pw);
+ clistr_push(cli, upper_case_old_pw, old_password, -1,STR_CONVERT|STR_TERMINATE|STR_UPPER|STR_ASCII);
E_P16((uchar *)upper_case_old_pw, old_pw_hash);
- pstrcpy(dos_new_password, new_password);
- unix_to_dos(dos_new_password, True);
+ clistr_push(cli, dos_new_password, new_password, -1, STR_CONVERT|STR_TERMINATE|STR_ASCII);
if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False))
return False;
@@ -340,9 +331,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
* Now place the old password hash in the data.
*/
memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
- fstrcpy(upper_case_new_pw, new_password);
- unix_to_dos(upper_case_new_pw,True);
- strupper(upper_case_new_pw);
+ clistr_push(cli, upper_case_new_pw, new_password, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER|STR_ASCII);
E_P16((uchar *)upper_case_new_pw, new_pw_hash);
@@ -369,10 +358,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
cli->rap_error = SVAL(rparam,0);
}
- if (rparam)
- free(rparam);
- if (rdata)
- free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return (cli->rap_error == 0);
}
@@ -399,7 +386,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
memset(p, 0, 6);
SSVAL(p, 0, SMB_INFO_STANDARD);
p += 6;
- p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE );
param_len = PTR_DIFF(p, param);
@@ -414,12 +401,12 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
cli_receive_trans(cli, SMBtrans2,
&rparam, &param_len,
&rdata, &data_len));
- if (!ret) {
+ if (!ret && cli_is_dos_error(cli)) {
/* we need to work around a Win95 bug - sometimes
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode, NULL);
+ cli_dos_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
}
@@ -451,8 +438,8 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
*mode = SVAL(rdata,l1_attrFile);
}
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
@@ -475,7 +462,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
memset(p, 0, 6);
SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO);
p += 6;
- p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT);
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE );
param_len = PTR_DIFF(p, param);
@@ -521,8 +508,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
*ino = IVAL(rdata, 64);
}
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
@@ -593,8 +580,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
*ino = IVAL(rdata, 64);
}
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
@@ -637,7 +624,71 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
memcpy(outdata, rdata, data_len);
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
+
+/****************************************************************************
+ Send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call.
+****************************************************************************/
+
+NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name)
+{
+ int data_len = 0;
+ int param_len = 0;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ pstring param;
+ char *rparam=NULL, *rdata=NULL;
+ int count=8;
+ char *p;
+ BOOL ret;
+ int len;
+
+ p = param;
+ memset(p, 0, 6);
+ SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO);
+ p += 6;
+ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE);
+
+ param_len = PTR_DIFF(p, param);
+
+ do {
+ ret = (cli_send_trans(cli, SMBtrans2,
+ NULL, /* Name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 10, /* param, length, max */
+ NULL, data_len, cli->max_xmit /* data, length, max */
+ ) &&
+ cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len));
+ if (!ret && cli_is_dos_error(cli)) {
+ /* we need to work around a Win95 bug - sometimes
+ it gives ERRSRV/ERRerror temprarily */
+ uint8 eclass;
+ uint32 ecode;
+ cli_dos_error(cli, &eclass, &ecode);
+ if (eclass != ERRSRV || ecode != ERRerror) break;
+ msleep(100);
+ }
+ } while (count-- && ret==False);
+
+ if (!ret || !rdata || data_len < 4) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ len = IVAL(rdata, 0);
+
+ if (len > data_len - 4) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, 0);
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return NT_STATUS_OK;
+}
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 8eb54b7f389..93333bff951 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -35,11 +35,11 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
set_message(cli->outbuf,10,0,True);
- CVAL(cli->outbuf,smb_com) = SMBreadX;
+ SCVAL(cli->outbuf,smb_com,SMBreadX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
SIVAL(cli->outbuf,smb_vwv3,offset);
SSVAL(cli->outbuf,smb_vwv5,size);
@@ -61,7 +61,7 @@ static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
set_message(cli->outbuf,10,0,True);
- CVAL(cli->outbuf,smb_com) = SMBreadbraw;
+ SCVAL(cli->outbuf,smb_com,SMBreadbraw);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -80,8 +80,6 @@ static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
{
- uint32 ecode;
- uint8 eclass;
char *p;
int size2;
int readsize;
@@ -108,15 +106,22 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
if (!cli_receive_smb(cli))
return -1;
- /*
- * Check for error. Because the client library doesn't support
- * STATUS32, we need to check for and ignore the more data error
- * for pipe support.
- */
+ /* Check for error. Make sure to check for DOS and NT
+ errors. */
- if (cli_error(cli, &eclass, &ecode, NULL) &&
- (eclass != ERRDOS && ecode != ERRmoredata)) {
- return -1;
+ if (cli_is_error(cli)) {
+ NTSTATUS status = NT_STATUS_OK;
+ uint8 eclass = 0;
+ uint32 ecode = 0;
+
+ if (cli_is_nt_error(cli))
+ status = cli_nt_error(cli);
+ else
+ cli_dos_error(cli, &eclass, &ecode);
+
+ if ((eclass == ERRDOS && ecode == ERRmoredata) ||
+ NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES))
+ return -1;
}
size2 = SVAL(cli->inbuf, smb_vwv5);
@@ -227,11 +232,11 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
else
set_message(cli->outbuf,12,0,True);
- CVAL(cli->outbuf,smb_com) = SMBwriteX;
+ SCVAL(cli->outbuf,smb_com,SMBwriteX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,fnum);
SIVAL(cli->outbuf,smb_vwv3,offset);
@@ -292,7 +297,7 @@ ssize_t cli_write(struct cli_state *cli,
received++;
- if (CVAL(cli->inbuf,smb_rcls) != 0)
+ if (cli_is_error(cli))
break;
bwritten += SVAL(cli->inbuf, smb_vwv2);
@@ -322,7 +327,7 @@ ssize_t cli_smbwrite(struct cli_state *cli,
set_message(cli->outbuf,5, 0,True);
- CVAL(cli->outbuf,smb_com) = SMBwrite;
+ SCVAL(cli->outbuf,smb_com,SMBwrite);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@@ -344,7 +349,7 @@ ssize_t cli_smbwrite(struct cli_state *cli,
if (!cli_receive_smb(cli))
return -1;
- if (CVAL(cli->inbuf,smb_rcls) != 0)
+ if (cli_is_error(cli))
return -1;
size = SVAL(cli->inbuf,smb_vwv0);
diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c
index 69c7d5f73fd..0e0884b843c 100644
--- a/source/libsmb/clisecdesc.c
+++ b/source/libsmb/clisecdesc.c
@@ -19,16 +19,13 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define NO_SYSLOG
-
#include "includes.h"
-
-
/****************************************************************************
query the security descriptor for a open file
- ****************************************************************************/
-SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx)
+ ****************************************************************************/
+SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
+ TALLOC_CTX *mem_ctx)
{
char param[8];
char *rparam=NULL, *rdata=NULL;
@@ -36,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx)
prs_struct pd;
SEC_DESC *psd = NULL;
- SIVAL(param, 0, fd);
+ SIVAL(param, 0, fnum);
SSVAL(param, 4, 0x7);
if (!cli_send_nt_trans(cli,
@@ -68,8 +65,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx)
cleanup:
- safe_free(rparam);
- safe_free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
prs_mem_free(&pd);
return psd;
@@ -77,8 +74,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx)
/****************************************************************************
set the security descriptor for a open file
- ****************************************************************************/
-BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd)
+ ****************************************************************************/
+BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
{
char param[8];
char *rparam=NULL, *rdata=NULL;
@@ -100,7 +97,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd)
goto cleanup;
}
- SIVAL(param, 0, fd);
+ SIVAL(param, 0, fnum);
SSVAL(param, 4, 0x7);
if (!cli_send_nt_trans(cli,
@@ -125,8 +122,8 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd)
cleanup:
- safe_free(rparam);
- safe_free(rdata);
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
talloc_destroy(mem_ctx);
diff --git a/source/libsmb/clistr.c b/source/libsmb/clistr.c
index 6dd3b751b48..8a76855c7f4 100644
--- a/source/libsmb/clistr.c
+++ b/source/libsmb/clistr.c
@@ -3,6 +3,7 @@
Version 3.0
client string routines
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jeremy Allison 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,14 +42,14 @@ flags can have:
dest_len is the maximum length allowed in the destination. If dest_len
is -1 then no maxiumum is used
****************************************************************************/
+
int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags)
{
int len=0;
/* treat a pstring as "unlimited" length */
- if (dest_len == -1) {
+ if (dest_len == -1)
dest_len = sizeof(pstring);
- }
if (clistr_align_out(cli, dest, flags)) {
*(char *)dest = 0;
@@ -61,31 +62,34 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len
/* the server doesn't want unicode */
safe_strcpy(dest, src, dest_len);
len = strlen(dest);
- if (flags & STR_TERMINATE) len++;
- if (flags & STR_CONVERT) unix_to_dos(dest,True);
- if (flags & STR_UPPER) strupper(dest);
+ if (flags & STR_TERMINATE)
+ len++;
+ if (flags & STR_CONVERT)
+ unix_to_dos(dest,True);
+ if (flags & STR_UPPER)
+ strupper(dest);
return len;
}
/* the server likes unicode. give it the works */
- if (flags & STR_CONVERT) {
- dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
- } else {
- ascii_to_unistr(dest, src, dest_len);
- }
- if (flags & STR_UPPER) {
+ if (flags & STR_CONVERT)
+ dos_PutUniCode(dest, unix_to_dos(src,False), dest_len, flags & STR_TERMINATE);
+ else
+ unix_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE);
+
+ if (flags & STR_UPPER)
strupper_w(dest);
- }
+
len += strlen(src)*2;
- if (flags & STR_TERMINATE) len += 2;
+ if (flags & STR_TERMINATE)
+ len += 2;
return len;
}
/****************************************************************************
-copy a string from a unicode or ascii source (depending on
-cli->capabilities) to a char* destination
+copy a string from a unicode or dos codepage source (depending on
+cli->capabilities) to a unix char* destination
flags can have:
- STR_CONVERT means convert from dos to unix codepage
STR_TERMINATE means the string in src is null terminated
STR_UNICODE means to force as unicode
STR_NOALIGN means don't do alignment
@@ -93,17 +97,18 @@ if STR_TERMINATE is set then src_len is ignored
src_len is the length of the source area in bytes
return the number of bytes occupied by the string in src
****************************************************************************/
+
int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags)
{
int len;
- if (dest_len == -1) {
+ if (dest_len == -1)
dest_len = sizeof(pstring);
- }
if (clistr_align_in(cli, src, flags)) {
src = (const void *)((const char *)src + 1);
- if (src_len > 0) src_len--;
+ if (src_len > 0)
+ src_len--;
}
if (!UNICODE_FLAG(cli, flags)) {
@@ -112,43 +117,51 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len
safe_strcpy(dest, src, dest_len);
len = strlen(src)+1;
} else {
- if (src_len > dest_len) src_len = dest_len;
+ if (src_len > dest_len)
+ src_len = dest_len;
len = src_len;
memcpy(dest, src, len);
dest[len] = 0;
}
- if (flags & STR_CONVERT)
- safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
+ safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
return len;
}
if (flags & STR_TERMINATE) {
- unistr_to_ascii(dest, src, dest_len);
- len = strlen(dest)*2 + 2;
+ int i;
+ src_len = strlen_w(src)*2+2;
+ for (i=0; i < src_len; i += 2) {
+ const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
+ if (c == (smb_ucs2_t)0 || (dest_len - i < 3))
+ break;
+ dest += unicode_to_unix_char(dest, c);
+ }
+ *dest++ = 0;
+ len = src_len;
} else {
- int i, c;
- if (dest_len*2 < src_len) src_len = 2*dest_len;
+ int i;
+ if (dest_len*2 < src_len)
+ src_len = 2*dest_len;
for (i=0; i < src_len; i += 2) {
- c = SVAL(src, i);
- *dest++ = c;
+ const smb_ucs2_t c = (smb_ucs2_t)SVAL(src, i);
+ dest += unicode_to_unix_char(dest, c);
}
*dest++ = 0;
len = src_len;
}
- if (flags & STR_CONVERT)
- safe_strcpy(dest,dos_to_unix(dest,False),dest_len);
return len;
}
-
/****************************************************************************
-return an alignment of either 0 or 1
-if unicode is not negotiated then return 0
-otherwise return 1 if offset is off
+ Return an alignment of either 0 or 1.
+ If unicode is not negotiated then return 0
+ otherwise return 1 if offset is off.
****************************************************************************/
+
static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags)
{
- if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags)) return 0;
+ if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags))
+ return 0;
return PTR_DIFF(p, buf) & 1;
}
@@ -161,5 +174,3 @@ int clistr_align_in(struct cli_state *cli, const void *p, int flags)
{
return clistr_align(cli, cli->inbuf, p, flags);
}
-
-
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index 6038584a891..96c041fa3be 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -28,7 +28,7 @@
send a SMB trans or trans2 request
****************************************************************************/
BOOL cli_send_trans(struct cli_state *cli, int trans,
- char *pipe_name,
+ const char *pipe_name,
int fid, int flags,
uint16 *setup, int lsetup, int msetup,
char *param, int lparam, int mparam,
@@ -46,7 +46,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,14+lsetup,0,True);
- CVAL(cli->outbuf,smb_com) = trans;
+ SCVAL(cli->outbuf,smb_com,trans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
@@ -89,7 +89,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) ||
- CVAL(cli->inbuf,smb_rcls) != 0) {
+ cli_is_error(cli)) {
return(False);
}
@@ -101,7 +101,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
- CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
+ SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2));
outparam = smb_buf(cli->outbuf);
outdata = outparam+this_lparam;
@@ -145,8 +145,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
int total_data=0;
int total_param=0;
int this_data,this_param;
- uint8 eclass;
- uint32 ecode;
+ NTSTATUS status;
char *tdata;
char *tparam;
@@ -170,16 +169,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
* to a trans call. This is not an error and should not
* be treated as such.
*/
-
- if (cli_error(cli, &eclass, &ecode, NULL))
- {
- if(cli->nt_pipe_fnum == 0)
- return(False);
-
- if(!(eclass == ERRDOS && ecode == ERRmoredata)) {
- if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW)))
- return(False);
- }
+ status = cli_nt_error(cli);
+
+ if (NT_STATUS_IS_ERR(status)) {
+ return False;
}
/* parse out the lengths */
@@ -196,7 +189,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
else
*data = tdata;
}
-
+
if (total_param!=0) {
tparam = Realloc(*param,total_param);
if (!tparam) {
@@ -247,10 +240,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
CVAL(cli->inbuf,smb_com)));
return(False);
}
- if (cli_error(cli, &eclass, &ecode, NULL))
- {
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
- return(False);
+ if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
+ return(False);
}
}
@@ -280,7 +271,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,19+lsetup,0,True);
- CVAL(cli->outbuf,smb_com) = SMBnttrans;
+ SCVAL(cli->outbuf,smb_com,SMBnttrans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
@@ -316,7 +307,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) ||
- CVAL(cli->inbuf,smb_rcls) != 0) {
+ cli_is_error(cli)) {
return(False);
}
@@ -328,7 +319,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
set_message(cli->outbuf,18,0,True);
- CVAL(cli->outbuf,smb_com) = SMBnttranss;
+ SCVAL(cli->outbuf,smb_com,SMBnttranss);
/* XXX - these should probably be aligned */
outparam = smb_buf(cli->outbuf);
@@ -396,7 +387,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
* to a trans call. This is not an error and should not
* be treated as such.
*/
- if (cli_error(cli, &eclass, &ecode, NULL)) {
+ if (cli_is_dos_error(cli)) {
+ cli_dos_error(cli, &eclass, &ecode);
if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
return(False);
}
@@ -406,20 +398,25 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount);
/* allocate it */
- tdata = Realloc(*data,total_data);
- if (!tdata) {
- DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer"));
- return False;
+ if (total_data) {
+ tdata = Realloc(*data,total_data);
+ if (!tdata) {
+ DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data));
+ return False;
+ } else {
+ *data = tdata;
+ }
}
- else
- *data = tdata;
- tparam = Realloc(*param,total_param);
- if (!tparam) {
- DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer"));
- return False;
+
+ if (total_param) {
+ tparam = Realloc(*param,total_param);
+ if (!tparam) {
+ DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param));
+ return False;
+ } else {
+ *param = tparam;
+ }
}
- else
- *param = tparam;
while (1) {
this_data = SVAL(cli->inbuf,smb_ntr_DataCount);
@@ -460,8 +457,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
CVAL(cli->inbuf,smb_com)));
return(False);
}
- if (cli_error(cli, &eclass, &ecode, NULL)) {
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+ if (cli_is_dos_error(cli)) {
+ cli_dos_error(cli, &eclass, &ecode);
+ if(cli->nt_pipe_fnum == 0 ||
+ !(eclass == ERRDOS && ecode == ERRmoredata))
return(False);
}
}
diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c
index d4c87920686..5f65c13edd9 100644
--- a/source/libsmb/credentials.c
+++ b/source/libsmb/credentials.c
@@ -21,10 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
-
/****************************************************************************
represent a credential as a string
****************************************************************************/
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 40625f5bbcd..55f17b2b34e 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -29,31 +29,31 @@
*/
struct smbc_server {
- struct smbc_server *next, *prev;
- struct cli_state cli;
- dev_t dev;
- char *server_name;
- char *share_name;
- char *workgroup;
- char *username;
- BOOL no_pathinfo2;
+ struct smbc_server *next, *prev;
+ struct cli_state cli;
+ dev_t dev;
+ char *server_name;
+ char *share_name;
+ char *workgroup;
+ char *username;
+ BOOL no_pathinfo2;
};
/* Keep directory entries in a list */
struct smbc_dir_list {
- struct smbc_dir_list *next;
- struct smbc_dirent *dirent;
+ struct smbc_dir_list *next;
+ struct smbc_dirent *dirent;
};
struct smbc_file {
- int cli_fd;
- int smbc_fd;
- char *fname;
- off_t offset;
- struct smbc_server *srv;
- BOOL file;
- struct smbc_dir_list *dir_list, *dir_end, *dir_next;
- int dir_type, dir_error;
+ int cli_fd;
+ int smbc_fd;
+ char *fname;
+ off_t offset;
+ struct smbc_server *srv;
+ BOOL file;
+ struct smbc_dir_list *dir_list, *dir_end, *dir_next;
+ int dir_type, dir_error;
};
int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */
@@ -63,11 +63,11 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path,
SMB_INO_T *ino);
extern BOOL in_client;
+extern pstring global_myname;
static int smbc_initialized = 0;
static smbc_get_auth_data_fn smbc_auth_fn = NULL;
/*static int smbc_debug;*/
static int smbc_start_fd;
-static int smbc_max_fd = 10000;
static struct smbc_file **smbc_file_table;
static struct smbc_server *smbc_srvs;
static pstring my_netbios_name;
@@ -89,104 +89,108 @@ static int
smbc_parse_path(const char *fname, char *server, char *share, char *path,
char *user, char *password) /* FIXME, lengths of strings */
{
- static pstring s;
- pstring userinfo;
- char *p;
- int len;
+ static pstring s;
+ pstring userinfo;
+ char *p;
+ char *q, *r;
+ int len;
- server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
- pstrcpy(s, fname);
+ server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
+ pstrcpy(s, fname);
- /* clean_fname(s); causing problems ... */
+ /* clean_fname(s); causing problems ... */
- /* see if it has the right prefix */
- len = strlen(smbc_prefix);
- if (strncmp(s,smbc_prefix,len) ||
- (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */
+ /* see if it has the right prefix */
+ len = strlen(smbc_prefix);
+ if (strncmp(s,smbc_prefix,len) ||
+ (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */
- p = s + len;
+ p = s + len;
- /* Watch the test below, we are testing to see if we should exit */
+ /* Watch the test below, we are testing to see if we should exit */
- if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
+ if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
- return -1;
+ return -1;
- }
-
- p += 2; /* Skip the // or \\ */
+ }
- if (*p == (char)0)
- return 0;
+ p += 2; /* Skip the // or \\ */
- if (*p == '/') {
+ if (*p == (char)0)
+ return 0;
- strncpy(server, lp_workgroup(), 16); /* FIXME: Danger here */
- return 0;
+ if (*p == '/') {
- }
+ strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */
+ return 0;
+
+ }
- /*
- * ok, its for us. Now parse out the server, share etc.
- *
- * However, we want to parse out [[domain;]user[:password]@] if it
- * exists ...
- */
+ /*
+ * ok, its for us. Now parse out the server, share etc.
+ *
+ * However, we want to parse out [[domain;]user[:password]@] if it
+ * exists ...
+ */
- if (strchr(p, '@')) {
- pstring username, passwd, domain;
- char *u = userinfo;
+ /* check that '@' occurs before '/', if '/' exists at all */
+ q = strchr(p, '@');
+ r = strchr(p, '/');
+ if (q && (!r || q < r)) {
+ pstring username, passwd, domain;
+ char *u = userinfo;
- next_token(&p, userinfo, "@", sizeof(fstring));
+ next_token(&p, userinfo, "@", sizeof(fstring));
- username[0] = passwd[0] = domain[0] = 0;
+ username[0] = passwd[0] = domain[0] = 0;
- if (strchr(u, ';')) {
+ if (strchr(u, ';')) {
- next_token(&u, domain, ";", sizeof(fstring));
+ next_token(&u, domain, ";", sizeof(fstring));
- }
+ }
- if (strchr(u, ':')) {
+ if (strchr(u, ':')) {
- next_token(&u, username, ":", sizeof(fstring));
+ next_token(&u, username, ":", sizeof(fstring));
- pstrcpy(passwd, u);
+ pstrcpy(passwd, u);
- }
- else {
+ }
+ else {
- pstrcpy(username, u);
+ pstrcpy(username, u);
- }
+ }
- if (username[0])
- strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */
+ if (username[0])
+ strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */
- if (passwd[0])
- strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */
+ if (passwd[0])
+ strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */
- }
+ }
- if (!next_token(&p, server, "/", sizeof(fstring))) {
+ if (!next_token(&p, server, "/", sizeof(fstring))) {
- return -1;
+ return -1;
- }
+ }
- if (*p == (char)0) return 0; /* That's it ... */
+ if (*p == (char)0) return 0; /* That's it ... */
- if (!next_token(&p, share, "/", sizeof(fstring))) {
+ if (!next_token(&p, share, "/", sizeof(fstring))) {
- return -1;
+ return -1;
- }
+ }
- pstrcpy(path, p);
+ pstrcpy(path, p);
- all_string_sub(path, "/", "\\", 0);
+ all_string_sub(path, "/", "\\", 0);
- return 0;
+ return 0;
}
/*
@@ -195,16 +199,27 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path,
int smbc_errno(struct cli_state *c)
{
- uint8 eclass;
- uint32 ecode;
int ret;
- ret = cli_error(c, &eclass, &ecode, NULL);
+ 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));
+ } else {
+ 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));
+ }
- if (ret) {
- DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n",
- (int)eclass, (int)ecode, (int)ecode, ret));
- }
return ret;
}
@@ -223,171 +238,210 @@ struct smbc_server *smbc_server(char *server, char *share,
char *workgroup, char *username,
char *password)
{
- struct smbc_server *srv=NULL;
- struct cli_state c;
- struct nmb_name called, calling;
- char *p, *server_n = server;
- fstring group;
- pstring ipenv;
- struct in_addr ip;
- extern struct in_addr ipzero;
+ struct smbc_server *srv=NULL;
+ struct cli_state c;
+ struct nmb_name called, calling;
+ char *p, *server_n = server;
+ fstring group;
+ pstring ipenv;
+ struct in_addr ip;
+ extern struct in_addr ipzero;
- ip = ipzero;
- ZERO_STRUCT(c);
-
- /* try to use an existing connection */
- for (srv=smbc_srvs;srv;srv=srv->next) {
- if (strcmp(server,srv->server_name)==0 &&
- strcmp(share,srv->share_name)==0 &&
- strcmp(workgroup,srv->workgroup)==0 &&
- strcmp(username, srv->username) == 0)
- return srv;
- }
-
- if (server[0] == 0) {
- errno = EPERM;
- return NULL;
- }
-
- /*
- * Pick up the auth info here, once we know we need to connect
- * But only if we do not have a username and password ...
- */
-
- if (!username[0] || !password[0])
- smbc_auth_fn(server, share, workgroup, sizeof(fstring),
- username, sizeof(fstring), password, sizeof(fstring));
-
- /*
- * However, smbc_auth_fn may have picked up info relating to an
- * existing connection, so try for an existing connection again ...
- */
-
- for (srv=smbc_srvs;srv;srv=srv->next) {
- if (strcmp(server,srv->server_name)==0 &&
- strcmp(share,srv->share_name)==0 &&
- strcmp(workgroup,srv->workgroup)==0 &&
- strcmp(username, srv->username) == 0)
- return srv;
- }
-
- make_nmb_name(&calling, my_netbios_name, 0x0);
- make_nmb_name(&called , server, 0x20);
-
- DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
+ ip = ipzero;
+ ZERO_STRUCT(c);
+
+ /* try to use an existing connection */
+ for (srv=smbc_srvs;srv;srv=srv->next) {
+ if (strcmp(server,srv->server_name)==0 &&
+ strcmp(share,srv->share_name)==0 &&
+ strcmp(workgroup,srv->workgroup)==0 &&
+ strcmp(username, srv->username) == 0)
+ return srv;
+ }
+
+ if (server[0] == 0) {
+ errno = EPERM;
+ return NULL;
+ }
+
+ /*
+ * Pick up the auth info here, once we know we need to connect
+ * But only if we do not have a username and password ...
+ */
+
+ if (!username[0] || !password[0])
+ smbc_auth_fn(server, share, workgroup, sizeof(fstring),
+ username, sizeof(fstring), password, sizeof(fstring));
+
+ /*
+ * However, smbc_auth_fn may have picked up info relating to an
+ * existing connection, so try for an existing connection again ...
+ */
+
+ for (srv=smbc_srvs;srv;srv=srv->next) {
+ if (strcmp(server,srv->server_name)==0 &&
+ strcmp(share,srv->share_name)==0 &&
+ strcmp(workgroup,srv->workgroup)==0 &&
+ strcmp(username, srv->username) == 0)
+ return srv;
+ }
+
+ make_nmb_name(&calling, my_netbios_name, 0x0);
+ make_nmb_name(&called , server, 0x20);
+
+ DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
- if ((p=strchr(server_n,'#')) &&
- (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
+ if ((p=strchr(server_n,'#')) &&
+ (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
- fstrcpy(group, server_n);
- p = strchr(group,'#');
- *p = 0;
+ fstrcpy(group, server_n);
+ p = strchr(group,'#');
+ *p = 0;
- }
+ }
- DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
+ DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
again:
- slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
+ slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n);
- ip = ipzero;
+ ip = ipzero;
- /* have to open a new connection */
- if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
- errno = ENOENT;
- return NULL;
- }
+ /* have to open a new connection */
+ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) {
+ if (c.initialised) cli_shutdown(&c);
+ errno = ENOENT;
+ return NULL;
+ }
- if (!cli_session_request(&c, &calling, &called)) {
- cli_shutdown(&c);
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- errno = ENOENT;
- return NULL;
- }
+ if (!cli_session_request(&c, &calling, &called)) {
+ cli_shutdown(&c);
+ if (strcmp(called.name, "*SMBSERVER")) {
+ make_nmb_name(&called , "*SMBSERVER", 0x20);
+ goto again;
+ }
+ errno = ENOENT;
+ return NULL;
+ }
- DEBUG(4,(" session request ok\n"));
+ DEBUG(4,(" session request ok\n"));
- if (!cli_negprot(&c)) {
- cli_shutdown(&c);
- errno = ENOENT;
- return NULL;
- }
-
- if (!cli_session_setup(&c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup) &&
- /* try an anonymous login if it failed */
- !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
- cli_shutdown(&c);
- errno = EPERM;
- return NULL;
- }
-
- DEBUG(4,(" session setup ok\n"));
-
- if (!cli_send_tconX(&c, share, "?????",
- password, strlen(password)+1)) {
- errno = smbc_errno(&c);
- cli_shutdown(&c);
- return NULL;
- }
+ if (!cli_negprot(&c)) {
+ cli_shutdown(&c);
+ errno = ENOENT;
+ return NULL;
+ }
+
+ if (!cli_session_setup(&c, username,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup) &&
+ /* try an anonymous login if it failed */
+ !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
+ cli_shutdown(&c);
+ errno = EPERM;
+ return NULL;
+ }
+
+ DEBUG(4,(" session setup ok\n"));
+
+ if (!cli_send_tconX(&c, share, "?????",
+ password, strlen(password)+1)) {
+ errno = smbc_errno(&c);
+ cli_shutdown(&c);
+ return NULL;
+ }
- DEBUG(4,(" tconx ok\n"));
+ DEBUG(4,(" tconx ok\n"));
- srv = (struct smbc_server *)malloc(sizeof(*srv));
- if (!srv) {
- errno = ENOMEM;
- goto failed;
- }
+ srv = (struct smbc_server *)malloc(sizeof(*srv));
+ if (!srv) {
+ errno = ENOMEM;
+ goto failed;
+ }
- ZERO_STRUCTP(srv);
+ ZERO_STRUCTP(srv);
- srv->cli = c;
+ srv->cli = c;
- srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
+ srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
- srv->server_name = strdup(server);
- if (!srv->server_name) {
- errno = ENOMEM;
- goto failed;
- }
+ srv->server_name = strdup(server);
+ if (!srv->server_name) {
+ errno = ENOMEM;
+ goto failed;
+ }
- srv->share_name = strdup(share);
- if (!srv->share_name) {
- errno = ENOMEM;
- goto failed;
- }
+ srv->share_name = strdup(share);
+ if (!srv->share_name) {
+ errno = ENOMEM;
+ goto failed;
+ }
- srv->workgroup = strdup(workgroup);
- if (!srv->workgroup) {
- errno = ENOMEM;
- goto failed;
- }
+ srv->workgroup = strdup(workgroup);
+ if (!srv->workgroup) {
+ errno = ENOMEM;
+ goto failed;
+ }
- srv->username = strdup(username);
- if (!srv->username) {
- errno = ENOMEM;
- goto failed;
- }
+ srv->username = strdup(username);
+ if (!srv->username) {
+ errno = ENOMEM;
+ goto failed;
+ }
- DLIST_ADD(smbc_srvs, srv);
+ DLIST_ADD(smbc_srvs, srv);
- return srv;
+ return srv;
failed:
- cli_shutdown(&c);
- if (!srv) return NULL;
+ cli_shutdown(&c);
+ if (!srv) return NULL;
- if (srv->server_name) free(srv->server_name);
- if (srv->share_name) free(srv->share_name);
- free(srv);
- return NULL;
+ SAFE_FREE(srv->server_name);
+ SAFE_FREE(srv->share_name);
+ SAFE_FREE(srv->workgroup);
+ SAFE_FREE(srv->username);
+ SAFE_FREE(srv);
+ return NULL;
}
+/*
+ *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl)
+ *
+ * We accept a *srv
+ */
+BOOL smbc_remove_unused_server(struct smbc_server * s)
+{
+ int p;
+
+ /* are we being fooled ? */
+ if (!s) return False;
+
+ /* close all open files/directories on this server */
+ for (p = 0; p < SMBC_MAX_FD; p++) {
+ if (smbc_file_table[p] &&
+ smbc_file_table[p]->srv == s) {
+ /* Still used .. DARN */
+ DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s,
+ smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd));
+ return False;
+ }
+ }
+
+ cli_shutdown(&s->cli);
+
+ SAFE_FREE(s->username);
+ SAFE_FREE(s->workgroup);
+ SAFE_FREE(s->server_name);
+ SAFE_FREE(s->share_name);
+ DLIST_REMOVE(smbc_srvs, s);
+ DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s));
+ SAFE_FREE(s);
+ return True;
+}
+
+
/*
*Initialise the library etc
*
@@ -397,128 +451,124 @@ struct smbc_server *smbc_server(char *server, char *share,
int smbc_init(smbc_get_auth_data_fn fn, int debug)
{
- pstring conf;
- int p, pid;
- char *user = NULL, *home = NULL, *pname="libsmbclient";
-
- /*
- * Next lot ifdef'd out until test suite fixed ...
- */
-
- if (!fn || debug < 0 || debug > 100) {
-
- errno = EINVAL;
- return -1;
-
- }
-
- if (smbc_initialized) { /* Already done, so don't do it again */
-
- return 0;
-
- }
-
+ pstring conf;
+ int p, pid;
+ char *user = NULL, *home = NULL, *pname="libsmbclient";
- smbc_initialized = 1;
- smbc_auth_fn = fn;
- /* smbc_debug = debug; */
+ if (!fn || debug < 0 || debug > 100) {
- DEBUGLEVEL = -1;
+ errno = EINVAL;
+ return -1;
- setup_logging(pname, False);
-
- /*
- * We try to construct our netbios name from our hostname etc
- */
-
- user = getenv("USER");
- if (!user) user = ""; /* FIXME: What to do about this? */
+ }
- /*
- * FIXME: Is this the best way to get the user info? */
+ if (smbc_initialized) { /* Don't go through this if we have already done it */
- pstrcpy(smbc_user, user); /* Save for use elsewhere */
+ return 0;
- pid = getpid();
+ }
- /*
- * Hmmm, I want to get hostname as well, but I am too lazy for the moment
- */
+ smbc_initialized = 1;
+ smbc_auth_fn = fn;
+ /* smbc_debug = debug; */
- slprintf(my_netbios_name, 16, "smbc%s%d", user, pid);
+ DEBUGLEVEL = -1;
- charset_initialise();
+ setup_logging(pname, False);
- /* Here we would open the smb.conf file if needed ... */
+ /* Here we would open the smb.conf file if needed ... */
- home = getenv("HOME");
+ home = getenv("HOME");
- slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
+ slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
- load_interfaces(); /* Load the list of interfaces ... */
+ load_interfaces(); /* Load the list of interfaces ... */
- in_client = True; /* FIXME, make a param */
+ charset_initialise();
+
+ in_client = True; /* FIXME, make a param */
- if (!lp_load(conf, True, False, False)) {
+ if (!lp_load(conf, True, False, False)) {
- /*
- * Hmmm, what the hell do we do here ... we could not parse the
- * config file ... We must return an error ... and keep info around
- * about why we failed
- */
+ /*
+ * Hmmm, what the hell do we do here ... we could not parse the
+ * config file ... We must return an error ... and keep info around
+ * about why we failed
+ */
- errno = ENOENT; /* FIXME: Figure out the correct error response */
- return -1;
+ errno = ENOENT; /* FIXME: Figure out the correct error response */
+ return -1;
- }
+ }
- codepage_initialise(lp_client_code_page()); /* Get a codepage */
+ codepage_initialise(lp_client_code_page()); /* Get a codepage */
- reopen_logs(); /* Get logging working ... */
+ reopen_logs(); /* Get logging working ... */
- name_register_wins(my_netbios_name, 0);
+ /*
+ * FIXME: Is this the best way to get the user info?
+ */
- /*
- * Now initialize the file descriptor array and figure out what the
- * max open files is, so we can return FD's that are above the max
- * open file, and separated by a guard band
- */
+ user = getenv("USER");
+ /* walk around as "guest" if no username can be found */
+ if (!user) user = strdup("guest");
+ pstrcpy(smbc_user, user); /* Save for use elsewhere */
+
+ /*
+ * We try to get our netbios name from the config. If that fails we fall
+ * back on constructing our netbios name from our hostname etc
+ */
+ if (global_myname) {
+ pstrcpy(my_netbios_name, global_myname);
+ }
+ else {
+ /*
+ * Hmmm, I want to get hostname as well, but I am too lazy for the moment
+ */
+ pid = getpid();
+ slprintf(my_netbios_name, 16, "smbc%s%d", user, pid);
+ }
+ DEBUG(0,("Using netbios name %s.\n", my_netbios_name));
-#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
- do {
- struct rlimit rlp;
+ name_register_wins(my_netbios_name, 0);
- if (getrlimit(RLIMIT_NOFILE, &rlp)) {
+ /*
+ * Now initialize the file descriptor array and figure out what the
+ * max open files is, so we can return FD's that are above the max
+ * open file, and separated by a guard band
+ */
- DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno)));
+#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
+ do {
+ struct rlimit rlp;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlp)) {
- smbc_start_fd = 1000000;
- smbc_max_fd = 10000; /* FIXME, should be a define ... */
+ DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno)));
- }
- else {
-
- smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */
- smbc_max_fd = 10000;
+ smbc_start_fd = 1000000;
- }
- } while ( 0 );
+ }
+ else {
+
+ smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */
+
+ }
+ } while ( 0 );
#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
- smbc_start_fd = 1000000;
- smbc_max_fd = 10000; /* FIXME, should be a define ... */
+ smbc_start_fd = 1000000;
#endif
- smbc_file_table = malloc(smbc_max_fd * sizeof(struct smbc_file *));
-
- for (p = 0; p < smbc_max_fd; p++)
- smbc_file_table[p] = NULL;
+ smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *));
+ if (!smbc_file_table)
+ return ENOMEM;
- if (!smbc_file_table)
- return ENOMEM;
+ for (p = 0; p < SMBC_MAX_FD; p++)
+ smbc_file_table[p] = NULL;
- return 0; /* Success */
+ return 0; /* Success */
}
@@ -528,107 +578,108 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug)
int smbc_open(const char *fname, int flags, mode_t mode)
{
- fstring server, share, user, password;
- pstring path;
- struct smbc_server *srv = NULL;
- int fd;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ struct smbc_server *srv = NULL;
+ int fd;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL; /* Best I can think of ... */
- return -1;
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- if (errno == EPERM) errno = EACCES;
- return -1; /* smbc_server sets errno */
+ if (!srv) {
- }
+ if (errno == EPERM) errno = EACCES;
+ return -1; /* smbc_server sets errno */
+
+ }
- /* Hmmm, the test for a directory is suspect here ... FIXME */
+ /* Hmmm, the test for a directory is suspect here ... FIXME */
- if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') {
+ if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') {
- fd = -1;
+ fd = -1;
- }
- else {
+ }
+ else {
+
+ int slot = 0;
- int slot = 0;
+ /* Find a free slot first */
- /* Find a free slot first */
+ while (smbc_file_table[slot])
+ slot++;
- while (smbc_file_table[slot])
- slot++;
+ if (slot > SMBC_MAX_FD) {
- if (slot > smbc_max_fd) {
+ errno = ENOMEM; /* FIXME, is this best? */
+ return -1;
- errno = ENOMEM; /* FIXME, is this best? */
- return -1;
+ }
- }
+ smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
- smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
+ if (!smbc_file_table[slot]) {
- if (!smbc_file_table[slot]) {
+ errno = ENOMEM;
+ return -1;
- errno = ENOMEM;
- return -1;
+ }
- }
+ if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) {
- if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) {
+ /* Handle the error ... */
- /* Handle the error ... */
+ SAFE_FREE(smbc_file_table[slot]);
+ errno = smbc_errno(&srv->cli);
+ return -1;
- free(smbc_file_table[slot]);
- smbc_file_table[slot] = NULL;
- errno = smbc_errno(&srv->cli);
- return -1;
-
- }
+ }
- /* Fill in file struct */
+ /* Fill in file struct */
- smbc_file_table[slot]->cli_fd = fd;
- smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
- smbc_file_table[slot]->fname = strdup(fname);
- smbc_file_table[slot]->srv = srv;
- smbc_file_table[slot]->offset = 0;
- smbc_file_table[slot]->file = True;
+ smbc_file_table[slot]->cli_fd = fd;
+ smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
+ smbc_file_table[slot]->fname = strdup(fname);
+ smbc_file_table[slot]->srv = srv;
+ smbc_file_table[slot]->offset = 0;
+ smbc_file_table[slot]->file = True;
- return smbc_file_table[slot]->smbc_fd;
+ return smbc_file_table[slot]->smbc_fd;
- }
+ }
- /* Check if opendir needed ... */
+ /* Check if opendir needed ... */
- if (fd == -1) {
- int eno = 0;
+ if (fd == -1) {
+ int eno = 0;
- eno = smbc_errno(&srv->cli);
- fd = smbc_opendir(fname);
- if (fd < 0) errno = eno;
- return fd;
+ eno = smbc_errno(&srv->cli);
+ fd = smbc_opendir(fname);
+ if (fd < 0) errno = eno;
+ return fd;
- }
+ }
- return 1; /* Success, with fd ... */
+ return 1; /* Success, with fd ... */
}
@@ -641,14 +692,14 @@ static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this
int smbc_creat(const char *path, mode_t mode)
{
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- return smbc_open(path, creat_bits, mode);
+ return smbc_open(path, creat_bits, mode);
}
/*
@@ -657,57 +708,57 @@ int smbc_creat(const char *path, mode_t mode)
ssize_t smbc_read(int fd, void *buf, size_t count)
{
- struct smbc_file *fe;
- int ret;
+ struct smbc_file *fe;
+ int ret;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count));
+ DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count));
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- /* Check that the buffer exists ... */
+ /* Check that the buffer exists ... */
- if (buf == NULL) {
+ if (buf == NULL) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe || !fe->file) {
+ if (!fe || !fe->file) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count);
+ ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count);
- if (ret < 0) {
+ if (ret < 0) {
- errno = smbc_errno(&fe->srv->cli);
- return -1;
+ errno = smbc_errno(&fe->srv->cli);
+ return -1;
- }
+ }
- fe->offset += ret;
+ fe->offset += ret;
- DEBUG(4, (" --> %d\n", ret));
+ DEBUG(4, (" --> %d\n", ret));
- return ret; /* Success, ret bytes of data ... */
+ return ret; /* Success, ret bytes of data ... */
}
@@ -717,53 +768,53 @@ ssize_t smbc_read(int fd, void *buf, size_t count)
ssize_t smbc_write(int fd, void *buf, size_t count)
{
- int ret;
- struct smbc_file *fe;
+ int ret;
+ struct smbc_file *fe;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- /* Check that the buffer exists ... */
+ /* Check that the buffer exists ... */
- if (buf == NULL) {
+ if (buf == NULL) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe || !fe->file) {
+ if (!fe || !fe->file) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count);
+ ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count);
- if (ret <= 0) {
+ if (ret <= 0) {
- errno = smbc_errno(&fe->srv->cli);
- return -1;
+ errno = smbc_errno(&fe->srv->cli);
+ return -1;
- }
+ }
- fe->offset += ret;
+ fe->offset += ret;
- return ret; /* Success, 0 bytes of data ... */
+ return ret; /* Success, 0 bytes of data ... */
}
/*
@@ -772,49 +823,57 @@ ssize_t smbc_write(int fd, void *buf, size_t count)
int smbc_close(int fd)
{
- struct smbc_file *fe;
+ struct smbc_file *fe;
+ struct smbc_server *srv;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
-
- }
-
- fe = smbc_file_table[fd - smbc_start_fd];
+ errno = EBADF;
+ return -1;
- if (!fe) {
+ }
- errno = EBADF;
- return -1;
+ fe = smbc_file_table[fd - smbc_start_fd];
- }
+ if (!fe) {
- if (!fe->file) {
+ errno = EBADF;
+ return -1;
- return smbc_closedir(fd);
+ }
- }
+ if (!fe->file) {
- if (!cli_close(&fe->srv->cli, fe->cli_fd)) {
+ return smbc_closedir(fd);
- errno = smbc_errno(&fe->srv->cli); /* FIXME, should we deallocate slot? */
- return -1;
+ }
- }
+ if (!cli_close(&fe->srv->cli, fe->cli_fd)) {
+ DEBUG(3, ("cli_close failed on %s (%d). purging server.\n",
+ fe->fname, fe->smbc_fd));
+ /* Deallocate slot and remove the server
+ * from the server cache if unused */
+ errno = smbc_errno(&fe->srv->cli);
+ srv = fe->srv;
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe);
+ smbc_file_table[fd - smbc_start_fd] = NULL;
+ smbc_remove_unused_server(srv);
+ return -1;
+ }
- if (fe->fname) free(fe->fname);
- free(fe);
- smbc_file_table[fd - smbc_start_fd] = NULL;
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe);
+ smbc_file_table[fd - smbc_start_fd] = NULL;
- return 0;
+ return 0;
}
/*
@@ -823,37 +882,39 @@ int smbc_close(int fd)
int smbc_unlink(const char *fname)
{
- fstring server, share, user, password;
- pstring path;
- struct smbc_server *srv = NULL;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ struct smbc_server *srv = NULL;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL; /* Best I can think of ... */
- return -1;
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
+ smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* smbc_server sets errno */
+ if (!srv) {
- }
+ return -1; /* smbc_server sets errno */
- /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+ }
+
+ /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
int job = smbc_stat_printjob(srv, path, NULL, NULL);
if (job == -1) {
@@ -869,42 +930,42 @@ int smbc_unlink(const char *fname)
}
} else */
- if (!cli_unlink(&srv->cli, path)) {
+ if (!cli_unlink(&srv->cli, path)) {
- errno = smbc_errno(&srv->cli);
+ errno = smbc_errno(&srv->cli);
- if (errno == EACCES) { /* Check if the file is a directory */
+ if (errno == EACCES) { /* Check if the file is a directory */
- int saverr = errno;
- size_t size = 0;
- uint16 mode = 0;
- time_t m_time = 0, a_time = 0, c_time = 0;
- SMB_INO_T ino = 0;
+ int saverr = errno;
+ size_t size = 0;
+ uint16 mode = 0;
+ time_t m_time = 0, a_time = 0, c_time = 0;
+ SMB_INO_T ino = 0;
- if (!smbc_getatr(srv, path, &mode, &size,
- &c_time, &a_time, &m_time, &ino)) {
+ if (!smbc_getatr(srv, path, &mode, &size,
+ &c_time, &a_time, &m_time, &ino)) {
- /* Hmmm, bad error ... What? */
+ /* Hmmm, bad error ... What? */
- errno = smbc_errno(&srv->cli);
- return -1;
+ errno = smbc_errno(&srv->cli);
+ return -1;
- }
- else {
+ }
+ else {
- if (IS_DOS_DIR(mode))
- errno = EISDIR;
- else
- errno = saverr; /* Restore this */
+ if (IS_DOS_DIR(mode))
+ errno = EISDIR;
+ else
+ errno = saverr; /* Restore this */
- }
- }
+ }
+ }
- return -1;
+ return -1;
- }
+ }
- return 0; /* Success ... */
+ return 0; /* Success ... */
}
@@ -914,65 +975,67 @@ int smbc_unlink(const char *fname)
int smbc_rename(const char *oname, const char *nname)
{
- fstring server1, share1, server2, share2, user1, user2, password1, password2;
- pstring path1, path2;
- struct smbc_server *srv = NULL;
+ fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup;
+ pstring path1, path2;
+ struct smbc_server *srv = NULL;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL; /* Best I can think of ... */
- return -1;
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
- }
+ }
+
+ if (!oname || !nname) {
- if (!oname || !nname) {
+ errno = EINVAL;
+ return -1;
- errno = EINVAL;
- return -1;
+ }
+
+ DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
- }
-
- DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
+ smbc_parse_path(oname, server1, share1, path1, user1, password1);
- smbc_parse_path(oname, server1, share1, path1, user1, password1);
+ if (user1[0] == (char)0) pstrcpy(user1, smbc_user);
- if (user1[0] == (char)0) pstrcpy(user1, smbc_user);
+ smbc_parse_path(nname, server2, share2, path2, user2, password2);
- smbc_parse_path(nname, server2, share2, path2, user2, password2);
+ if (user2[0] == (char)0) pstrcpy(user2, smbc_user);
- if (user2[0] == (char)0) pstrcpy(user2, smbc_user);
+ if (strcmp(server1, server2) || strcmp(share1, share2) ||
+ strcmp(user1, user2)) {
- if (strcmp(server1, server2) || strcmp(share1, share2) ||
- strcmp(user1, user2)) {
+ /* Can't rename across file systems, or users?? */
- /* Can't rename across file systems, or users?? */
+ errno = EXDEV;
+ return -1;
- errno = EXDEV;
- return -1;
+ }
- }
+ pstrcpy(workgroup, lp_workgroup());
- srv = smbc_server(server1, share1, lp_workgroup(), user1, password1);
- if (!srv) {
+ srv = smbc_server(server1, share1, workgroup, user1, password1);
+ if (!srv) {
- return -1;
+ return -1;
- }
+ }
- if (!cli_rename(&srv->cli, path1, path2)) {
- int eno = smbc_errno(&srv->cli);
+ if (!cli_rename(&srv->cli, path1, path2)) {
+ int eno = smbc_errno(&srv->cli);
- if (eno != EEXIST ||
- !cli_unlink(&srv->cli, path2) ||
- !cli_rename(&srv->cli, path1, path2)) {
+ if (eno != EEXIST ||
+ !cli_unlink(&srv->cli, path2) ||
+ !cli_rename(&srv->cli, path1, path2)) {
- errno = eno;
- return -1;
+ errno = eno;
+ return -1;
- }
- }
+ }
+ }
- return 0; /* Success */
+ return 0; /* Success */
}
@@ -982,67 +1045,67 @@ int smbc_rename(const char *oname, const char *nname)
off_t smbc_lseek(int fd, off_t offset, int whence)
{
- struct smbc_file *fe;
- size_t size;
+ struct smbc_file *fe;
+ size_t size;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
-
- }
+ errno = EINVAL;
+ return -1;
+
+ }
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe) {
+ if (!fe) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- if (!fe->file) {
+ if (!fe->file) {
- errno = EINVAL;
- return -1; /* Can't lseek a dir ... */
+ errno = EINVAL;
+ return -1; /* Can't lseek a dir ... */
- }
+ }
- switch (whence) {
- case SEEK_SET:
- fe->offset = offset;
- break;
+ switch (whence) {
+ case SEEK_SET:
+ fe->offset = offset;
+ break;
- case SEEK_CUR:
- fe->offset += offset;
- break;
+ case SEEK_CUR:
+ fe->offset += offset;
+ break;
- case SEEK_END:
- if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
- NULL, NULL, NULL) &&
- !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
- NULL)) {
+ case SEEK_END:
+ if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
+ NULL, NULL, NULL) &&
+ !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL,
+ NULL)) {
- errno = EINVAL;
- return -1;
- }
- fe->offset = size + offset;
- break;
+ errno = EINVAL;
+ return -1;
+ }
+ fe->offset = size + offset;
+ break;
- default:
- errno = EINVAL;
- break;
+ default:
+ errno = EINVAL;
+ break;
- }
+ }
- return fe->offset;
+ return fe->offset;
}
@@ -1054,8 +1117,8 @@ static
ino_t smbc_inode(const char *name)
{
- if (!*name) return 2; /* FIXME, why 2 ??? */
- return (ino_t)str_checksum(name);
+ if (!*name) return 2; /* FIXME, why 2 ??? */
+ return (ino_t)str_checksum(name);
}
@@ -1067,37 +1130,37 @@ ino_t smbc_inode(const char *name)
static
int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode)
{
+
+ st->st_mode = 0;
- st->st_mode = 0;
-
- if (IS_DOS_DIR(mode)) {
- st->st_mode = SMBC_DIR_MODE;
- } else {
- st->st_mode = SMBC_FILE_MODE;
- }
-
- if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
- if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
- if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
- if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
-
- st->st_size = size;
- st->st_blksize = 512;
- st->st_blocks = (size+511)/512;
- st->st_uid = getuid();
- st->st_gid = getgid();
-
- if (IS_DOS_DIR(mode)) {
- st->st_nlink = 2;
- } else {
- st->st_nlink = 1;
- }
+ if (IS_DOS_DIR(mode)) {
+ st->st_mode = SMBC_DIR_MODE;
+ } else {
+ st->st_mode = SMBC_FILE_MODE;
+ }
- if (st->st_ino == 0) {
- st->st_ino = smbc_inode(fname);
- }
+ if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR;
+ if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP;
+ if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH;
+ if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR;
+
+ st->st_size = size;
+ st->st_blksize = 512;
+ st->st_blocks = (size+511)/512;
+ st->st_uid = getuid();
+ st->st_gid = getgid();
+
+ if (IS_DOS_DIR(mode)) {
+ st->st_nlink = 2;
+ } else {
+ st->st_nlink = 1;
+ }
- return True; /* FIXME: Is this needed ? */
+ if (st->st_ino == 0) {
+ st->st_ino = smbc_inode(fname);
+ }
+
+ return True; /* FIXME: Is this needed ? */
}
@@ -1112,28 +1175,28 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path,
SMB_INO_T *ino)
{
- if (!smbc_initialized) {
-
- errno = EINVAL;
- return -1;
+ if (!smbc_initialized) {
+
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
+ DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
- if (!srv->no_pathinfo2 &&
- cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
- size, mode, ino)) return True;
-
- /* if this is NT then don't bother with the getatr */
- if (srv->cli.capabilities & CAP_NT_SMBS) return False;
-
- if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
- a_time = c_time = m_time;
- srv->no_pathinfo2 = True;
- return True;
- }
- return False;
+ if (!srv->no_pathinfo2 &&
+ cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
+ size, mode, ino)) return True;
+
+ /* if this is NT then don't bother with the getatr */
+ if (srv->cli.capabilities & CAP_NT_SMBS) return False;
+
+ if (cli_getatr(&srv->cli, path, mode, size, m_time)) {
+ a_time = c_time = m_time;
+ srv->no_pathinfo2 = True;
+ return True;
+ }
+ return False;
}
/*
@@ -1142,83 +1205,83 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path,
int smbc_stat(const char *fname, struct stat *st)
{
- struct smbc_server *srv;
- fstring server, share, user, password;
- pstring path;
- time_t m_time = 0, a_time = 0, c_time = 0;
- size_t size = 0;
- uint16 mode = 0;
- SMB_INO_T ino = 0;
-
- if (!smbc_initialized) {
-
- errno = EINVAL; /* Best I can think of ... */
- return -1;
-
- }
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ time_t m_time = 0, a_time = 0, c_time = 0;
+ size_t size = 0;
+ uint16 mode = 0;
+ SMB_INO_T ino = 0;
+
+ if (!smbc_initialized) {
+
+ errno = EINVAL; /* Best I can think of ... */
+ return -1;
+
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_stat(%s)\n", fname));
-
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ DEBUG(4, ("smbc_stat(%s)\n", fname));
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- if (!srv) {
+ pstrcpy(workgroup, lp_workgroup());
- return -1; /* errno set by smbc_server */
+ srv = smbc_server(server, share, workgroup, user, password);
- }
-
- /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
-
- mode = aDIR | aRONLY;
+ if (!srv) {
- }
- else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+ return -1; /* errno set by smbc_server */
- if (strcmp(path, "\\") == 0) {
+ }
- mode = aDIR | aRONLY;
+ /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
- }
- else {
+ mode = aDIR | aRONLY;
- mode = aRONLY;
- smbc_stat_printjob(srv, path, &size, &m_time);
- c_time = a_time = m_time;
+ }
+ else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+
+ if (strcmp(path, "\\") == 0) {
+
+ mode = aDIR | aRONLY;
- }
- else { */
+ }
+ else {
- if (!smbc_getatr(srv, path, &mode, &size,
- &c_time, &a_time, &m_time, &ino)) {
+ mode = aRONLY;
+ smbc_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
- errno = smbc_errno(&srv->cli);
- return -1;
+ }
+ else { */
- }
+ if (!smbc_getatr(srv, path, &mode, &size,
+ &c_time, &a_time, &m_time, &ino)) {
- /* } */
+ errno = smbc_errno(&srv->cli);
+ return -1;
+
+ }
- st->st_ino = ino;
+ st->st_ino = ino;
- smbc_setup_stat(st, path, size, mode);
+ smbc_setup_stat(st, path, size, mode);
- st->st_atime = a_time;
- st->st_ctime = c_time;
- st->st_mtime = m_time;
- st->st_dev = srv->dev;
+ st->st_atime = a_time;
+ st->st_ctime = c_time;
+ st->st_mtime = m_time;
+ st->st_dev = srv->dev;
- return 0;
+ return 0;
}
@@ -1228,61 +1291,61 @@ int smbc_stat(const char *fname, struct stat *st)
int smbc_fstat(int fd, struct stat *st)
{
- struct smbc_file *fe;
- time_t c_time, a_time, m_time;
- size_t size;
- uint16 mode;
- SMB_INO_T ino = 0;
-
- if (!smbc_initialized) {
-
- errno = EINVAL;
- return -1;
+ struct smbc_file *fe;
+ time_t c_time, a_time, m_time;
+ size_t size;
+ uint16 mode;
+ SMB_INO_T ino = 0;
- }
+ if (!smbc_initialized) {
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ errno = EINVAL;
+ return -1;
- errno = EBADF;
- return -1;
+ }
- }
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- fe = smbc_file_table[fd - smbc_start_fd];
+ errno = EBADF;
+ return -1;
+
+ }
- if (!fe) {
+ fe = smbc_file_table[fd - smbc_start_fd];
+
+ if (!fe) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- if (!fe->file) {
+ if (!fe->file) {
- return smbc_fstatdir(fd, st);
+ return smbc_fstatdir(fd, st);
- }
+ }
- if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) &&
- !cli_getattrE(&fe->srv->cli, fe->cli_fd,
- &mode, &size, &c_time, &a_time, &m_time)) {
+ if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) &&
+ !cli_getattrE(&fe->srv->cli, fe->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time)) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- st->st_ino = ino;
+ st->st_ino = ino;
- smbc_setup_stat(st, fe->fname, size, mode);
+ smbc_setup_stat(st, fe->fname, size, mode);
- st->st_atime = a_time;
- st->st_ctime = c_time;
- st->st_mtime = m_time;
- st->st_dev = fe->srv->dev;
+ st->st_atime = a_time;
+ st->st_ctime = c_time;
+ st->st_mtime = m_time;
+ st->st_dev = fe->srv->dev;
- return 0;
+ return 0;
}
@@ -1296,136 +1359,139 @@ int smbc_fstat(int fd, struct stat *st)
* smb:workgroup//server
* smb://server
* smb://server/share
+ * smb://<IP-addr> which should list shares on server
+ * smb://<IP-addr>/share which should list files on share
*/
static void smbc_remove_dir(struct smbc_file *dir)
{
- struct smbc_dir_list *d,*f;
+ struct smbc_dir_list *d,*f;
- d = dir->dir_list;
- while (d) {
+ d = dir->dir_list;
+ while (d) {
- f = d; d = d->next;
+ f = d; d = d->next;
- if (f->dirent) free(f->dirent);
- free(f);
+ SAFE_FREE(f->dirent);
+ SAFE_FREE(f);
- }
+ }
- dir->dir_list = dir->dir_end = dir->dir_next = NULL;
+ dir->dir_list = dir->dir_end = dir->dir_next = NULL;
}
static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type)
{
- struct smbc_dirent *dirent;
- int size;
+ struct smbc_dirent *dirent;
+ int size;
- /*
- * Allocate space for the dirent, which must be increased by the
- * size of the name and the comment and 1 for the null on the comment.
- * The null on the name is already accounted for.
- */
+ /*
+ * Allocate space for the dirent, which must be increased by the
+ * size of the name and the comment and 1 for the null on the comment.
+ * The null on the name is already accounted for.
+ */
- size = sizeof(struct smbc_dirent) + (name?strlen(name):0) +
- (comment?strlen(comment):0) + 1;
+ size = sizeof(struct smbc_dirent) + (name?strlen(name):0) +
+ (comment?strlen(comment):0) + 1;
- dirent = malloc(size);
+ dirent = malloc(size);
- if (!dirent) {
+ if (!dirent) {
- dir->dir_error = ENOMEM;
- return -1;
+ dir->dir_error = ENOMEM;
+ return -1;
- }
+ }
- if (dir->dir_list == NULL) {
+ if (dir->dir_list == NULL) {
- dir->dir_list = malloc(sizeof(struct smbc_dir_list));
- if (!dir->dir_list) {
+ dir->dir_list = malloc(sizeof(struct smbc_dir_list));
+ if (!dir->dir_list) {
- free(dirent);
- dir->dir_error = ENOMEM;
- return -1;
+ SAFE_FREE(dirent);
+ dir->dir_error = ENOMEM;
+ return -1;
- }
+ }
- dir->dir_end = dir->dir_next = dir->dir_list;
+ dir->dir_end = dir->dir_next = dir->dir_list;
- }
- else {
-
- dir->dir_end->next = malloc(sizeof(struct smbc_dir_list));
-
- if (!dir->dir_end) {
-
- free(dirent);
- dir->dir_error = ENOMEM;
- return -1;
+ }
+ else {
- }
+ dir->dir_end->next = malloc(sizeof(struct smbc_dir_list));
+
+ if (!dir->dir_end) {
+
+ SAFE_FREE(dirent);
+ dir->dir_error = ENOMEM;
+ return -1;
- dir->dir_end = dir->dir_end->next;
+ }
- }
+ dir->dir_end = dir->dir_end->next;
- dir->dir_end->next = NULL;
- dir->dir_end->dirent = dirent;
+ }
- dirent->smbc_type = type;
- dirent->namelen = (name?strlen(name):0);
- dirent->commentlen = (comment?strlen(comment):0);
- dirent->dirlen = size;
+ dir->dir_end->next = NULL;
+ dir->dir_end->dirent = dirent;
+
+ dirent->smbc_type = type;
+ dirent->namelen = (name?strlen(name):0);
+ dirent->commentlen = (comment?strlen(comment):0);
+ dirent->dirlen = size;
- strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
+ strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
- dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
- strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
+ dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
+ strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
- return 0;
+ return 0;
}
static void
list_fn(const char *name, uint32 type, const char *comment, void *state)
{
- struct smbc_file *dir = (struct smbc_file *)state;
- int dirent_type;
+ struct smbc_file *dir = (struct smbc_file *)state;
+ int dirent_type;
- /* We need to process the type a little ... */
+ /* We need to process the type a little ... */
- if (dir->dir_type == SMBC_FILE_SHARE) {
+ if (dir->dir_type == SMBC_FILE_SHARE) {
+
+ switch (type) {
+ case 0: /* Directory tree */
+ dirent_type = SMBC_FILE_SHARE;
+ break;
- switch (type) {
- case 0: /* Directory tree */
- dirent_type = SMBC_FILE_SHARE;
- break;
+ case 1:
+ dirent_type = SMBC_PRINTER_SHARE;
+ break;
- case 1:
- dirent_type = SMBC_PRINTER_SHARE;
- break;
+ case 2:
+ dirent_type = SMBC_COMMS_SHARE;
+ break;
- case 2:
- dirent_type = SMBC_COMMS_SHARE;
- break;
+ case 3:
+ dirent_type = SMBC_IPC_SHARE;
+ break;
- case 3:
- dirent_type = SMBC_IPC_SHARE;
- break;
+ default:
+ dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */
+ break;
+ }
- default:
- dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */
- break;
- }
-
- }
- else dirent_type = dir->dir_type;
+ }
+ else dirent_type = dir->dir_type;
- if (add_dirent(dir, name, comment, dirent_type) < 0) {
+ if (add_dirent(dir, name, comment, dirent_type) < 0) {
- /* An error occurred, what do we do? */
+ /* An error occurred, what do we do? */
+ /* FIXME: Add some code here */
- }
+ }
}
@@ -1433,321 +1499,312 @@ static void
dir_list_fn(file_info *finfo, const char *mask, void *state)
{
- /* fprintf(stderr, "Finfo->name=%s, mask=%s, mode=%0X\n", finfo->name, mask, finfo->mode);*/
- if (add_dirent((struct smbc_file *)state, finfo->name, "",
- (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
+ if (add_dirent((struct smbc_file *)state, finfo->name, "",
+ (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) {
+
+ /* Handle an error ... */
- /* Handle an error ... */
+ /* FIXME: Add some code ... */
- }
+ }
}
int smbc_opendir(const char *fname)
{
- fstring server, share, user, password;
- pstring path;
- struct smbc_server *srv = NULL;
- struct in_addr rem_ip;
- int slot = 0;
- uint8 eclass;
- uint32 ecode;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ struct smbc_server *srv = NULL;
+ struct in_addr rem_ip;
+ int slot = 0;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
+
+ }
- }
+ if (smbc_parse_path(fname, server, share, path, user, password)) {
- if (smbc_parse_path(fname, server, share, path, user, password)) {
+ errno = EINVAL;
+ return -1;
- errno = EINVAL;
- return -1;
+ }
- }
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ pstrcpy(workgroup, lp_workgroup());
- /* Get a file entry ... */
+ /* Get a file entry ... */
- slot = 0;
+ slot = 0;
- while (smbc_file_table[slot])
- slot++;
+ while (smbc_file_table[slot])
+ slot++;
- if (slot > smbc_max_fd) {
+ if (slot > SMBC_MAX_FD) {
- errno = ENOMEM;
- return -1; /* FIXME, ... move into a func */
+ errno = ENOMEM;
+ return -1; /* FIXME, ... move into a func */
- }
+ }
- smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
+ smbc_file_table[slot] = malloc(sizeof(struct smbc_file));
- if (!smbc_file_table[slot]) {
+ if (!smbc_file_table[slot]) {
- errno = ENOMEM;
- return -1;
+ errno = ENOMEM;
+ return -1;
- }
+ }
- smbc_file_table[slot]->cli_fd = 0;
- smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
- smbc_file_table[slot]->fname = strdup(fname);
- smbc_file_table[slot]->srv = NULL;
- smbc_file_table[slot]->offset = 0;
- smbc_file_table[slot]->file = False;
- smbc_file_table[slot]->dir_list =
- smbc_file_table[slot]->dir_next =
- smbc_file_table[slot]->dir_end = NULL;
+ smbc_file_table[slot]->cli_fd = 0;
+ smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd;
+ smbc_file_table[slot]->fname = strdup(fname);
+ smbc_file_table[slot]->srv = NULL;
+ smbc_file_table[slot]->offset = 0;
+ smbc_file_table[slot]->file = False;
+ smbc_file_table[slot]->dir_list =
+ smbc_file_table[slot]->dir_next =
+ smbc_file_table[slot]->dir_end = NULL;
- if (server[0] == (char)0) {
+ if (server[0] == (char)0) {
- if (share[0] != (char)0 || path[0] != (char)0) {
+ if (share[0] != (char)0 || path[0] != (char)0) {
- errno = EINVAL;
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
-
- }
+ errno = EINVAL;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- /* We have server and share and path empty ... so list the workgroups */
+ }
- /*cli_get_backup_server(my_netbios_name, lp_workgroup(), server, sizeof(server));*/
+ /* We have server and share and path empty ... so list the workgroups */
- if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) {
+ if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) {
- errno = EINVAL; /* Something wrong with smb.conf? */
- return -1;
+ errno = EINVAL; /* Something wrong with smb.conf? */
+ return -1;
- }
+ }
- smbc_file_table[slot]->dir_type = SMBC_WORKGROUP;
+ smbc_file_table[slot]->dir_type = SMBC_WORKGROUP;
- /* find the name of the server ... */
+ /* find the name of the server ... */
- if (!name_status_find(0, rem_ip, server)) {
+ if (!name_status_find("*", 0, 0, rem_ip, server)) {
- fprintf(stderr, "Could not get the name of local master browser ...\n");
- errno = EINVAL;
- return -1;
+ DEBUG(0,("Could not get the name of local master browser for server %s\n", server));
+ errno = EINVAL;
+ return -1;
- }
+ }
- /*
- * Get a connection to IPC$ on the server if we do not already have one
- */
+ /*
+ * Get a connection to IPC$ on the server if we do not already have one
+ */
- srv = smbc_server(server, "IPC$", lp_workgroup(), user, password);
+ srv = smbc_server(server, "IPC$", workgroup, user, password);
- if (!srv) {
+ if (!srv) {
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+
+ return -1;
- }
+ }
- smbc_file_table[slot]->srv = srv;
+ smbc_file_table[slot]->srv = srv;
- /* Now, list the stuff ... */
+ /* Now, list the stuff ... */
- if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x80000000, list_fn,
- (void *)smbc_file_table[slot])) {
+ if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn,
+ (void *)smbc_file_table[slot])) {
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- errno = cli_error(&srv->cli, &eclass, &ecode, NULL);
- return -1;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ errno = cli_errno(&srv->cli);
- }
- }
- else { /* Server not an empty string ... Check the rest and see what gives */
+ return -1;
+
+ }
+ }
+ else { /* Server not an empty string ... Check the rest and see what gives */
- if (share[0] == (char)0) {
+ if (share[0] == (char)0) {
- if (path[0] != (char)0) { /* Should not have empty share with path */
+ if (path[0] != (char)0) { /* Should not have empty share with path */
- errno = EINVAL;
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ errno = EINVAL;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- }
-
- /* Check to see if <server><1D> translates, or <server><20> translates */
+ }
- if (resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */
- pstring buserver;
+ /* Check to see if <server><1D> translates, or <server><20> translates */
+ /* However, we check to see if <server> is an IP address first */
- smbc_file_table[slot]->dir_type = SMBC_SERVER;
+ if (!is_ipaddress(server) && /* Not an IP addr so check next */
+ resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */
+ pstring buserver;
- /*
- * Get the backup list ...
- */
+ smbc_file_table[slot]->dir_type = SMBC_SERVER;
- /*cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); */
+ /*
+ * Get the backup list ...
+ */
- if (!name_status_find(0, rem_ip, buserver)) {
- fprintf(stderr, "Could not get name of local master browser ...\n");
- errno = EPERM; /* FIXME, is this correct */
- return -1;
+ if (!name_status_find("*", 0, 0, rem_ip, buserver)) {
- }
+ DEBUG(0, ("Could not get name of local master browser for server %s\n", server));
+ errno = EPERM; /* FIXME, is this correct */
+ return -1;
- /*
- * Get a connection to IPC$ on the server if we do not already have one
- */
+ }
- srv = smbc_server(buserver, "IPC$", lp_workgroup(), user, password);
+ /*
+ * Get a connection to IPC$ on the server if we do not already have one
+ */
- if (!srv) {
+ srv = smbc_server(buserver, "IPC$", workgroup, user, password);
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL; /* FIXME: Memory leaks ... */
- return -1;
+ if (!srv) {
- }
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- smbc_file_table[slot]->srv = srv;
+ }
- /* Now, list the servers ... */
+ smbc_file_table[slot]->srv = srv;
- if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn,
- (void *)smbc_file_table[slot])) {
+ /* Now, list the servers ... */
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- errno = cli_error(&srv->cli, &eclass, &ecode, NULL);
- return -1;
+ if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn,
+ (void *)smbc_file_table[slot])) {
- }
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ errno = cli_errno(&srv->cli);
+ return -1;
+
+ }
- }
- else {
+ }
+ else {
- if (resolve_name(server, &rem_ip, 0x20)) {
+ if (resolve_name(server, &rem_ip, 0x20)) {
- /* Now, list the shares ... */
+ /* Now, list the shares ... */
- smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
+ smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(server, "IPC$", lp_workgroup(), user, password);
+ srv = smbc_server(server, "IPC$", workgroup, user, password);
- if (!srv) {
+ if (!srv) {
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- }
+ }
- smbc_file_table[slot]->srv = srv;
+ smbc_file_table[slot]->srv = srv;
- /* Now, list the servers ... */
+ /* Now, list the servers ... */
- if (cli_RNetShareEnum(&srv->cli, list_fn,
- (void *)smbc_file_table[slot]) < 0) {
+ if (cli_RNetShareEnum(&srv->cli, list_fn,
+ (void *)smbc_file_table[slot]) < 0) {
- errno = cli_error(&srv->cli, &eclass, &ecode, NULL);
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ errno = cli_errno(&srv->cli);
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- }
+ }
- }
- else {
+ }
+ else {
- errno = ENODEV; /* Neither the workgroup nor server exists */
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ errno = ENODEV; /* Neither the workgroup nor server exists */
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- }
+ }
- }
+ }
- }
- else { /* The server and share are specified ... work from there ... */
+ }
+ else { /* The server and share are specified ... work from there ... */
- /* Well, we connect to the server and list the directory */
+ /* Well, we connect to the server and list the directory */
- smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
+ smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ srv = smbc_server(server, share, workgroup, user, password);
- if (!srv) {
+ if (!srv) {
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- return -1;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ return -1;
- }
+ }
- smbc_file_table[slot]->srv = srv;
+ smbc_file_table[slot]->srv = srv;
- /* Now, list the files ... */
+ /* Now, list the files ... */
- pstrcat(path, "\\*");
+ pstrcat(path, "\\*");
- if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn,
- (void *)smbc_file_table[slot]) < 0) {
+ if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn,
+ (void *)smbc_file_table[slot]) < 0) {
- if (smbc_file_table[slot]) {
- if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname);
- free(smbc_file_table[slot]);
- }
- smbc_file_table[slot] = NULL;
- errno = smbc_errno(&srv->cli);
- return -1;
+ if (smbc_file_table[slot]) {
+ SAFE_FREE(smbc_file_table[slot]->fname);
+ SAFE_FREE(smbc_file_table[slot]);
+ }
+ errno = smbc_errno(&srv->cli);
+ return -1;
- }
- }
+ }
+ }
- }
+ }
- return smbc_file_table[slot]->smbc_fd;
+ return smbc_file_table[slot]->smbc_fd;
}
@@ -1757,43 +1814,43 @@ int smbc_opendir(const char *fname)
int smbc_closedir(int fd)
{
- struct smbc_file *fe;
-
- if (!smbc_initialized) {
+ struct smbc_file *fe;
- errno = EINVAL;
- return -1;
+ if (!smbc_initialized) {
- }
+ errno = EINVAL;
+ return -1;
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ }
- errno = EBADF;
- return -1;
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- }
+ errno = EBADF;
+ return -1;
+
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe) {
+ if (!fe) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- smbc_remove_dir(fe); /* Clean it up */
+ smbc_remove_dir(fe); /* Clean it up */
- if (fe) {
+ if (fe) {
- if (fe->fname) free(fe->fname);
- free(fe); /* Free the space too */
+ SAFE_FREE(fe->fname);
+ SAFE_FREE(fe); /* Free the space too */
- }
+ }
- smbc_file_table[fd - smbc_start_fd] = NULL;
+ smbc_file_table[fd - smbc_start_fd] = NULL;
- return 0;
+ return 0;
}
@@ -1805,66 +1862,63 @@ static char smbc_local_dirent[512]; /* Make big enough */
struct smbc_dirent *smbc_readdir(unsigned int fd)
{
- struct smbc_file *fe;
- struct smbc_dirent *dirp, *dirent;
-
- /* Check that all is ok first ... */
+ struct smbc_file *fe;
+ struct smbc_dirent *dirp, *dirent;
- if (!smbc_initialized) {
+ /* Check that all is ok first ... */
- errno = EINVAL;
- return NULL;
+ if (!smbc_initialized) {
- }
+ errno = EINVAL;
+ return NULL;
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
-
- errno = EBADF;
- return NULL;
+ }
- }
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- fe = smbc_file_table[fd - smbc_start_fd];
+ errno = EBADF;
+ return NULL;
- if (!fe) {
+ }
- errno = EBADF;
- return NULL;
+ fe = smbc_file_table[fd - smbc_start_fd];
- }
+ if (!fe) {
- if (fe->file != False) { /* FIXME, should be dir, perhaps */
+ errno = EBADF;
+ return NULL;
- errno = ENOTDIR;
- return NULL;
+ }
- }
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
- if (!fe->dir_next)
- return NULL;
- else {
+ errno = ENOTDIR;
+ return NULL;
- dirent = fe->dir_next->dirent;
+ }
- if (!dirent) {
+ if (!fe->dir_next)
+ return NULL;
+ else {
- errno = ENOENT;
- return NULL;
+ dirent = fe->dir_next->dirent;
- }
+ if (!dirent) {
- /* Hmmm, do I even need to copy it? */
+ errno = ENOENT;
+ return NULL;
- bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */
+ }
- dirp = (struct smbc_dirent *)smbc_local_dirent;
+ /* Hmmm, do I even need to copy it? */
- dirp->comment = (char *)(&dirp->name + dirent->namelen + 1);
-
- fe->dir_next = fe->dir_next->next;
+ bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */
+ dirp = (struct smbc_dirent *)smbc_local_dirent;
+ dirp->comment = (char *)(&dirp->name + dirent->namelen + 1);
+ fe->dir_next = fe->dir_next->next;
- return (struct smbc_dirent *)smbc_local_dirent;
- }
+ return (struct smbc_dirent *)smbc_local_dirent;
+ }
}
@@ -1874,95 +1928,95 @@ struct smbc_dirent *smbc_readdir(unsigned int fd)
int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count)
{
- struct smbc_file *fe;
- struct smbc_dir_list *dir;
- int rem = count, reqd;
- char *ndir = (char *)dirp;
-
- /* Check that all is ok first ... */
+ struct smbc_file *fe;
+ struct smbc_dir_list *dir;
+ int rem = count, reqd;
+ char *ndir = (char *)dirp;
- if (!smbc_initialized) {
+ /* Check that all is ok first ... */
- errno = EINVAL;
- return -1;
+ if (!smbc_initialized) {
- }
+ errno = EINVAL;
+ return -1;
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ }
- errno = EBADF;
- return -1;
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- }
+ errno = EBADF;
+ return -1;
- fe = smbc_file_table[fd - smbc_start_fd];
+ }
- if (!fe) {
+ fe = smbc_file_table[fd - smbc_start_fd];
- errno = EBADF;
- return -1;
+ if (!fe) {
- }
+ errno = EBADF;
+ return -1;
+
+ }
- if (fe->file != False) { /* FIXME, should be dir, perhaps */
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
- errno = ENOTDIR;
- return -1;
+ errno = ENOTDIR;
+ return -1;
- }
+ }
- /*
- * Now, retrieve the number of entries that will fit in what was passed
- * We have to figure out if the info is in the list, or we need to
- * send a request to the server to get the info.
- */
+ /*
+ * Now, retrieve the number of entries that will fit in what was passed
+ * We have to figure out if the info is in the list, or we need to
+ * send a request to the server to get the info.
+ */
- while ((dir = fe->dir_next)) {
- struct smbc_dirent *dirent;
+ while ((dir = fe->dir_next)) {
+ struct smbc_dirent *dirent;
- if (!dir->dirent) {
+ if (!dir->dirent) {
- errno = ENOENT; /* Bad error */
- return -1;
+ errno = ENOENT; /* Bad error */
+ return -1;
- }
+ }
- if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen +
- dir->dirent->commentlen + 1))) {
+ if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen +
+ dir->dirent->commentlen + 1))) {
- if (rem < count) { /* We managed to copy something */
+ if (rem < count) { /* We managed to copy something */
- errno = 0;
- return count - rem;
+ errno = 0;
+ return count - rem;
- }
- else { /* Nothing copied ... */
+ }
+ else { /* Nothing copied ... */
- errno = EINVAL; /* Not enough space ... */
- return -1;
+ errno = EINVAL; /* Not enough space ... */
+ return -1;
- }
+ }
- }
+ }
- dirent = dir->dirent;
+ dirent = dir->dirent;
- bcopy(dirent, ndir, reqd); /* Copy the data in ... */
+ bcopy(dirent, ndir, reqd); /* Copy the data in ... */
- ((struct smbc_dirent *)ndir)->comment =
- (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1);
+ ((struct smbc_dirent *)ndir)->comment =
+ (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1);
- ndir += reqd;
+ ndir += reqd;
- rem -= reqd;
+ rem -= reqd;
- fe->dir_next = dir = dir -> next;
- }
+ fe->dir_next = dir = dir -> next;
+ }
- if (rem == count)
- return 0;
- else
- return count - rem;
+ if (rem == count)
+ return 0;
+ else
+ return count - rem;
}
@@ -1972,67 +2026,69 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count)
int smbc_mkdir(const char *fname, mode_t mode)
{
- struct smbc_server *srv;
- fstring server, share, user, password;
- pstring path;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_mkdir(%s)\n", fname));
+ DEBUG(4, ("smbc_mkdir(%s)\n", fname));
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* errno set by smbc_server */
+ if (!srv) {
- }
+ return -1; /* errno set by smbc_server */
+
+ }
- /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
+ /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
- mode = aDIR | aRONLY;
+ mode = aDIR | aRONLY;
- }
- else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+ }
+ else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
- if (strcmp(path, "\\") == 0) {
+ if (strcmp(path, "\\") == 0) {
- mode = aDIR | aRONLY;
+ mode = aDIR | aRONLY;
- }
- else {
+ }
+ else {
- mode = aRONLY;
- smbc_stat_printjob(srv, path, &size, &m_time);
- c_time = a_time = m_time;
+ mode = aRONLY;
+ smbc_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
- }
- else { */
+ }
+ else { */
- if (!cli_mkdir(&srv->cli, path)) {
+ if (!cli_mkdir(&srv->cli, path)) {
- errno = smbc_errno(&srv->cli);
- return -1;
+ errno = smbc_errno(&srv->cli);
+ return -1;
- }
+ }
- return 0;
+ return 0;
}
@@ -2045,8 +2101,8 @@ static int smbc_rmdir_dirempty = True;
static void rmdir_list_fn(file_info *finfo, const char *mask, void *state)
{
- if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0)
- smbc_rmdir_dirempty = False;
+ if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0)
+ smbc_rmdir_dirempty = False;
}
@@ -2056,95 +2112,97 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state)
int smbc_rmdir(const char *fname)
{
- struct smbc_server *srv;
- fstring server, share, user, password;
- pstring path;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_rmdir(%s)\n", fname));
+ DEBUG(4, ("smbc_rmdir(%s)\n", fname));
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* errno set by smbc_server */
+ if (!srv) {
- }
+ return -1; /* errno set by smbc_server */
- /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
+ }
- mode = aDIR | aRONLY;
+ /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
- }
- else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+ mode = aDIR | aRONLY;
- if (strcmp(path, "\\") == 0) {
+ }
+ else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
- mode = aDIR | aRONLY;
+ if (strcmp(path, "\\") == 0) {
- }
- else {
+ mode = aDIR | aRONLY;
- mode = aRONLY;
- smbc_stat_printjob(srv, path, &size, &m_time);
- c_time = a_time = m_time;
+ }
+ else {
- }
- else { */
+ mode = aRONLY;
+ smbc_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
+
+ }
+ else { */
- if (!cli_rmdir(&srv->cli, path)) {
+ if (!cli_rmdir(&srv->cli, path)) {
- errno = smbc_errno(&srv->cli);
+ errno = smbc_errno(&srv->cli);
- if (errno == EACCES) { /* Check if the dir empty or not */
+ if (errno == EACCES) { /* Check if the dir empty or not */
- pstring lpath; /* Local storage to avoid buffer overflows */
+ pstring lpath; /* Local storage to avoid buffer overflows */
- smbc_rmdir_dirempty = True; /* Make this so ... */
+ smbc_rmdir_dirempty = True; /* Make this so ... */
- pstrcpy(lpath, path);
- pstrcat(lpath, "\\*");
+ pstrcpy(lpath, path);
+ pstrcat(lpath, "\\*");
- if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn,
- NULL) < 0) {
+ if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn,
+ NULL) < 0) {
- /* Fix errno to ignore latest error ... */
+ /* Fix errno to ignore latest error ... */
- DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n",
- smbc_errno(&srv->cli)));
- errno = EACCES;
+ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n",
+ smbc_errno(&srv->cli)));
+ errno = EACCES;
- }
+ }
- if (smbc_rmdir_dirempty)
- errno = EACCES;
- else
- errno = ENOTEMPTY;
+ if (smbc_rmdir_dirempty)
+ errno = EACCES;
+ else
+ errno = ENOTEMPTY;
- }
+ }
- return -1;
+ return -1;
- }
+ }
- return 0;
+ return 0;
}
@@ -2154,39 +2212,39 @@ int smbc_rmdir(const char *fname)
off_t smbc_telldir(int fd)
{
- struct smbc_file *fe;
+ struct smbc_file *fe;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe) {
+ if (!fe) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- if (fe->file != False) { /* FIXME, should be dir, perhaps */
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
- errno = ENOTDIR;
- return -1;
+ errno = ENOTDIR;
+ return -1;
- }
+ }
- return (off_t) fe->dir_next;
+ return (off_t) fe->dir_next;
}
@@ -2198,24 +2256,24 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list,
struct smbc_dirent *dirent)
{
- /* Run down the list looking for what we want */
+ /* Run down the list looking for what we want */
- if (dirent) {
+ if (dirent) {
- struct smbc_dir_list *tmp = list;
+ struct smbc_dir_list *tmp = list;
- while (tmp) {
+ while (tmp) {
- if (tmp->dirent == dirent)
- return tmp;
+ if (tmp->dirent == dirent)
+ return tmp;
- tmp = tmp->next;
+ tmp = tmp->next;
- }
+ }
- }
+ }
- return NULL; /* Not found, or an error */
+ return NULL; /* Not found, or an error */
}
@@ -2226,62 +2284,62 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list,
int smbc_lseekdir(int fd, off_t offset)
{
- struct smbc_file *fe;
- struct smbc_dirent *dirent = (struct smbc_dirent *)offset;
- struct smbc_dir_list *list_ent = NULL;
+ struct smbc_file *fe;
+ struct smbc_dirent *dirent = (struct smbc_dirent *)offset;
+ struct smbc_dir_list *list_ent = NULL;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) {
+ if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- fe = smbc_file_table[fd - smbc_start_fd];
+ fe = smbc_file_table[fd - smbc_start_fd];
- if (!fe) {
+ if (!fe) {
- errno = EBADF;
- return -1;
+ errno = EBADF;
+ return -1;
- }
+ }
- if (fe->file != False) { /* FIXME, should be dir, perhaps */
+ if (fe->file != False) { /* FIXME, should be dir, perhaps */
- errno = ENOTDIR;
- return -1;
+ errno = ENOTDIR;
+ return -1;
- }
+ }
- /* Now, check what we were passed and see if it is OK ... */
+ /* Now, check what we were passed and see if it is OK ... */
- if (dirent == NULL) { /* Seek to the begining of the list */
+ if (dirent == NULL) { /* Seek to the begining of the list */
- fe->dir_next = fe->dir_list;
- return 0;
+ fe->dir_next = fe->dir_list;
+ return 0;
- }
+ }
- /* Now, run down the list and make sure that the entry is OK */
- /* This may need to be changed if we change the format of the list */
+ /* Now, run down the list and make sure that the entry is OK */
+ /* This may need to be changed if we change the format of the list */
- if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) {
+ if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) {
- errno = EINVAL; /* Bad entry */
- return -1;
+ errno = EINVAL; /* Bad entry */
+ return -1;
- }
+ }
- fe->dir_next = list_ent;
+ fe->dir_next = list_ent;
- return 0;
+ return 0;
}
@@ -2292,16 +2350,16 @@ int smbc_lseekdir(int fd, off_t offset)
int smbc_fstatdir(int fd, struct stat *st)
{
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- /* No code yet ... */
+ /* No code yet ... */
- return 0;
+ return 0;
}
@@ -2314,71 +2372,71 @@ int smbc_fstatdir(int fd, struct stat *st)
int smbc_print_file(const char *fname, const char *printq)
{
- int fid1, fid2, bytes, saverr, tot_bytes = 0;
- char buf[4096];
-
- if (!smbc_initialized) {
-
- errno = EINVAL;
- return -1;
+ int fid1, fid2, bytes, saverr, tot_bytes = 0;
+ char buf[4096];
- }
+ if (!smbc_initialized) {
- if (!fname && !printq) {
+ errno = EINVAL;
+ return -1;
- errno = EINVAL;
- return -1;
+ }
- }
+ if (!fname && !printq) {
- /* Try to open the file for reading ... */
+ errno = EINVAL;
+ return -1;
- if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) {
+ }
- fprintf(stderr, "Error, fname=%s, errno=%i\n", fname, errno);
- return -1; /* smbc_open sets errno */
+ /* Try to open the file for reading ... */
- }
+ if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) {
+
+ DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
+ return -1; /* smbc_open sets errno */
+
+ }
- /* Now, try to open the printer file for writing */
+ /* Now, try to open the printer file for writing */
- if ((fid2 = smbc_open_print_job(printq)) < 0) {
+ if ((fid2 = smbc_open_print_job(printq)) < 0) {
- saverr = errno; /* Save errno */
- smbc_close(fid1);
- errno = saverr;
- return -1;
+ saverr = errno; /* Save errno */
+ smbc_close(fid1);
+ errno = saverr;
+ return -1;
- }
+ }
- while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) {
+ while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) {
- tot_bytes += bytes;
+ tot_bytes += bytes;
- if ((smbc_write(fid2, buf, bytes)) < 0) {
+ if ((smbc_write(fid2, buf, bytes)) < 0) {
- saverr = errno;
- smbc_close(fid1);
- smbc_close(fid2);
- errno = saverr;
+ saverr = errno;
+ smbc_close(fid1);
+ smbc_close(fid2);
+ errno = saverr;
- }
+ }
- }
+ }
- saverr = errno;
+ saverr = errno;
- smbc_close(fid1); /* We have to close these anyway */
- smbc_close(fid2);
+ smbc_close(fid1); /* We have to close these anyway */
+ smbc_close(fid2);
- if (bytes < 0) {
+ if (bytes < 0) {
- errno = saverr;
- return -1;
+ errno = saverr;
+ return -1;
- }
+ }
- return tot_bytes;
+ return tot_bytes;
}
@@ -2388,30 +2446,30 @@ int smbc_print_file(const char *fname, const char *printq)
int smbc_open_print_job(const char *fname)
{
- fstring server, share, user, password;
- pstring path;
-
- if (!smbc_initialized) {
-
- errno = EINVAL;
- return -1;
+ fstring server, share, user, password;
+ pstring path;
+
+ if (!smbc_initialized) {
- }
+ errno = EINVAL;
+ return -1;
+
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_open_print_job(%s)\n", fname));
+ DEBUG(4, ("smbc_open_print_job(%s)\n", fname));
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- /* What if the path is empty, or the file exists? */
+ /* What if the path is empty, or the file exists? */
- return smbc_open(fname, O_WRONLY, 666);
+ return smbc_open(fname, O_WRONLY, 666);
}
@@ -2421,46 +2479,48 @@ int smbc_open_print_job(const char *fname)
int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *))
{
- struct smbc_server *srv;
- fstring server, share, user, password;
- pstring path;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
-
- if (!fname) {
+ }
- errno = EINVAL;
- return -1;
+ if (!fname) {
+
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
-
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
+
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* errno set by smbc_server */
+ if (!srv) {
- }
+ return -1; /* errno set by smbc_server */
- if (cli_print_queue(&srv->cli, fn) < 0) {
+ }
- errno = smbc_errno(&srv->cli);
- return -1;
+ if (cli_print_queue(&srv->cli, fn) < 0) {
- }
+ errno = smbc_errno(&srv->cli);
+ return -1;
- return 0;
+ }
+
+ return 0;
}
@@ -2470,51 +2530,52 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *))
int smbc_unlink_print_job(const char *fname, int id)
{
- struct smbc_server *srv;
- fstring server, share, user, password;
- pstring path;
- int err;
+ struct smbc_server *srv;
+ fstring server, share, user, password, workgroup;
+ pstring path;
+ int err;
- if (!smbc_initialized) {
+ if (!smbc_initialized) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- if (!fname) {
+ if (!fname) {
- errno = EINVAL;
- return -1;
+ errno = EINVAL;
+ return -1;
- }
+ }
- DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
+ DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
- smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
+ smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/
- if (user[0] == (char)0) pstrcpy(user, smbc_user);
+ if (user[0] == (char)0) pstrcpy(user, smbc_user);
- srv = smbc_server(server, share, lp_workgroup(), user, password);
+ pstrcpy(workgroup, lp_workgroup());
- if (!srv) {
+ srv = smbc_server(server, share, workgroup, user, password);
- return -1; /* errno set by smbc_server */
+ if (!srv) {
- }
+ return -1; /* errno set by smbc_server */
- if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+ }
- if (err < 0)
- errno = smbc_errno(&srv->cli);
- else if (err == ERRnosuchprintjob)
- errno = EINVAL;
- return -1;
+ if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+ if (err < 0)
+ errno = smbc_errno(&srv->cli);
+ else if (err == ERRnosuchprintjob)
+ errno = EINVAL;
+ return -1;
- }
+ }
- return 0;
+ return 0;
}
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index aa6301cc38e..d9a61d9368c 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* nmbd.c sets this to True. */
BOOL global_in_nmbd = False;
@@ -75,7 +73,7 @@ static struct node_status *parse_node_status(char *p, int *num_names)
do a NBT node status query on an open socket and return an array of
structures holding the returned names or NULL if the query failed
**************************************************************************/
-struct node_status *name_status_query(int fd,struct nmb_name *name,
+struct node_status *node_status_query(int fd,struct nmb_name *name,
struct in_addr to_ip, int *num_names)
{
BOOL found=False;
@@ -162,7 +160,8 @@ find the first type XX name in a node status reply - used for finding
a servers name given its IP
return the matched name in *name
**************************************************************************/
-BOOL name_status_find(int type, struct in_addr to_ip, char *name)
+
+BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
{
struct node_status *status;
struct nmb_name nname;
@@ -170,23 +169,28 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name)
int sock;
sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
- if (sock == -1) return False;
+ if (sock == -1)
+ return False;
- make_nmb_name(&nname, "*", 0);
- status = name_status_query(sock, &nname, to_ip, &count);
+ /* W2K PDC's seem not to respond to '*'#0. JRA */
+ make_nmb_name(&nname, q_name, q_type);
+ status = node_status_query(sock, &nname, to_ip, &count);
close(sock);
- if (!status) return False;
+ if (!status)
+ return False;
for (i=0;i<count;i++) {
- if (status[i].type == type) break;
+ if (status[i].type == type)
+ break;
}
- if (i == count) return False;
+ if (i == count)
+ return False;
StrnCpy(name, status[i].name, 15);
dos_to_unix(name, True);
- free(status);
+ SAFE_FREE(status);
return True;
}
@@ -209,7 +213,7 @@ BOOL name_register(int fd, const char *name, int name_type,
register_ip.s_addr = name_ip.s_addr; /* Fix this ... */
- bzero((char *)&p, sizeof(p));
+ memset((char *)&p, '\0', sizeof(p));
*count = 0;
@@ -241,7 +245,7 @@ BOOL name_register(int fd, const char *name, int name_type,
}
- bzero((char *)nmb->additional, sizeof(struct res_rec));
+ memset((char *)nmb->additional, '\0', sizeof(struct res_rec));
nmb->additional->rr_name = nmb->question.question_name;
nmb->additional->rr_type = RR_TYPE_NB;
@@ -275,7 +279,7 @@ BOOL name_register(int fd, const char *name, int name_type,
if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) {
debug_nmb_packet(p2);
- free(p2); /* No memory leaks ... */
+ SAFE_FREE(p2); /* No memory leaks ... */
}
return True;
@@ -407,8 +411,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
if (!tmp_ip_list) {
DEBUG(0,("name_query: Realloc failed.\n"));
- if (ip_list)
- free(ip_list);
+ SAFE_FREE(ip_list);
}
ip_list = tmp_ip_list;
@@ -867,10 +870,7 @@ static BOOL internal_resolve_name(const char *name, int name_type,
}
}
- if((*return_iplist) != NULL) {
- free((char *)(*return_iplist));
- *return_iplist = NULL;
- }
+ SAFE_FREE(*return_iplist);
return False;
}
@@ -886,13 +886,26 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
struct in_addr *ip_list = NULL;
int count = 0;
- if(internal_resolve_name(name, name_type, &ip_list, &count)) {
- *return_ip = ip_list[0];
- free((char *)ip_list);
+ if (is_ipaddress(name)) {
+ *return_ip = *interpret_addr2(name);
return True;
}
- if(ip_list != NULL)
- free((char *)ip_list);
+
+ if(internal_resolve_name(name, name_type, &ip_list, &count)) {
+ int i;
+ /* only return valid addresses for TCP connections */
+ for (i=0; i<count; i++) {
+ char *ip_str = inet_ntoa(ip_list[i]);
+ if (ip_str &&
+ strcmp(ip_str, "255.255.255.255") != 0 &&
+ strcmp(ip_str, "0.0.0.0") != 0) {
+ *return_ip = ip_list[i];
+ SAFE_FREE(ip_list);
+ return True;
+ }
+ }
+ }
+ SAFE_FREE(ip_list);
return False;
}
@@ -928,7 +941,7 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
if (strcmp(dest_host,"*") == 0) {
extern pstring global_myname;
ret = resolve_name(lp_workgroup(), ip, 0x1B);
- lookup_pdc_name(global_myname, lp_workgroup(), ip, dest_host);
+ lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host);
} else {
ret = resolve_name(dest_host, ip, 0x20);
}
@@ -953,46 +966,46 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip)
if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
*master_ip = ip_list[0];
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
return True;
}
if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
*master_ip = ip_list[0];
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
return True;
}
- if(ip_list != NULL)
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
return False;
}
/********************************************************
- Lookup a PDC name given a Domain name and IP address.
+ Lookup a DC name given a Domain name and IP address.
*********************************************************/
-BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name)
+BOOL lookup_dc_name(const char *srcname, const char *domain,
+ struct in_addr *dc_ip, char *ret_name)
{
#if !defined(I_HATE_WINDOWS_REPLY_CODE)
- fstring pdc_name;
- BOOL ret;
+ fstring dc_name;
+ BOOL ret;
- /*
- * Due to the fact win WinNT *sucks* we must do a node status
- * query here... JRA.
- */
+ /*
+ * Due to the fact win WinNT *sucks* we must do a node status
+ * query here... JRA.
+ */
- *pdc_name = '\0';
+ *dc_name = '\0';
- ret = name_status_find(0x20,*pdc_ip,pdc_name);
+ ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
- if(ret && *pdc_name) {
- fstrcpy(ret_name, pdc_name);
- return True;
- }
+ if(ret && *dc_name) {
+ fstrcpy(ret_name, dc_name);
+ return True;
+ }
- return False;
+ return False;
#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
@@ -1021,7 +1034,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
/* Find out the transient UDP port we have been allocated. */
if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
- DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
+ DEBUG(0,("lookup_dc_name: Failed to get local UDP port. Error was %s\n",
strerror(errno)));
close(sock);
return False;
@@ -1098,7 +1111,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
GetTimeOfDay(&tval);
if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+ DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
close(sock);
return False;
}
@@ -1114,7 +1127,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
if (!retries)
break;
if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+ DEBUG(0,("lookup_dc_name: send_packet failed.\n"));
close(sock);
return False;
}
@@ -1131,7 +1144,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
buf -= 4;
if (CVAL(buf,smb_com) != SMBtrans) {
- DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
+ DEBUG(0,("lookup_dc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
CVAL(buf,smb_com), (unsigned int)SMBtrans ));
free_packet(p_ret);
continue;
@@ -1141,17 +1154,17 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
if (len <= 0) {
- DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
+ DEBUG(0,("lookup_dc_name: datagram len < 0 (%d)\n", len ));
free_packet(p_ret);
continue;
}
- DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
+ DEBUG(4,("lookup_dc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
if(SVAL(buf2,0) != QUERYFORPDC_R) {
- DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
+ DEBUG(0,("lookup_dc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
(unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
free_packet(p_ret);
continue;
@@ -1176,7 +1189,58 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
/********************************************************
Get the IP address list of the PDC/BDC's of a Domain.
*********************************************************/
+
BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count)
{
- return internal_resolve_name(group, pdc_only ? 0x1B : 0x1C, ip_list, count);
+ int name_type = pdc_only ? 0x1B : 0x1C;
+
+ /*
+ * If it's our domain then
+ * use the 'password server' parameter.
+ */
+
+ if (strequal(group, lp_workgroup())) {
+ char *p;
+ char *pserver = lp_passwordserver();
+ fstring name;
+ int num_adresses = 0;
+ struct in_addr *return_iplist = NULL;
+
+ if (! *pserver)
+ return internal_resolve_name(group, name_type, ip_list, count);
+
+ p = pserver;
+ while (next_token(&p,name,LIST_SEP,sizeof(name))) {
+ if (strequal(name, "*"))
+ return internal_resolve_name(group, name_type, ip_list, count);
+ num_adresses++;
+ }
+ if (num_adresses == 0)
+ return internal_resolve_name(group, name_type, ip_list, count);
+
+ return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
+ if(return_iplist == NULL) {
+ DEBUG(3,("get_dc_list: malloc fail !\n"));
+ return False;
+ }
+ p = pserver;
+ *count = 0;
+ while (next_token(&p,name,LIST_SEP,sizeof(name))) {
+ struct in_addr name_ip;
+ if (resolve_name( name, &name_ip, 0x20) == False)
+ continue;
+ return_iplist[(*count)++] = name_ip;
+ }
+ *ip_list = return_iplist;
+ return (*count != 0);
+ } else
+ return internal_resolve_name(group, name_type, ip_list, count);
+}
+
+/********************************************************
+ Get the IP address list of the Local Master Browsers
+********************************************************/
+BOOL get_lmb_list(struct in_addr **ip_list, int *count)
+{
+ return internal_resolve_name( MSBROWSE, 0x1, ip_list, count);
}
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 0a6bbe87e23..08748ed0aa0 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -22,12 +22,10 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
int num_good_sends = 0;
int num_good_receives = 0;
-static struct opcode_names {
+static const struct opcode_names {
char *nmb_opcode_name;
int opcode;
} nmb_header_opcode_names[] = {
@@ -44,9 +42,9 @@ static struct opcode_names {
/****************************************************************************
* Lookup a nmb opcode name.
****************************************************************************/
-static char *lookup_opcode_name( int opcode )
+static const char *lookup_opcode_name( int opcode )
{
- struct opcode_names *op_namep;
+ const struct opcode_names *op_namep;
int i;
for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
@@ -173,13 +171,14 @@ static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length,
parse a nmb name from "compressed" format to something readable
return the space taken by the name, or 0 if the name is invalid
******************************************************************/
-static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
+static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
{
int m,n=0;
uchar *ubuf = (uchar *)inbuf;
int ret = 0;
BOOL got_pointer=False;
int loop_count=0;
+ int offset = ofs;
if (length - offset < 2)
return(0);
@@ -345,8 +344,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
(*offset) += l;
if (!l || (*offset)+10 > length) {
- free(*recs);
- *recs = NULL;
+ SAFE_FREE(*recs);
return(False);
}
(*recs)[i].rr_type = RSVAL(inbuf,(*offset));
@@ -356,8 +354,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
(*offset) += 10;
if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
(*offset)+(*recs)[i].rdlength > length) {
- free(*recs);
- *recs = NULL;
+ SAFE_FREE(*recs);
return(False);
}
memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
@@ -580,19 +577,10 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
free_and_exit:
- if(copy_nmb->answers) {
- free((char *)copy_nmb->answers);
- copy_nmb->answers = NULL;
- }
- if(copy_nmb->nsrecs) {
- free((char *)copy_nmb->nsrecs);
- copy_nmb->nsrecs = NULL;
- }
- if(copy_nmb->additional) {
- free((char *)copy_nmb->additional);
- copy_nmb->additional = NULL;
- }
- free((char *)pkt_copy);
+ SAFE_FREE(copy_nmb->answers);
+ SAFE_FREE(copy_nmb->nsrecs);
+ SAFE_FREE(copy_nmb->additional);
+ SAFE_FREE(pkt_copy);
DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
return NULL;
@@ -640,18 +628,9 @@ struct packet_struct *copy_packet(struct packet_struct *packet)
******************************************************************/
static void free_nmb_packet(struct nmb_packet *nmb)
{
- if (nmb->answers) {
- free(nmb->answers);
- nmb->answers = NULL;
- }
- if (nmb->nsrecs) {
- free(nmb->nsrecs);
- nmb->nsrecs = NULL;
- }
- if (nmb->additional) {
- free(nmb->additional);
- nmb->additional = NULL;
- }
+ SAFE_FREE(nmb->answers);
+ SAFE_FREE(nmb->nsrecs);
+ SAFE_FREE(nmb->additional);
}
/*******************************************************************
@@ -674,7 +653,7 @@ void free_packet(struct packet_struct *packet)
else if (packet->packet_type == DGRAM_PACKET)
free_dgram_packet(&packet->packet.dgram);
ZERO_STRUCTPN(packet);
- free(packet);
+ SAFE_FREE(packet);
}
/*******************************************************************
@@ -976,7 +955,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
timeout.tv_sec = t/1000;
timeout.tv_usec = 1000*(t%1000);
- if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
+ if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
/* errno should be EBADF or EINVAL. */
DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
return NULL;
@@ -1291,5 +1270,3 @@ int name_len(char *s1)
return(len);
} /* name_len */
-
-
diff --git a/source/libsmb/nterr.c b/source/libsmb/nterr.c
index 17bb825219f..25286156ee3 100644
--- a/source/libsmb/nterr.c
+++ b/source/libsmb/nterr.c
@@ -1,16 +1,37 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
/* NT error codes. please read nterr.h */
#include "includes.h"
-typedef struct
+typedef const struct
{
char *nt_errstr;
- uint32 nt_errcode;
-
+ NTSTATUS nt_errcode;
} nt_err_code_struct;
nt_err_code_struct nt_errs[] =
{
+ { "NT_STATUS_OK", NT_STATUS_OK },
{ "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL },
{ "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED },
{ "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS },
@@ -513,39 +534,48 @@ nt_err_code_struct nt_errs[] =
{ "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
{ "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
- { NULL, 0 }
+ { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES },
+ { NULL, NT_STATUS(0) }
};
/*****************************************************************************
returns an NT error message. not amazingly helpful, but better than a number.
*****************************************************************************/
-BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len)
+char *get_nt_error_msg(NTSTATUS nt_code)
{
- int idx = 0;
+ static pstring msg;
+ int idx = 0;
- slprintf(msg, len-1, "NT code %08x", nt_code);
+ slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code));
- while (nt_errs[idx].nt_errstr != NULL)
- {
- if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == (nt_code & 0xFFFFFF))
- {
- safe_strcpy(msg, nt_errs[idx].nt_errstr, len);
- return True;
+ while (nt_errs[idx].nt_errstr != NULL) {
+ if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
+ NT_STATUS_V(nt_code)) {
+ return nt_errs[idx].nt_errstr;
}
idx++;
}
- return False;
+
+ return msg;
}
/*****************************************************************************
- returns an NT error message. not amazingly helpful, but better than a number.
+ returns an NT_STATUS constant as a string for inclusion in autogen C code
*****************************************************************************/
-char *get_nt_error_msg(uint32 nt_code)
+char *get_nt_error_c_code(NTSTATUS nt_code)
{
- static pstring msg;
+ static pstring out;
+ int idx = 0;
- get_safe_nt_error_msg(nt_code, msg, sizeof(msg));
- return msg;
-}
+ while (nt_errs[idx].nt_errstr != NULL) {
+ if (NT_STATUS_V(nt_errs[idx].nt_errcode) ==
+ NT_STATUS_V(nt_code)) {
+ return nt_errs[idx].nt_errstr;
+ }
+ idx++;
+ }
+ slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code));
+ return out;
+}
diff --git a/source/libsmb/pwd_cache.c b/source/libsmb/pwd_cache.c
index 420b49ed2e7..45fb00e6e16 100644
--- a/source/libsmb/pwd_cache.c
+++ b/source/libsmb/pwd_cache.c
@@ -21,12 +21,10 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
/****************************************************************************
-initialises a password structure
+ Initialises a password structure.
****************************************************************************/
+
void pwd_init(struct pwd_info *pwd)
{
memset((char *)pwd->password , '\0', sizeof(pwd->password ));
@@ -41,59 +39,51 @@ void pwd_init(struct pwd_info *pwd)
}
/****************************************************************************
-returns NULL password flag
+ Returns NULL password flag.
****************************************************************************/
+
BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
{
return pwd->null_pwd;
}
-
/****************************************************************************
-compares two passwords. hmm, not as trivial as expected. hmm.
+ Compares two passwords. hmm, not as trivial as expected. hmm.
****************************************************************************/
+
BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
{
- if (pwd1->cleartext && pwd2->cleartext)
- {
+ if (pwd1->cleartext && pwd2->cleartext) {
if (strequal(pwd1->password, pwd2->password))
- {
return True;
- }
}
if (pwd1->null_pwd && pwd2->null_pwd)
- {
return True;
- }
if (!pwd1->null_pwd && !pwd2->null_pwd &&
- !pwd1->cleartext && !pwd2->cleartext)
- {
+ !pwd1->cleartext && !pwd2->cleartext) {
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: nt#\n"));
dump_data(100, pwd1->smb_nt_pwd, 16);
dump_data(100, pwd2->smb_nt_pwd, 16);
#endif
if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
- {
return True;
- }
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: lm#\n"));
dump_data(100, pwd1->smb_lm_pwd, 16);
dump_data(100, pwd2->smb_lm_pwd, 16);
#endif
if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
- {
return True;
- }
}
return False;
}
/****************************************************************************
-reads a password
+ Reads a password.
****************************************************************************/
+
void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
{
/* grab a password */
@@ -112,24 +102,19 @@ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
*/
#if 0
if (user_pass == NULL || user_pass[0] == 0)
- {
pwd_set_nullpwd(pwd);
- }
else if (do_encrypt)
#endif
if (do_encrypt)
- {
pwd_make_lm_nt_16(pwd, user_pass);
- }
else
- {
pwd_set_cleartext(pwd, user_pass);
- }
}
/****************************************************************************
- stores a cleartext password
- ****************************************************************************/
+ Stores a cleartext password.
+****************************************************************************/
+
void pwd_set_nullpwd(struct pwd_info *pwd)
{
pwd_init(pwd);
@@ -140,8 +125,9 @@ void pwd_set_nullpwd(struct pwd_info *pwd)
}
/****************************************************************************
- stores a cleartext password
+ Stores a cleartext password.
****************************************************************************/
+
void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
{
pwd_init(pwd);
@@ -153,45 +139,36 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
}
/****************************************************************************
- gets a cleartext password
- ****************************************************************************/
+ Gets a cleartext password.
+****************************************************************************/
+
void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
{
- if (pwd->cleartext)
- {
+ if (pwd->cleartext) {
fstrcpy(clr, pwd->password);
dos_to_unix(clr, True);
- }
- else
- {
+ } else {
clr[0] = 0;
}
}
/****************************************************************************
- stores lm and nt hashed passwords
- ****************************************************************************/
+ Stores lm and nt hashed passwords.
+****************************************************************************/
+
void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
{
pwd_init(pwd);
if (lm_pwd)
- {
memcpy(pwd->smb_lm_pwd, lm_pwd, 16);
- }
else
- {
memset((char *)pwd->smb_lm_pwd, '\0', 16);
- }
if (nt_pwd)
- {
memcpy(pwd->smb_nt_pwd, nt_pwd, 16);
- }
else
- {
memset((char *)pwd->smb_nt_pwd, '\0', 16);
- }
pwd->null_pwd = False;
pwd->cleartext = False;
@@ -199,23 +176,21 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
}
/****************************************************************************
- gets lm and nt hashed passwords
- ****************************************************************************/
+ Gets lm and nt hashed passwords.
+****************************************************************************/
+
void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
{
if (lm_pwd != NULL)
- {
memcpy(lm_pwd, pwd->smb_lm_pwd, 16);
- }
if (nt_pwd != NULL)
- {
memcpy(nt_pwd, pwd->smb_nt_pwd, 16);
- }
}
/****************************************************************************
- makes lm and nt hashed passwords
- ****************************************************************************/
+ Makes lm and nt hashed passwords.
+****************************************************************************/
+
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
{
pstring dos_passwd;
@@ -232,8 +207,9 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
}
/****************************************************************************
- makes lm and nt OWF crypts
- ****************************************************************************/
+ Makes lm and nt OWF crypts.
+****************************************************************************/
+
void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
{
@@ -264,16 +240,13 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
}
/****************************************************************************
- gets lm and nt crypts
- ****************************************************************************/
+ Gets lm and nt crypts.
+****************************************************************************/
+
void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
{
if (lm_owf != NULL)
- {
memcpy(lm_owf, pwd->smb_lm_owf, 24);
- }
if (nt_owf != NULL)
- {
memcpy(nt_owf, pwd->smb_nt_owf, 24);
- }
}
diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c
index 7e8a9a5b89e..866fc0c7e0b 100644
--- a/source/libsmb/smbdes.c
+++ b/source/libsmb/smbdes.c
@@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw)
permute(out, rl, perm6, 64);
}
-static void str_to_key(unsigned char *str,unsigned char *key)
+static void str_to_key(const unsigned char *str,unsigned char *key)
{
int i;
@@ -277,7 +277,7 @@ static void str_to_key(unsigned char *str,unsigned char *key)
}
-static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
+static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
{
int i;
char outb[64];
@@ -305,33 +305,33 @@ static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, i
}
}
-void E_P16(unsigned char *p14,unsigned char *p16)
+void E_P16(const unsigned char *p14,unsigned char *p16)
{
unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
smbhash(p16, sp8, p14, 1);
smbhash(p16+8, sp8, p14+7, 1);
}
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
+void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24)
{
smbhash(p24, c8, p21, 1);
smbhash(p24+8, c8, p21+7, 1);
smbhash(p24+16, c8, p21+14, 1);
}
-void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
+void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out)
{
smbhash(out, in, p14, 0);
smbhash(out+8, in+8, p14+7, 0);
}
-void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
+void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out)
{
smbhash(out, in, p14, 1);
smbhash(out+8, in+8, p14+7, 1);
}
-void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
+void cred_hash1(unsigned char *out, const unsigned char *in,unsigned char *key)
{
unsigned char buf[8];
@@ -339,7 +339,7 @@ void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
smbhash(out, buf, key+9, 1);
}
-void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
+void cred_hash2(unsigned char *out, const unsigned char *in,unsigned char *key)
{
unsigned char buf[8];
static unsigned char key2[8];
@@ -358,7 +358,7 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for
smbhash(out + 8, in + 8, key2, forw);
}
-void SamOEMhash( unsigned char *data, unsigned char *key, int val)
+void SamOEMhash( unsigned char *data, const unsigned char *key, int val)
{
unsigned char s_box[256];
unsigned char index_i = 0;
@@ -397,3 +397,20 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
data[ind] = data[ind] ^ s_box[t];
}
}
+
+/* Decode a sam password hash into a password. The password hash is the
+ same method used to store passwords in the NT registry. The DES key
+ used is based on the RID of the user. */
+
+void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw)
+{
+ uchar s[14];
+
+ s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF);
+ s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF);
+ s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF);
+ s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF);
+
+ smbhash(out, in, s, forw);
+ smbhash(out+8, in+8, s+7, forw);
+}
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 872cc288769..1de2ca53084 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#include "byteorder.h"
/*
diff --git a/source/libsmb/smberr.c b/source/libsmb/smberr.c
index 9648786ea54..3ef4eaf989e 100644
--- a/source/libsmb/smberr.c
+++ b/source/libsmb/smberr.c
@@ -22,12 +22,21 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* error code stuff - put together by Merik Karman
merik@blackadder.dsh.oz.au */
-typedef struct
+
+/* There is a big list of error codes and their meanings at:
+
+ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/errlist_7oz7.asp
+
+ and if you don't like MSDN try:
+
+ http://www.siris.gr/computers/library/error.htm
+
+*/
+
+typedef const struct
{
char *name;
int code;
@@ -42,14 +51,14 @@ err_code_struct dos_msgs[] = {
{"ERRnofids",ERRnofids,"No file descriptors available"},
{"ERRnoaccess",ERRnoaccess,"Access denied."},
{"ERRbadfid",ERRbadfid,"Invalid file handle."},
- {"ERRbadmcb",7,"Memory control blocks destroyed."},
+ {"ERRbadmcb",ERRbadmcb,"Memory control blocks destroyed."},
{"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."},
{"ERRbadmem",ERRbadmem,"Invalid memory block address."},
{"ERRbadenv",ERRbadenv,"Invalid environment."},
{"ERRbadformat",11,"Invalid format."},
{"ERRbadaccess",ERRbadaccess,"Invalid open mode."},
{"ERRbaddata",ERRbaddata,"Invalid data."},
- {"ERR",ERRres,"reserved."},
+ {"ERRres",ERRres,"reserved."},
{"ERRbaddrive",ERRbaddrive,"Invalid drive specified."},
{"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."},
{"ERRdiffdevice",ERRdiffdevice,"Not same device."},
@@ -65,7 +74,10 @@ err_code_struct dos_msgs[] = {
{"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."},
{"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."},
{"ERRmoredata",ERRmoredata,"There is more data to be returned."},
- {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
+ {"ERRinvgroup",ERRinvgroup,"Invalid workgroup (try the -W option)"},
+ {"ERRlogonfailure",ERRlogonfailure,"Logon failure"},
+ {"ERRdiskfull",ERRdiskfull,"Disk full"},
+ {"ERRgeneral",ERRgeneral, "General failure"},
{NULL,-1,NULL}};
/* Server Error Messages */
@@ -127,7 +139,7 @@ err_code_struct hard_msgs[] = {
{NULL,-1,NULL}};
-struct
+const struct
{
int code;
char *class;
@@ -146,39 +158,111 @@ struct
/****************************************************************************
-return a SMB error string from a SMB buffer
+return a SMB error name from a class and code
+****************************************************************************/
+char *smb_dos_err_name(uint8 class, uint16 num)
+{
+ static pstring ret;
+ int i,j;
+
+ for (i=0;err_classes[i].class;i++)
+ if (err_classes[i].code == class) {
+ if (err_classes[i].err_msgs) {
+ err_code_struct *err = err_classes[i].err_msgs;
+ for (j=0;err[j].name;j++)
+ if (num == err[j].code) {
+ return err[j].name;
+ }
+ }
+ slprintf(ret, sizeof(ret) - 1, "%d",num);
+ return ret;
+ }
+
+ slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",class,num);
+ return(ret);
+}
+
+/* Return a string for a DOS error */
+
+char *get_dos_error_msg(WERROR result)
+{
+ uint16 errnum;
+
+ errnum = W_ERROR_V(result);
+
+ return smb_dos_err_name(ERRDOS, errnum);
+}
+
+/****************************************************************************
+return a SMB error class name as a string.
+****************************************************************************/
+char *smb_dos_err_class(uint8 class)
+{
+ static pstring ret;
+ int i;
+
+ for (i=0;err_classes[i].class;i++) {
+ if (err_classes[i].code == class) {
+ return err_classes[i].class;
+ }
+ }
+
+ slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",class);
+ return(ret);
+}
+
+/****************************************************************************
+return a SMB string from an SMB buffer
****************************************************************************/
-char *smb_errstr(char *inbuf)
+char *smb_dos_errstr(char *inbuf)
{
- static pstring ret;
- int class = CVAL(inbuf,smb_rcls);
- int num = SVAL(inbuf,smb_err);
- int i,j;
-
- for (i=0;err_classes[i].class;i++)
- if (err_classes[i].code == class)
- {
- if (err_classes[i].err_msgs)
- {
- err_code_struct *err = err_classes[i].err_msgs;
- for (j=0;err[j].name;j++)
- if (num == err[j].code)
- {
- if (DEBUGLEVEL > 0)
- slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",
- err_classes[i].class,
- err[j].name,err[j].message);
- else
- slprintf(ret, sizeof(ret) - 1, "%s - %s",
- err_classes[i].class,err[j].name);
- return ret;
+ static pstring ret;
+ int class = CVAL(inbuf,smb_rcls);
+ int num = SVAL(inbuf,smb_err);
+ int i,j;
+
+ for (i=0;err_classes[i].class;i++)
+ if (err_classes[i].code == class) {
+ if (err_classes[i].err_msgs) {
+ err_code_struct *err = err_classes[i].err_msgs;
+ for (j=0;err[j].name;j++)
+ if (num == err[j].code) {
+ if (DEBUGLEVEL > 0)
+ slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",
+ err_classes[i].class,
+ err[j].name,err[j].message);
+ else
+ slprintf(ret, sizeof(ret) - 1, "%s - %s",
+ err_classes[i].class,err[j].name);
+ return ret;
+ }
+ }
+
+ slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
+ return ret;
}
- }
-
- slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
- return ret;
- }
-
- slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
- return(ret);
+
+ slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
+ return(ret);
+}
+
+
+/*****************************************************************************
+ returns an WERROR error message.
+ *****************************************************************************/
+char *werror_str(WERROR status)
+{
+ static fstring msg;
+ slprintf(msg, sizeof(msg), "WIN32 code 0x%08x", W_ERROR_V(status));
+ return msg;
+}
+
+
+/*****************************************************************************
+map a unix errno to a win32 error
+ *****************************************************************************/
+WERROR map_werror_from_unix(int error)
+{
+ NTSTATUS status = map_nt_error_from_unix(error);
+ return ntstatus_to_werror(status);
}
diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c
index 8f115623a1c..6a54250506d 100644
--- a/source/libsmb/unexpected.c
+++ b/source/libsmb/unexpected.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static TDB_CONTEXT *tdbd = NULL;
/* the key type used in the unexpeceted packet database */
@@ -149,9 +147,9 @@ check for a particular packet in the unexpected packet queue
struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
char *mailslot_name)
{
- TDB_CONTEXT *tdb2;
+ TDB_CONTEXT *tdb2 = NULL;
- tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
+ tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
if (!tdb2) return NULL;
matched_packet = NULL;
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 7f91f664102..cbf98c46a5e 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -28,7 +28,7 @@
#include "includes.h"
-extern int DEBUGLEVEL;
+#define ZERO_ZERO 0
/* This contains elements that differentiate locks. The smbpid is a
client supplied pid, and is essentially the locking context for
@@ -116,6 +116,32 @@ static BOOL brl_conflict(struct lock_struct *lck1,
return True;
}
+#if ZERO_ZERO
+static BOOL brl_conflict1(struct lock_struct *lck1,
+ struct lock_struct *lck2)
+{
+ if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) {
+ return False;
+ }
+
+ if (brl_same_context(&lck1->context, &lck2->context) &&
+ lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) {
+ return False;
+ }
+
+ if (lck2->start == 0 && lck2->size == 0 && lck1->size != 0) {
+ return True;
+ }
+
+ if (lck1->start >= (lck2->start + lck2->size) ||
+ lck2->start >= (lck1->start + lck1->size)) {
+ return False;
+ }
+
+ return True;
+}
+#endif
+
/****************************************************************************
Check to see if this lock conflicts, but ignore our own locks on the
same fnum only.
@@ -201,7 +227,7 @@ void brl_init(int read_only)
if (tdb)
return;
- tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
+ tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
if (!tdb) {
DEBUG(0,("Failed to open byte range locking database\n"));
@@ -231,28 +257,44 @@ void brl_shutdown(int read_only)
tdb_close(tdb);
}
+#if ZERO_ZERO
+/****************************************************************************
+compare two locks for sorting
+****************************************************************************/
+static int lock_compare(struct lock_struct *lck1,
+ struct lock_struct *lck2)
+{
+ if (lck1->start != lck2->start) return (lck1->start - lck2->start);
+ if (lck2->size != lck1->size) {
+ return ((int)lck1->size - (int)lck2->size);
+ }
+ return 0;
+}
+#endif
+
/****************************************************************************
Lock a range of bytes.
****************************************************************************/
-BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
- br_off start, br_off size,
- enum brl_type lock_type)
+NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
+ uint16 smbpid, pid_t pid, uint16 tid,
+ br_off start, br_off size,
+ enum brl_type lock_type)
{
TDB_DATA kbuf, dbuf;
int count, i;
struct lock_struct lock, *locks;
char *tp;
+ NTSTATUS status = NT_STATUS_OK;
kbuf = locking_key(dev,ino);
dbuf.dptr = NULL;
-#if 0
+#if !ZERO_ZERO
if (start == 0 && size == 0) {
- tdb_delete(tdb, kbuf);
- return True;
+ DEBUG(0,("client sent 0/0 lock - please report this\n"));
+ return NT_STATUS_INVALID_PARAMETER;
}
#endif
@@ -273,35 +315,44 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
count = dbuf.dsize / sizeof(*locks);
for (i=0; i<count; i++) {
if (brl_conflict(&locks[i], &lock)) {
+ status = NT_STATUS_LOCK_NOT_GRANTED;
goto fail;
}
+#if ZERO_ZERO
+ if (lock.start == 0 && lock.size == 0 &&
+ locks[i].size == 0) {
+ break;
+ }
+#endif
}
}
-#if 0
- if (start == 0 && size == 0) {
- if (dbuf.dptr) free(dbuf.dptr);
- tdb_chainunlock(tdb, kbuf);
- return True;
- }
-#endif
-
/* no conflicts - add it to the list of locks */
tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks));
- if (!tp) goto fail;
- else dbuf.dptr = tp;
+ if (!tp) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ } else {
+ dbuf.dptr = tp;
+ }
memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock));
dbuf.dsize += sizeof(lock);
+
+#if ZERO_ZERO
+ /* sort the lock list */
+ qsort(dbuf.dptr, dbuf.dsize/sizeof(lock), sizeof(lock), lock_compare);
+#endif
+
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
- return True;
+ return NT_STATUS_OK;
fail:
- if (dbuf.dptr) free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
- return False;
+ return status;
}
/****************************************************************************
@@ -337,6 +388,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
+#if ZERO_ZERO
for (i=0; i<count; i++) {
struct lock_struct *lock = &locks[i];
@@ -357,11 +409,12 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return True;
}
}
+#endif
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
@@ -384,7 +437,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return True;
}
@@ -393,7 +446,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
/* we didn't find it */
fail:
- if (dbuf.dptr) free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return False;
}
@@ -446,12 +499,12 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
}
/* no conflicts - we could have added it */
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return True;
fail:
- if (dbuf.dptr) free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
return False;
}
@@ -504,7 +557,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
/* we didn't find it */
fail:
- if (dbuf.dptr) free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index b2fb6812652..9822c587f1c 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -36,7 +36,6 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
uint16 global_smbpid;
/* the locking database handle */
@@ -99,14 +98,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
Utility function called by locking requests.
****************************************************************************/
-BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type,
- int *eclass,uint32 *ecode)
+NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
- BOOL ok = False;
+ NTSTATUS status;
if (!lp_locking(SNUM(conn)))
- return(True);
+ return NT_STATUS_OK;
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
@@ -115,12 +113,12 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
- ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
- lock_pid, sys_getpid(), conn->cnum,
- offset, count,
- lock_type);
+ status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
+ lock_pid, sys_getpid(), conn->cnum,
+ offset, count,
+ lock_type);
- if (ok && lp_posix_locking(SNUM(conn))) {
+ if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
/*
* Try and get a POSIX lock on this range.
@@ -128,9 +126,8 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
* overlapping on a different fd. JRA.
*/
- ok = set_posix_lock(fsp, offset, count, lock_type);
-
- if (!ok) {
+ if (!set_posix_lock(fsp, offset, count, lock_type)) {
+ status = NT_STATUS_LOCK_NOT_GRANTED;
/*
* We failed to map - we must now remove the brl
* lock entry.
@@ -142,31 +139,23 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
}
}
- if (!ok) {
- *eclass = ERRDOS;
- *ecode = ERRlock;
- return False;
- }
- return True; /* Got lock */
+ return status;
}
/****************************************************************************
Utility function called by unlocking requests.
****************************************************************************/
-BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,
- int *eclass,uint32 *ecode)
+NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
+ SMB_BIG_UINT count,SMB_BIG_UINT offset)
{
BOOL ok = False;
if (!lp_locking(SNUM(conn)))
- return(True);
+ return NT_STATUS_OK;
if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
- *eclass = ERRDOS;
- *ecode = ERRbadfid;
- return False;
+ return NT_STATUS_INVALID_HANDLE;
}
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
@@ -183,17 +172,15 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
if (!ok) {
DEBUG(10,("do_unlock: returning ERRlock.\n" ));
- *eclass = ERRDOS;
- *ecode = ERRnotlocked;
- return False;
+ return NT_STATUS_LOCK_NOT_GRANTED;
}
if (!lp_posix_locking(SNUM(conn)))
- return True;
+ return NT_STATUS_OK;
(void)release_posix_lock(fsp, offset, count);
- return True; /* Did unlock */
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -223,6 +210,9 @@ void locking_close_file(files_struct *fsp)
}
}
+#if 0
+/* Not currently used. JRA */
+
/****************************************************************************
Delete a record if it is for a dead process, if check_self is true, then
delete any records belonging to this pid also (there shouldn't be any).
@@ -279,6 +269,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
tdb_chainunlock(tdb, kbuf);
return ret;
}
+#endif
/****************************************************************************
Initialise the locking functions.
@@ -288,8 +279,6 @@ static int open_read_only;
BOOL locking_init(int read_only)
{
- BOOL check_self = False;
-
brl_init(read_only);
if (tdb)
@@ -308,10 +297,6 @@ BOOL locking_init(int read_only)
if (!posix_locking_init(read_only))
return False;
- /* delete any dead locks */
- if (!read_only)
- tdb_traverse(tdb, delete_fn, &check_self);
-
open_read_only = read_only;
return True;
@@ -323,16 +308,10 @@ BOOL locking_init(int read_only)
BOOL locking_end(void)
{
- BOOL check_self = True;
brl_shutdown(open_read_only);
if (tdb) {
- /* delete any dead locks */
-
- if (!open_read_only)
- tdb_traverse(tdb, delete_fn, &check_self);
-
if (tdb_close(tdb) != 0)
return False;
}
@@ -362,10 +341,6 @@ static TDB_DATA locking_key_fsp(files_struct *fsp)
return locking_key(fsp->dev, fsp->inode);
}
-#ifndef LOCK_SHARE_ENTRY_SPIN_COUNT
-#define LOCK_SHARE_ENTRY_SPIN_COUNT 100
-#endif
-
/*******************************************************************
Lock a hash bucket entry.
******************************************************************/
@@ -405,33 +380,110 @@ void unlock_share_entry_fsp(files_struct *fsp)
}
/*******************************************************************
+ Print out a share mode.
+********************************************************************/
+
+static char *share_mode_str(int num, share_mode_entry *e)
+{
+ static pstring share_str;
+
+ slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
+pid = %u, share_mode = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
+ num, e->pid, e->share_mode, e->op_port, e->op_type, e->share_file_id,
+ (unsigned int)e->dev, (double)e->inode );
+
+ return share_str;
+}
+
+/*******************************************************************
+ Print out a share mode table.
+********************************************************************/
+
+static void print_share_mode_table(struct locking_data *data)
+{
+ int num_share_modes = data->u.num_share_mode_entries;
+ share_mode_entry *shares = (share_mode_entry *)(data + 1);
+ int i;
+
+ for (i = 0; i < num_share_modes; i++) {
+ share_mode_entry *entry_p = &shares[i];
+ DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) ));
+ }
+}
+
+/*******************************************************************
Get all share mode entries for a dev/inode pair.
********************************************************************/
int get_share_modes(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry **shares)
+ share_mode_entry **pp_shares)
{
TDB_DATA dbuf;
struct locking_data *data;
- int ret;
+ int num_share_modes;
+ share_mode_entry *shares = NULL;
- *shares = NULL;
+ *pp_shares = NULL;
dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return 0;
data = (struct locking_data *)dbuf.dptr;
- ret = data->u.num_share_mode_entries;
- if(ret)
- *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares));
- free(dbuf.dptr);
+ num_share_modes = data->u.num_share_mode_entries;
+ if(num_share_modes) {
+ int i;
+ int del_count = 0;
- if (! *shares)
- return 0;
+ shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data),
+ num_share_modes * sizeof(share_mode_entry));
- return ret;
+ if (!shares) {
+ SAFE_FREE(dbuf.dptr);
+ return 0;
+ }
+
+ /*
+ * Ensure that each entry has a real process attached.
+ */
+
+ for (i = 0; i < num_share_modes; ) {
+ share_mode_entry *entry_p = &shares[i];
+ if (process_exists(entry_p->pid)) {
+ DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) ));
+ i++;
+ } else {
+ DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) ));
+ memcpy( &shares[i], &shares[i+1],
+ sizeof(share_mode_entry) * (num_share_modes - i - 1));
+ num_share_modes--;
+ del_count++;
+ }
+ }
+
+ /* Did we delete any ? If so, re-store in tdb. */
+ if (del_count) {
+ data->u.num_share_mode_entries = num_share_modes;
+
+ if (num_share_modes)
+ memcpy(dbuf.dptr + sizeof(*data), shares,
+ num_share_modes * sizeof(share_mode_entry));
+
+ /* The record has shrunk a bit */
+ dbuf.dsize -= del_count * sizeof(share_mode_entry);
+
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) {
+ SAFE_FREE(shares);
+ SAFE_FREE(dbuf.dptr);
+ return 0;
+ }
+ }
+ }
+
+ SAFE_FREE(dbuf.dptr);
+ *pp_shares = shares;
+ return num_share_modes;
}
/*******************************************************************
@@ -449,19 +501,36 @@ static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_t
e->op_port = port;
e->op_type = op_type;
memcpy(x, &fsp->open_time, sizeof(struct timeval));
+ e->share_file_id = fsp->file_id;
+ e->dev = fsp->dev;
+ e->inode = fsp->inode;
}
/*******************************************************************
Check if two share mode entries are identical, ignoring oplock
- and port info and also ignoring the delete on close setting.
+ and port info.
********************************************************************/
BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
{
+#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
+ if (e1->pid == e2->pid &&
+ e1->share_file_id == e2->share_file_id &&
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
+ DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
+ (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
+ (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
+ smb_panic("PANIC: share_modes_identical logic error.\n");
+ }
+#endif
+
return (e1->pid == e2->pid &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
- e1->time.tv_sec == e2->time.tv_sec &&
- e1->time.tv_usec == e2->time.tv_usec );
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ e1->share_file_id == e2->share_file_id );
}
/*******************************************************************
@@ -496,10 +565,12 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
* from the record.
*/
- DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->u.num_share_mode_entries ));
+ DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries ));
for (i=0;i<data->u.num_share_mode_entries;) {
if (share_modes_identical(&shares[i], entry)) {
+ DEBUG(10,("del_share_entry: deleted %s\n",
+ share_mode_str(i, &shares[i]) ));
if (ppse)
*ppse = memdup(&shares[i], sizeof(*shares));
data->u.num_share_mode_entries--;
@@ -507,7 +578,7 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
del_count++;
- DEBUG(10,("del_share_mode: deleting entry %d\n", i ));
+ DEBUG(10,("del_share_entry: deleting entry %d\n", i ));
} else {
i++;
@@ -529,7 +600,9 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
count = -1;
}
}
- free(dbuf.dptr);
+ DEBUG(10,("del_share_entry: Remaining table.\n"));
+ print_share_mode_table((struct locking_data *)dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return count;
}
@@ -578,13 +651,20 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
return False;
data = (struct locking_data *)p;
data->u.num_share_mode_entries = 1;
+
+ DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
+ fsp->fsp_name ));
+
pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname);
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
dbuf.dptr = p;
dbuf.dsize = size;
if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
- free(p);
+
+ print_share_mode_table((struct locking_data *)p);
+
+ SAFE_FREE(p);
return ret;
}
@@ -592,6 +672,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
data = (struct locking_data *)dbuf.dptr;
data->u.num_share_mode_entries++;
+
+ DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
+ fsp->fsp_name, data->u.num_share_mode_entries ));
+
size = dbuf.dsize + sizeof(share_mode_entry);
p = malloc(size);
if (!p)
@@ -600,12 +684,13 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
dbuf.dsize - sizeof(*data));
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize = size;
if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
- free(p);
+ print_share_mode_table((struct locking_data *)p);
+ SAFE_FREE(p);
return ret;
}
@@ -650,7 +735,7 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
}
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return need_store;
}
@@ -740,12 +825,12 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
/* store it back */
if (data->u.num_share_mode_entries) {
if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) {
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return False;
}
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return True;
}
diff --git a/source/locking/posix.c b/source/locking/posix.c
index eb5e4b6460c..8b3538d8ca1 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -24,7 +24,6 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
/*
* The POSIX locking database handle.
@@ -107,8 +106,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(int));
if (!tp) {
DEBUG(0,("add_fd_to_close_entry: Realloc fail !\n"));
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return False;
} else
dbuf.dptr = tp;
@@ -120,7 +118,7 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
DEBUG(0,("add_fd_to_close_entry: tdb_store fail !\n"));
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return True;
}
@@ -240,17 +238,16 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
*/
if (!add_fd_to_close_entry(fsp)) {
- free((char *)entries);
+ SAFE_FREE(entries);
return False;
}
- free((char *)entries);
+ SAFE_FREE(entries);
fsp->fd = -1;
return 0;
}
- if(entries)
- free((char *)entries);
+ SAFE_FREE(entries);
/*
* No outstanding POSIX locks. Get the pending close fd's
@@ -276,8 +273,7 @@ int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
delete_close_entries(fsp);
}
- if (fd_array)
- free((char *)fd_array);
+ SAFE_FREE(fd_array);
/*
* Finally close the fd associated with this fsp.
@@ -338,13 +334,12 @@ static BOOL delete_posix_lock_entry_by_index(files_struct *fsp, size_t entry)
tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE);
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return True;
fail:
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return False;
}
@@ -391,7 +386,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
goto fail;
}
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
DEBUG(10,("add_posix_lock: File %s: type = %s: start=%.0f size=%.0f: dev=%.0f inode=%.0f\n",
fsp->fsp_name, posix_lock_type_name(lock_type), (double)start, (double)size,
@@ -400,8 +395,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
return True;
fail:
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return False;
}
@@ -499,14 +493,12 @@ static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T
posix_lock_type_name(pl->lock_type), (double)pl->start, (double)pl->size,
(unsigned int)num_overlapping_records ));
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return num_overlapping_records;
fail:
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return -1;
}
@@ -955,8 +947,7 @@ lock: start = %.0f, size = %.0f\n", (double)l_curr->start, (double)l_curr->size,
} /* end for ( l_curr = lhead; l_curr;) */
} /* end for (i=0; i<num_locks && ul_head; i++) */
- if (dbuf.dptr)
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return lhead;
}
@@ -1266,7 +1257,7 @@ void posix_locking_close_file(files_struct *fsp)
/* All locks are ours. */
DEBUG(10,("posix_locking_close_file: file %s has %u outstanding locks, but all on one fd.\n",
fsp->fsp_name, (unsigned int)count ));
- free((char *)entries);
+ SAFE_FREE(entries);
delete_posix_lock_entries(fsp);
return;
}
@@ -1281,7 +1272,7 @@ void posix_locking_close_file(files_struct *fsp)
if (pl->fd == fsp->fd)
release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size );
}
- free((char *)entries);
+ SAFE_FREE(entries);
}
/*******************************************************************
diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c
index cd93e5f6bc8..729e8d48c6d 100644
--- a/source/msdfs/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -22,7 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
extern uint32 global_client_caps;
@@ -616,14 +615,14 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
{
reply_size = setup_ver2_dfs_referral(pathname, ppdata, &junction,
consumedcnt, self_referral);
- free(junction.referral_list);
+ SAFE_FREE(junction.referral_list);
break;
}
case 3:
{
reply_size = setup_ver3_dfs_referral(pathname, ppdata, &junction,
consumedcnt, self_referral);
- free(junction.referral_list);
+ SAFE_FREE(junction.referral_list);
break;
}
default:
diff --git a/source/nmbd/asyncdns.c b/source/nmbd/asyncdns.c
index 1fe04a39e37..5ae2eb202da 100644
--- a/source/nmbd/asyncdns.c
+++ b/source/nmbd/asyncdns.c
@@ -20,8 +20,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/***************************************************************************
Add a DNS result to the name cache.
****************************************************************************/
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 3e7b2171ec0..fa4e1c4cfd9 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -27,9 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-extern pstring debugf;
pstring servicesf = CONFIGFILE;
int ClientNMB = -1;
@@ -56,8 +53,9 @@ time_t StartupTime = 0;
extern struct in_addr ipzero;
/**************************************************************************** **
- catch a sigterm
+ Catch a sigterm.
**************************************************************************** */
+
static void sig_term(int sig)
{
BlockSignals(True,SIGTERM);
@@ -81,8 +79,9 @@ static void sig_term(int sig)
} /* sig_term */
/**************************************************************************** **
- catch a sighup
+ Catch a sighup.
**************************************************************************** */
+
static VOLATILE sig_atomic_t reload_after_sighup = False;
static void sig_hup(int sig)
@@ -101,16 +100,16 @@ static void sig_hup(int sig)
} /* sig_hup */
-
#if DUMP_CORE
/**************************************************************************** **
- prepare to dump a core file - carefully!
+ Prepare to dump a core file - carefully!
**************************************************************************** */
+
static BOOL dump_core(void)
{
char *p;
pstring dname;
- pstrcpy( dname, debugf );
+ pstrcpy( dname, lp_logfile() );
if ((p=strrchr(dname,'/')))
*p=0;
pstrcat( dname, "/corefiles" );
@@ -141,10 +140,10 @@ static BOOL dump_core(void)
} /* dump_core */
#endif
-
/**************************************************************************** **
- possibly continue after a fault
+ Possibly continue after a fault.
**************************************************************************** */
+
static void fault_continue(void)
{
#if DUMP_CORE
@@ -153,8 +152,9 @@ static void fault_continue(void)
} /* fault_continue */
/**************************************************************************** **
- expire old names from the namelist and server list
+ Expire old names from the namelist and server list.
**************************************************************************** */
+
static void expire_names_and_servers(time_t t)
{
static time_t lastrun = 0;
@@ -182,10 +182,10 @@ static void expire_names_and_servers(time_t t)
expire_workgroups_and_servers(t);
} /* expire_names_and_servers */
-
/************************************************************************** **
-reload the list of network interfaces
+ Reload the list of network interfaces.
************************************************************************** */
+
static BOOL reload_interfaces(time_t t)
{
static time_t lastt;
@@ -262,11 +262,10 @@ static BOOL reload_interfaces(time_t t)
return False;
}
-
-
/**************************************************************************** **
- reload the services file
+ Reload the services file.
**************************************************************************** */
+
static BOOL reload_nmbd_services(BOOL test)
{
BOOL ret;
@@ -311,6 +310,7 @@ cannot be set in the smb.conf file. nmbd aborting.\n"));
/**************************************************************************** **
The main select loop.
**************************************************************************** */
+
static void process(void)
{
BOOL run_election;
@@ -509,10 +509,10 @@ static void process(void)
}
} /* process */
-
/**************************************************************************** **
- open the socket communication
+ Open the socket communication.
**************************************************************************** */
+
static BOOL open_sockets(BOOL isdaemon, int port)
{
/* The sockets opened here will be used to receive broadcast
@@ -542,10 +542,10 @@ static BOOL open_sockets(BOOL isdaemon, int port)
return( True );
} /* open_sockets */
-
/**************************************************************************** **
- initialise connect, service and file structs
+ Initialise connect, service and file structs.
**************************************************************************** */
+
static BOOL init_structs(void)
{
extern fstring local_machine;
@@ -628,15 +628,17 @@ static BOOL init_structs(void)
} /* init_structs */
/**************************************************************************** **
- usage on the program
+ Usage on the program.
**************************************************************************** */
+
static void usage(char *pname)
{
- printf( "Usage: %s [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
+ printf( "Usage: %s [-DaiohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
printf( " [-n name] [-p port] [-s configuration file]\n" );
- printf( "\t-D Become a daemon\n" );
+ printf( "\t-D Become a daemon (default)\n" );
printf( "\t-a Append to log file (default)\n" );
+ printf( "\t-i Run interactive (not a daemon)\n" );
printf( "\t-o Overwrite log file, don't append\n" );
printf( "\t-h Print usage\n" );
printf( "\t-V Print version\n" );
@@ -651,14 +653,17 @@ static void usage(char *pname)
/**************************************************************************** **
- main program
+ Main program.
**************************************************************************** */
+
int main(int argc,char *argv[])
{
int opt;
extern FILE *dbf;
extern char *optarg;
extern BOOL append_log;
+ BOOL opt_interactive = False;
+ pstring logfile;
append_log = True; /* Default, override with '-o' option. */
@@ -672,8 +677,8 @@ static void usage(char *pname)
TimeInit();
- slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", LOGFILEBASE);
- setup_logging( argv[0], False );
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", LOGFILEBASE);
+ lp_set_logfile(logfile);
charset_initialise();
@@ -710,7 +715,7 @@ static void usage(char *pname)
#endif
while( EOF !=
- (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
+ (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dip:hSH:G:f:" )) )
{
switch (opt)
{
@@ -732,7 +737,8 @@ static void usage(char *pname)
strupper(global_myname);
break;
case 'l':
- slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", optarg);
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", optarg);
+ lp_set_logfile(logfile);
break;
case 'a':
append_log = True;
@@ -740,6 +746,9 @@ static void usage(char *pname)
case 'o':
append_log = False;
break;
+ case 'i':
+ opt_interactive = True;
+ break;
case 'D':
is_daemon = True;
break;
@@ -768,10 +777,11 @@ static void usage(char *pname)
}
}
+ setup_logging( argv[0], opt_interactive );
reopen_logs();
- DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
- DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
+ DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) );
+ DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) );
if ( !reload_nmbd_services(False) )
return(-1);
@@ -806,12 +816,21 @@ static void usage(char *pname)
is_daemon = True;
}
- if (is_daemon)
+ if (is_daemon && !opt_interactive)
{
DEBUG( 2, ( "Becoming a daemon.\n" ) );
become_daemon();
}
+#if HAVE_SETPGID
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (opt_interactive)
+ setpgid( (pid_t)0, (pid_t)0 );
+#endif
+
#ifndef SYNC_DNS
/* Setup the async dns. We do it here so it doesn't have all the other
stuff initialised and thus chewing memory and sockets */
@@ -880,4 +899,3 @@ static void usage(char *pname)
fclose(dbf);
return(0);
} /* main */
-
diff --git a/source/nmbd/nmbd_become_dmb.c b/source/nmbd/nmbd_become_dmb.c
index 76d92c2f3ed..6825643c85a 100644
--- a/source/nmbd/nmbd_become_dmb.c
+++ b/source/nmbd/nmbd_become_dmb.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
diff --git a/source/nmbd/nmbd_become_lmb.c b/source/nmbd/nmbd_become_lmb.c
index 31c67ae7f3f..52955d9bfc0 100644
--- a/source/nmbd/nmbd_become_lmb.c
+++ b/source/nmbd/nmbd_become_lmb.c
@@ -24,7 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c
index 10d22431e91..cc1ce6c2ab5 100644
--- a/source/nmbd/nmbd_browserdb.c
+++ b/source/nmbd/nmbd_browserdb.c
@@ -30,8 +30,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* -------------------------------------------------------------------------- **
* Variables...
*
@@ -56,7 +54,7 @@ ubi_dlNewList( lmb_browserlist );
*/
static void remove_lmb_browser_entry( struct browse_cache_record *browc )
{
- free( (char *)ubi_dlRemThis( lmb_browserlist, browc ) );
+ safe_free( (char *)ubi_dlRemThis( lmb_browserlist, browc ) );
} /* remove_lmb_browser_entry */
/* ************************************************************************** **
diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c
index 23ca0a398f5..d472b6ff284 100644
--- a/source/nmbd/nmbd_browsesync.c
+++ b/source/nmbd/nmbd_browsesync.c
@@ -25,7 +25,6 @@
#include "includes.h"
#include "smb.h"
-extern int DEBUGLEVEL;
extern struct in_addr ipzero;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -129,7 +128,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf;
- CVAL(p,0) = ANN_MasterAnnouncement;
+ SCVAL(p,0,ANN_MasterAnnouncement);
p++;
StrnCpy(p,global_myname,15);
diff --git a/source/nmbd/nmbd_elections.c b/source/nmbd/nmbd_elections.c
index 0fc3ab9a896..ae225184951 100644
--- a/source/nmbd/nmbd_elections.c
+++ b/source/nmbd/nmbd_elections.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -46,10 +44,10 @@ static void send_election_dgram(struct subnet_record *subrec, char *workgroup_na
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf;
- CVAL(p,0) = ANN_Election; /* Election opcode. */
+ SCVAL(p,0,ANN_Election); /* Election opcode. */
p++;
- CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
+ SCVAL(p,0,((criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION));
SIVAL(p,1,criterion);
SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */
p += 13;
diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c
index dd1559c62c3..d9d1894534d 100644
--- a/source/nmbd/nmbd_incomingdgrams.c
+++ b/source/nmbd/nmbd_incomingdgrams.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
extern BOOL found_lm_clients;
diff --git a/source/nmbd/nmbd_incomingrequests.c b/source/nmbd/nmbd_incomingrequests.c
index 82cda38c7f8..dbbb7315787 100644
--- a/source/nmbd/nmbd_incomingrequests.c
+++ b/source/nmbd/nmbd_incomingrequests.c
@@ -28,7 +28,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern fstring global_myworkgroup;
/****************************************************************************
@@ -595,7 +594,7 @@ on the same subnet (%s) as the requestor. Not replying.\n",
if (!success && bcast)
{
if((prdata != rdata) && (prdata != NULL))
- free(prdata);
+ SAFE_FREE(prdata);
goto done; /* Never reply with a negative response to broadcasts. */
}
@@ -608,7 +607,7 @@ on the same subnet (%s) as the requestor. Not replying.\n",
if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
{
if((prdata != rdata) && (prdata != NULL))
- free(prdata);
+ SAFE_FREE(prdata);
goto done;
}
@@ -634,7 +633,7 @@ on the same subnet (%s) as the requestor. Not replying.\n",
reply_data_len); /* data length. */
if((prdata != rdata) && (prdata != NULL))
- free(prdata);
+ SAFE_FREE(prdata);
done:
END_PROFILE(name_query);
}
diff --git a/source/nmbd/nmbd_lmhosts.c b/source/nmbd/nmbd_lmhosts.c
index 158988813b7..8eb198020f7 100644
--- a/source/nmbd/nmbd_lmhosts.c
+++ b/source/nmbd/nmbd_lmhosts.c
@@ -26,8 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
Load a lmhosts file.
****************************************************************************/
diff --git a/source/nmbd/nmbd_logonnames.c b/source/nmbd/nmbd_logonnames.c
index c63de56a34a..4f48b21b7fd 100644
--- a/source/nmbd/nmbd_logonnames.c
+++ b/source/nmbd/nmbd_logonnames.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
diff --git a/source/nmbd/nmbd_mynames.c b/source/nmbd/nmbd_mynames.c
index 7672417786a..b1b3f48b62a 100644
--- a/source/nmbd/nmbd_mynames.c
+++ b/source/nmbd/nmbd_mynames.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern char **my_netbios_names;
extern fstring global_myworkgroup;
@@ -100,53 +98,50 @@ BOOL register_my_workgroup_and_names(void)
register_my_workgroup_one_subnet(subrec);
}
- /* If we are not a WINS client, we still need to add the magic Samba
+ /* We still need to add the magic Samba
names and the netbios names to the unicast subnet directly. This is
to allow unicast node status requests and queries to still work
in a broadcast only environment. */
- if(we_are_a_wins_client() == False)
- {
- add_samba_names_to_subnet(unicast_subnet);
+ add_samba_names_to_subnet(unicast_subnet);
- for (i=0; my_netbios_names[i]; i++)
+ for (i=0; my_netbios_names[i]; i++)
+ {
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
{
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
+ /*
+ * Ensure all the IP addresses are added if we are multihomed.
+ */
+ struct nmb_name nmbname;
- make_nmb_name(&nmbname, my_netbios_names[i],0x20);
- insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
+ make_nmb_name(&nmbname, my_netbios_names[i],0x20);
+ insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
- make_nmb_name(&nmbname, my_netbios_names[i],0x3);
- insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
+ make_nmb_name(&nmbname, my_netbios_names[i],0x3);
+ insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
- make_nmb_name(&nmbname, my_netbios_names[i],0x0);
- insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
- }
+ make_nmb_name(&nmbname, my_netbios_names[i],0x0);
+ insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
}
+ }
+ /*
+ * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
+ * also for the same reasons.
+ */
+
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
+ {
/*
- * Add the WORKGROUP<0> and WORKGROUP<1e> group names to the unicast subnet
- * also for the same reasons.
+ * Ensure all the IP addresses are added if we are multihomed.
*/
+ struct nmb_name nmbname;
- for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
- {
- /*
- * Ensure all the IP addresses are added if we are multihomed.
- */
- struct nmb_name nmbname;
-
- make_nmb_name(&nmbname, global_myworkgroup, 0x0);
- insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
+ make_nmb_name(&nmbname, global_myworkgroup, 0x0);
+ insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- make_nmb_name(&nmbname, global_myworkgroup, 0x1e);
- insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- }
+ make_nmb_name(&nmbname, global_myworkgroup, 0x1e);
+ insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
}
/*
diff --git a/source/nmbd/nmbd_namelistdb.c b/source/nmbd/nmbd_namelistdb.c
index 15328af33eb..4e8c251b3ec 100644
--- a/source/nmbd/nmbd_namelistdb.c
+++ b/source/nmbd/nmbd_namelistdb.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern char **my_netbios_names;
uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
@@ -78,9 +76,8 @@ static void update_name_in_namelist( struct subnet_record *subrec,
(void)ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
if( oldrec )
{
- if( oldrec->data.ip )
- free( oldrec->data.ip );
- free( oldrec );
+ SAFE_FREE( oldrec->data.ip );
+ SAFE_FREE( oldrec );
}
} /* update_name_in_namelist */
@@ -93,11 +90,10 @@ void remove_name_from_namelist( struct subnet_record *subrec,
{
(void)ubi_trRemove( subrec->namelist, namerec );
- if(namerec->data.ip != NULL)
- free((char *)namerec->data.ip);
+ SAFE_FREE(namerec->data.ip);
ZERO_STRUCTP(namerec);
- free((char *)namerec);
+ SAFE_FREE(namerec);
subrec->namelist_changed = True;
} /* remove_name_from_namelist */
@@ -206,7 +202,7 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
ZERO_STRUCTP(namerec);
- free( (char *)namerec );
+ SAFE_FREE( namerec );
return NULL;
}
@@ -353,7 +349,7 @@ void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
namerec->data.num_ips * sizeof(struct in_addr) );
new_list[namerec->data.num_ips] = new_ip;
- free((char *)namerec->data.ip);
+ SAFE_FREE(namerec->data.ip);
namerec->data.ip = new_list;
namerec->data.num_ips += 1;
@@ -520,7 +516,7 @@ void add_samba_names_to_subnet( struct subnet_record *subrec )
PERMANENT_NAME, num_ips, iplist);
if(iplist != &subrec->myip)
- free((char *)iplist);
+ SAFE_FREE(iplist);
}
/****************************************************************************
diff --git a/source/nmbd/nmbd_namequery.c b/source/nmbd/nmbd_namequery.c
index b497526475e..1f0895ee37f 100644
--- a/source/nmbd/nmbd_namequery.c
+++ b/source/nmbd/nmbd_namequery.c
@@ -24,7 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern struct in_addr ipzero;
/****************************************************************************
diff --git a/source/nmbd/nmbd_nameregister.c b/source/nmbd/nmbd_nameregister.c
index 6154f06edde..c3361cec60b 100644
--- a/source/nmbd/nmbd_nameregister.c
+++ b/source/nmbd/nmbd_nameregister.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern fstring global_myworkgroup;
/****************************************************************************
@@ -311,12 +309,12 @@ static BOOL multihomed_register_name( struct nmb_name *nmbname, uint16 nb_flags,
DEBUG(0,("multihomed_register_name: Failed to send packet trying to \
register name %s IP %s\n", nmb_namestr(nmbname), inet_ntoa(ip_list[i]) ));
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
return True;
}
}
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
return False;
}
diff --git a/source/nmbd/nmbd_namerelease.c b/source/nmbd/nmbd_namerelease.c
index 0f693c63d02..30a9d165612 100644
--- a/source/nmbd/nmbd_namerelease.c
+++ b/source/nmbd/nmbd_namerelease.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
Deal with a response packet when releasing one of our names.
****************************************************************************/
diff --git a/source/nmbd/nmbd_nodestatus.c b/source/nmbd/nmbd_nodestatus.c
index d28ea1cff4e..eeb532d4109 100644
--- a/source/nmbd/nmbd_nodestatus.c
+++ b/source/nmbd/nmbd_nodestatus.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
Deal with a successful node status response.
****************************************************************************/
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index 00059c1775e..9d4dfbc8078 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -28,8 +28,6 @@ extern int ClientNMB;
extern int ClientDGRAM;
extern int global_nmb_port;
-extern int DEBUGLEVEL;
-
extern int num_response_packets;
extern struct in_addr loopback_ip;
@@ -1758,8 +1756,8 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
*listen_number = (count*2) + 2;
- if (*ppset) free(*ppset);
- if (*psock_array) free(*psock_array);
+ SAFE_FREE(*ppset);
+ SAFE_FREE(*psock_array);
*ppset = pset;
*psock_array = sock_array;
@@ -1820,7 +1818,7 @@ BOOL listen_for_packets(BOOL run_election)
BlockSignals(False, SIGTERM);
- selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
+ selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
/* We can only take signals when we are in the select - block them again here. */
@@ -1851,8 +1849,7 @@ BOOL listen_for_packets(BOOL run_election)
DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
- } else if ((ip_equal(loopback_ip, packet->ip) ||
- ismyip(packet->ip)) && packet->port == global_nmb_port) {
+ } else if (ip_equal(loopback_ip, packet->ip) && packet->port == global_nmb_port) {
DEBUG(7,("discarding own packet from %s:%d\n",
inet_ntoa(packet->ip),packet->port));
free_packet(packet);
@@ -1938,7 +1935,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
set_message(ptr,17,17 + len,True);
memcpy(ptr,tmp,4);
- CVAL(ptr,smb_com) = SMBtrans;
+ SCVAL(ptr,smb_com,SMBtrans);
SSVAL(ptr,smb_vwv1,len);
SSVAL(ptr,smb_vwv11,len);
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index 3699754c885..c9130fe478c 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -26,8 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
diff --git a/source/nmbd/nmbd_responserecordsdb.c b/source/nmbd/nmbd_responserecordsdb.c
index 1b6e1ca16db..b24c85a9d81 100644
--- a/source/nmbd/nmbd_responserecordsdb.c
+++ b/source/nmbd/nmbd_responserecordsdb.c
@@ -26,8 +26,6 @@
extern int ClientNMB;
-extern int DEBUGLEVEL;
-
extern struct in_addr ipzero;
int num_response_packets = 0;
@@ -83,7 +81,7 @@ void remove_response_record(struct subnet_record *subrec,
(*rrec->userdata->free_fn)(rrec->userdata);
} else {
ZERO_STRUCTP(rrec->userdata);
- free((char *)rrec->userdata);
+ SAFE_FREE(rrec->userdata);
}
}
@@ -92,7 +90,7 @@ void remove_response_record(struct subnet_record *subrec,
free_packet(rrec->packet);
ZERO_STRUCTP(rrec);
- free((char *)rrec);
+ SAFE_FREE(rrec);
num_response_packets--; /* count of total number of packets still around */
}
@@ -138,7 +136,7 @@ struct response_record *make_response_record( struct subnet_record *subrec,
{
DEBUG(0,("make_response_queue_record: copy fail for userdata.\n"));
ZERO_STRUCTP(rrec);
- free(rrec);
+ SAFE_FREE(rrec);
return NULL;
}
}
@@ -150,7 +148,7 @@ struct response_record *make_response_record( struct subnet_record *subrec,
{
DEBUG(0,("make_response_queue_record: malloc fail for userdata.\n"));
ZERO_STRUCTP(rrec);
- free(rrec);
+ SAFE_FREE(rrec);
return NULL;
}
rrec->userdata->copy_fn = userdata->copy_fn;
diff --git a/source/nmbd/nmbd_sendannounce.c b/source/nmbd/nmbd_sendannounce.c
index 87115a1eb0d..2c1704c73fe 100644
--- a/source/nmbd/nmbd_sendannounce.c
+++ b/source/nmbd/nmbd_sendannounce.c
@@ -27,7 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
@@ -48,9 +47,9 @@ void send_browser_reset(int reset_type, char *to_name, int to_type, struct in_ad
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf;
- CVAL(p,0) = ANN_ResetBrowserState;
+ SCVAL(p,0,ANN_ResetBrowserState);
p++;
- CVAL(p,0) = reset_type;
+ SCVAL(p,0,reset_type);
p++;
send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
@@ -75,10 +74,10 @@ to subnet %s\n", work->work_group, subrec->subnet_name));
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf;
- CVAL(p,0) = ANN_AnnouncementRequest;
+ SCVAL(p,0,ANN_AnnouncementRequest);
p++;
- CVAL(p,0) = work->token; /* (local) Unique workgroup token id. */
+ SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
p++;
StrnCpy(p,global_myname,15);
strupper(p);
@@ -104,17 +103,17 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf+1;
- CVAL(outbuf,0) = announce_type;
+ SCVAL(outbuf,0,announce_type);
/* Announcement parameters. */
- CVAL(p,0) = updatecount;
+ SCVAL(p,0,updatecount);
SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
StrnCpy(p+5,server_name,15);
strupper(p+5);
- CVAL(p,21) = lp_major_announce_version(); /* Major version. */
- CVAL(p,22) = lp_minor_announce_version(); /* Minor version. */
+ SCVAL(p,21,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
/* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
@@ -146,8 +145,8 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
SSVAL(p,0,announce_type);
SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- CVAL(p,6) = lp_major_announce_version(); /* Major version. */
- CVAL(p,7) = lp_minor_announce_version(); /* Minor version. */
+ SCVAL(p,6,lp_major_announce_version()); /* Major version. */
+ SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
SSVAL(p,8,announce_interval); /* In seconds - according to spec. */
p += 10;
@@ -589,7 +588,7 @@ for workgroup %s on subnet %s.\n", global_myworkgroup, FIRST_SUBNET->subnet_name
memset(outbuf,'\0',sizeof(outbuf));
p = outbuf;
- CVAL(p,0) = ANN_MasterAnnouncement;
+ SCVAL(p,0,ANN_MasterAnnouncement);
p++;
StrnCpy(p,global_myname,15);
diff --git a/source/nmbd/nmbd_serverlistdb.c b/source/nmbd/nmbd_serverlistdb.c
index 41009bc68f0..e4bce464a31 100644
--- a/source/nmbd/nmbd_serverlistdb.c
+++ b/source/nmbd/nmbd_serverlistdb.c
@@ -27,8 +27,6 @@
extern int ClientNMB;
-extern int DEBUGLEVEL;
-
extern fstring global_myworkgroup;
extern char **my_netbios_names;
@@ -57,7 +55,7 @@ void remove_all_servers(struct work_record *work)
work->serverlist = servrec->next;
ZERO_STRUCTP(servrec);
- free((char *)servrec);
+ SAFE_FREE(servrec);
}
@@ -122,7 +120,7 @@ void remove_server_from_workgroup(struct work_record *work, struct server_record
work->serverlist = servrec->next;
ZERO_STRUCTP(servrec);
- free((char *)servrec);
+ SAFE_FREE(servrec);
work->subnet->work_changed = True;
}
@@ -298,6 +296,19 @@ static uint32 write_this_workgroup_name( struct subnet_record *subrec,
Write out the browse.dat file.
******************************************************************/
+void write_browse_list_entry(FILE *fp, fstring name, uint32 rec_type,
+ fstring local_master_browser_name, fstring description)
+{
+ fstring tmp;
+
+ slprintf(tmp,sizeof(tmp)-1, "\"%s\"", name);
+ fprintf(fp, "%-25s ", tmp);
+ fprintf(fp, "%08x ", rec_type);
+ slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", local_master_browser_name);
+ fprintf(fp, "%-30s", tmp);
+ fprintf(fp, "\"%s\"\n", description);
+}
+
void write_browse_list(time_t t, BOOL force_write)
{
struct subnet_record *subrec;
@@ -305,7 +316,6 @@ void write_browse_list(time_t t, BOOL force_write)
struct server_record *servrec;
pstring fname,fnamenew;
uint32 stype;
- fstring tmp;
int i;
FILE *fp;
BOOL list_changed = force_write;
@@ -367,12 +377,8 @@ void write_browse_list(time_t t, BOOL force_write)
return;
}
- slprintf(tmp,sizeof(tmp)-1, "\"%s\"", work->work_group);
- fprintf(fp, "%-25s ", tmp);
- fprintf(fp, "%08x ", SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", work->local_master_browser_name);
- fprintf(fp, "%-30s", tmp);
- fprintf(fp, "\"%s\"\n", work->work_group);
+ write_browse_list_entry(fp, work->work_group, SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY,
+ work->local_master_browser_name, work->work_group);
/*
* We need to do something special for our own names.
@@ -396,13 +402,10 @@ void write_browse_list(time_t t, BOOL force_write)
}
/* Output server details, plus what workgroup they're in. */
- slprintf(tmp, sizeof(tmp)-1, "\"%s\"", my_netbios_names[i]);
- fprintf(fp, "%-25s ", tmp);
- fprintf(fp, "%08x ", stype);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ",
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- fprintf(fp, "%-30s", tmp);
- fprintf(fp, "\"%s\"\n", global_myworkgroup);
+ write_browse_list_entry(fp, my_netbios_names[i], stype,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
+ global_myworkgroup);
+
}
for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
@@ -415,15 +418,9 @@ void write_browse_list(time_t t, BOOL force_write)
uint32 wg_type = write_this_workgroup_name( subrec, work);
if(wg_type)
- {
- slprintf(tmp, sizeof(tmp)-1, "\"%s\"", work->work_group);
- fprintf(fp, "%-25s ", tmp);
-
- fprintf(fp, "%08x ", wg_type);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", work->local_master_browser_name);
- fprintf(fp, "%-30s", tmp);
- fprintf(fp, "\"%s\"\n", work->work_group);
- }
+ write_browse_list_entry(fp, work->work_group, wg_type,
+ work->local_master_browser_name,
+ work->work_group);
/* Now write out any server records a workgroup may have. */
@@ -437,16 +434,10 @@ void write_browse_list(time_t t, BOOL force_write)
serv_type = write_this_server_name(subrec, work, servrec);
+ /* Output server details, plus what workgroup they're in. */
if(serv_type)
- {
- /* Output server details, plus what workgroup they're in. */
- slprintf(tmp, sizeof(tmp)-1, "\"%s\"", servrec->serv.name);
- fprintf(fp, "%-25s ", tmp);
- fprintf(fp, "%08x ", serv_type);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", servrec->serv.comment);
- fprintf(fp, "%-30s", tmp);
- fprintf(fp, "\"%s\"\n", work->work_group);
- }
+ write_browse_list_entry(fp, servrec->serv.name, serv_type,
+ servrec->serv.comment, work->work_group);
}
}
}
diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c
index 3bad3f9568a..9030e42b298 100644
--- a/source/nmbd/nmbd_subnetdb.c
+++ b/source/nmbd/nmbd_subnetdb.c
@@ -31,8 +31,6 @@ extern int ClientNMB;
extern int ClientDGRAM;
extern int global_nmb_port;
-extern int DEBUGLEVEL;
-
extern fstring myworkgroup;
extern char **my_netbios_names;
extern struct in_addr ipzero;
@@ -188,7 +186,7 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
close(nmb_sock);
close(dgram_sock);
ZERO_STRUCTP(subrec);
- free((char *)subrec);
+ SAFE_FREE(subrec);
return(NULL);
}
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 4afb730519a..1132d9a5147 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -31,8 +31,6 @@
#include "includes.h"
#include "smb.h"
-extern int DEBUGLEVEL;
-
struct sync_record {
struct sync_record *next, *prev;
fstring workgroup;
@@ -299,7 +297,7 @@ void sync_check_completion(void)
complete_sync(s);
DLIST_REMOVE(syncs, s);
ZERO_STRUCTP(s);
- free(s);
+ SAFE_FREE(s);
}
}
}
diff --git a/source/nmbd/nmbd_winsproxy.c b/source/nmbd/nmbd_winsproxy.c
index 24ba192cdb3..84102289587 100644
--- a/source/nmbd/nmbd_winsproxy.c
+++ b/source/nmbd/nmbd_winsproxy.c
@@ -23,8 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
Function called when the name lookup succeeded.
****************************************************************************/
@@ -83,7 +81,7 @@ returned for name %s.\n", nmb_namestr(nmbname) ));
WINS_PROXY_NAME, num_ips, iplist );
if(iplist != &ip)
- free((char *)iplist);
+ SAFE_FREE(iplist);
/*
* Check that none of the IP addresses we are returning is on the
@@ -161,7 +159,7 @@ static struct userdata_struct *wins_proxy_userdata_copy_fn(struct userdata_struc
/* Do a deep copy of the packet. */
if((copy_of_p = copy_packet(p)) == NULL)
{
- free((char *)new_userdata);
+ SAFE_FREE(new_userdata);
return NULL;
}
@@ -192,7 +190,7 @@ static void wins_proxy_userdata_free_fn(struct userdata_struct *userdata)
free_packet(p);
ZERO_STRUCTP(userdata);
- free((char *)userdata);
+ SAFE_FREE(userdata);
}
/****************************************************************************
diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c
index 296102fd99c..04f7ae33bbc 100644
--- a/source/nmbd/nmbd_winsserver.c
+++ b/source/nmbd/nmbd_winsserver.c
@@ -26,7 +26,6 @@
#define WINS_LIST "wins.dat"
#define WINS_VERSION 1
-extern int DEBUGLEVEL;
extern struct in_addr ipzero;
@@ -300,7 +299,7 @@ BOOL initialise_wins(void)
if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
{
DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
continue;
}
@@ -339,7 +338,7 @@ BOOL initialise_wins(void)
name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
}
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
}
fclose(fp);
@@ -1281,7 +1280,7 @@ static void process_wins_dmb_query_request(struct subnet_record *subrec,
prdata, /* data to send. */
num_ips*6); /* data length. */
- free(prdata);
+ SAFE_FREE(prdata);
}
/****************************************************************************
@@ -1339,7 +1338,7 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
reply_data_len); /* data length. */
if((prdata != rdata) && (prdata != NULL))
- free(prdata);
+ SAFE_FREE(prdata);
}
/***********************************************************************
diff --git a/source/nmbd/nmbd_workgroupdb.c b/source/nmbd/nmbd_workgroupdb.c
index 01477c81133..baa40dc1f9e 100644
--- a/source/nmbd/nmbd_workgroupdb.c
+++ b/source/nmbd/nmbd_workgroupdb.c
@@ -27,8 +27,6 @@
extern int ClientNMB;
-extern int DEBUGLEVEL;
-
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
diff --git a/source/nsswitch/nss.h b/source/nsswitch/nss.h
index 6995305b93f..6165e0b24a5 100644
--- a/source/nsswitch/nss.h
+++ b/source/nsswitch/nss.h
@@ -1,3 +1,5 @@
+#ifndef _NSSWITCH_NSS_H
+#define _NSSWITCH_NSS_H
/*
Unix SMB/Netbios implementation.
Version 2.0
@@ -46,7 +48,49 @@ typedef nss_status_t NSS_STATUS;
typedef enum nss_status NSS_STATUS;
-#else /* Nothing's defined. Neither gnu nor sun */
+#elif HAVE_NS_API_H
+
+/* SGI IRIX */
+
+/* following required to prevent warnings of double definition
+ * of datum from ns_api.h
+*/
+#ifdef DATUM
+#define _DATUM_DEFINED
+#endif
+
+#include <ns_api.h>
+
+typedef enum
+{
+ NSS_STATUS_SUCCESS=NS_SUCCESS,
+ NSS_STATUS_NOTFOUND=NS_NOTFOUND,
+ NSS_STATUS_UNAVAIL=NS_UNAVAIL,
+ NSS_STATUS_TRYAGAIN=NS_TRYAGAIN
+} NSS_STATUS;
+
+#define NSD_MEM_STATIC 0
+#define NSD_MEM_VOLATILE 1
+#define NSD_MEM_DYNAMIC 2
+
+#elif defined(HPUX)
+/* HP-UX 11 */
+
+#include "nsswitch/hp_nss_common.h"
+#include "nsswitch/hp_nss_dbdefs.h"
+#include <nsswitch.h>
+
+#ifndef _HAVE_TYPEDEF_NSS_STATUS
+#define _HAVE_TYPEDEF_NSS_STATUS
+typedef nss_status_t NSS_STATUS;
+
+#define NSS_STATUS_SUCCESS NSS_SUCCESS
+#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
+#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
+#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
+#endif /* HPUX */
+
+#else /* Nothing's defined. Neither gnu nor sun nor hp */
typedef enum
{
@@ -58,3 +102,4 @@ typedef enum
#endif
+#endif /* _NSSWITCH_NSS_H */
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index b3dea202c2c..048140fd790 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -281,7 +281,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
return PAM_USER_UNKNOWN;
case 0:
/* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
+ _pam_log(LOG_NOTICE, "user '%s' granted access", username);
return PAM_SUCCESS;
default:
/* we don't know anything about this return value */
@@ -338,7 +338,7 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
return PAM_USER_UNKNOWN;
case 0:
/* Otherwise, the authentication looked good */
- _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
+ _pam_log(LOG_NOTICE, "user '%s' granted access", username);
return PAM_SUCCESS;
default:
/* we don't know anything about this return value */
@@ -461,6 +461,30 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc,
return PAM_SERVICE_ERR;
}
+/* HP added session open and close handlers to always return success */
+PAM_EXTERN
+int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ /* parse arguments */
+ ctrl = _pam_parse(argc, argv);
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_open_session handler") ;
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ /* parse arguments */
+ ctrl = _pam_parse(argc, argv);
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"libpam_winbind:pam_sm_close_session handler");
+ return PAM_SUCCESS;
+}
+/* end HP add */
+
#ifdef PAM_STATIC
/* static module data */
@@ -470,8 +494,8 @@ struct pam_module _pam_winbind_modstruct = {
pam_sm_authenticate,
pam_sm_setcred,
pam_sm_acct_mgmt,
- NULL,
- NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
pam_sm_chauthtok
};
diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
index 5618dc1b61f..058168c72ec 100644
--- a/source/nsswitch/pam_winbind.h
+++ b/source/nsswitch/pam_winbind.h
@@ -25,9 +25,9 @@
#define PAM_SM_ACCOUNT
#define PAM_SM_PASSWORD
-#if defined(SUNOS5) || defined(SUNOS4)
+#if defined(SUNOS5) || defined(SUNOS4) || defined(HPUX)
-/* Solaris always uses dynamic pam modules */
+/* Solaris and HPUX always use dynamic pam modules */
#define PAM_EXTERN extern
#include <security/pam_appl.h>
@@ -68,13 +68,7 @@ do { \
* Don't just free it, forget it too.
*/
-#define _pam_drop(X) \
-do { \
- if (X) { \
- free(X); \
- X=NULL; \
- } \
-} while (0)
+#define _pam_drop(X) SAFE_FREE(X)
#define x_strdup(s) ( (s) ? strdup(s):NULL )
#endif
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 6ade637c8c2..843b85c0c7b 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -32,28 +32,24 @@ NSS_STATUS winbindd_request(int req_type,
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
form DOMAIN/user into a domain and a user */
-static void parse_domain_user(char *domuser, fstring domain, fstring user)
+static BOOL parse_domain_user(char *domuser, fstring domain, fstring user)
{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
- }
+ char *p = strchr(domuser,*lp_winbind_separator());
+
+ if (!p)
+ return False;
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
strupper(domain);
+ return True;
}
/* Call winbindd to convert a name to a sid */
-BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name_type)
+BOOL winbind_lookup_name(const char *name, DOM_SID *sid,
+ enum SID_NAME_USE *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -62,6 +58,13 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name
if (!sid || !name_type)
return False;
+ /*
+ * Don't do the lookup if the name has no separator.
+ */
+
+ if (!strchr(name, *lp_winbind_separator()))
+ return False;
+
/* Send off request */
ZERO_STRUCT(request);
@@ -80,7 +83,8 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name
/* Call winbindd to convert sid to name */
-BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
+BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
+ enum SID_NAME_USE *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -104,7 +108,9 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N
if (result == NSS_STATUS_SUCCESS) {
parse_domain_user(response.data.name.name, dom_name, name);
*name_type = (enum SID_NAME_USE)response.data.name.type;
- DEBUG(10,("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", sid_str, dom_name, name ));
+
+ DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
+ sid_str, dom_name, name));
}
return (result == NSS_STATUS_SUCCESS);
@@ -245,7 +251,7 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
/* Fetch the list of groups a user is a member of from winbindd. This is
used by winbind_initgroups and winbind_getgroups. */
-static int wb_getgroups(char *user, gid_t **groups)
+static int wb_getgroups(const char *user, gid_t **groups)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -281,13 +287,10 @@ int winbind_initgroups(char *user, gid_t gid)
{
gid_t *tgr, *groups = NULL;
int result;
- char *sep;
/* Call normal initgroups if we are a local user */
- sep = lp_winbind_separator();
-
- if (!strchr(user, *sep)) {
+ if (!strchr(user, *lp_winbind_separator())) {
return initgroups(user, gid);
}
@@ -317,8 +320,8 @@ int winbind_initgroups(char *user, gid_t gid)
errno = ENOMEM;
result = -1;
goto done;
- } else
- groups = tgr;
+ }
+ else groups = tgr;
groups[ngroups] = gid;
ngroups++;
@@ -343,7 +346,7 @@ int winbind_initgroups(char *user, gid_t gid)
/* Free response data if necessary */
done:
- safe_free(groups);
+ SAFE_FREE(groups);
return result;
}
@@ -353,16 +356,24 @@ int winbind_initgroups(char *user, gid_t gid)
time consuming. If size is zero, list is not modified and the total
number of groups for the user is returned. */
-int winbind_getgroups(char *user, int size, gid_t *list)
+int winbind_getgroups(const char *user, int size, gid_t *list)
{
gid_t *groups = NULL;
int result, i;
+ /*
+ * Don't do the lookup if the name has no separator.
+ */
+
+ if (!strchr(user, *lp_winbind_separator()))
+ return -1;
+
/* Fetch list of groups */
result = wb_getgroups(user, &groups);
- if (size == 0) goto done;
+ if (size == 0)
+ goto done;
if (result > size) {
result = -1;
@@ -377,13 +388,11 @@ int winbind_getgroups(char *user, int size, gid_t *list)
}
done:
- safe_free(groups);
+ SAFE_FREE(groups);
return result;
}
-/**********************************************************************************
- Utility function. Convert a uid_t to a name if possible.
-**********************************************************************************/
+/* Utility function. Convert a uid_t to a name if possible. */
BOOL winbind_uidtoname(fstring name, uid_t uid)
{
@@ -400,13 +409,13 @@ BOOL winbind_uidtoname(fstring name, uid_t uid)
if (name_type != SID_NAME_USER)
return False;
- slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name, lp_winbind_separator(), user_name );
+ slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
+ lp_winbind_separator(), user_name);
+
return True;
}
-/**********************************************************************************
- Utility function. Convert a gid_t to a name if possible.
-**********************************************************************************/
+/* Utility function. Convert a gid_t to a name if possible. */
BOOL winbind_gidtoname(fstring name, gid_t gid)
{
@@ -420,25 +429,24 @@ BOOL winbind_gidtoname(fstring name, gid_t gid)
if (!winbind_lookup_sid(&sid, dom_name, group_name, &name_type))
return False;
- if (name_type != SID_NAME_USER)
+ if (name_type != SID_NAME_DOM_GRP)
return False;
- slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name, lp_winbind_separator(), group_name );
+ slprintf(name, sizeof(fstring)-1, "%s%s%s", dom_name,
+ lp_winbind_separator(), group_name);
+
return True;
}
-/**********************************************************************************
- Utility function. Convert a name to a uid_t if possible.
-**********************************************************************************/
+/* Utility function. Convert a name to a uid_t if possible. */
-BOOL winbind_nametouid(uid_t *puid, char *name)
+BOOL winbind_nametouid(uid_t *puid, const char *name)
{
DOM_SID sid;
enum SID_NAME_USE name_type;
- if (!winbind_lookup_name(name, &sid, &name_type)) {
- return False;
- }
+ if (!winbind_lookup_name(name, &sid, &name_type))
+ return False;
if (name_type != SID_NAME_USER)
return False;
@@ -446,18 +454,15 @@ BOOL winbind_nametouid(uid_t *puid, char *name)
return winbind_sid_to_uid(puid, &sid);
}
-/**********************************************************************************
- Utility function. Convert a name to a gid_t if possible.
-**********************************************************************************/
+/* Utility function. Convert a name to a gid_t if possible. */
-BOOL winbind_nametogid(gid_t *pgid, char *gname)
+BOOL winbind_nametogid(gid_t *pgid, const char *gname)
{
DOM_SID g_sid;
enum SID_NAME_USE name_type;
- if (!winbind_lookup_name(gname, &g_sid, &name_type)) {
- return False;
- }
+ if (!winbind_lookup_name(gname, &g_sid, &name_type))
+ return False;
if (name_type != SID_NAME_DOM_GRP)
return False;
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 7fb2bc2cf54..d3feaeb4504 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -28,15 +28,25 @@
/* Global variables. These are effectively the client state information */
-static int established_socket = -1; /* fd for winbindd socket */
+int winbindd_fd = -1; /* fd for winbindd socket */
static char *excluded_domain;
+/* Free a response structure */
+
+void free_response(struct winbindd_response *response)
+{
+ /* Free any allocated extra_data */
+
+ if (response)
+ SAFE_FREE(response->extra_data);
+}
+
/*
smbd needs to be able to exclude lookups for its own domain
*/
void winbind_exclude_domain(const char *domain)
{
- if (excluded_domain) free(excluded_domain);
+ SAFE_FREE(excluded_domain);
excluded_domain = strdup(domain);
}
@@ -77,15 +87,15 @@ void init_response(struct winbindd_response *response)
void close_sock(void)
{
- if (established_socket != -1) {
- close(established_socket);
- established_socket = -1;
+ if (winbindd_fd != -1) {
+ close(winbindd_fd);
+ winbindd_fd = -1;
}
}
/* Connect to winbindd socket */
-static int open_pipe_sock(void)
+int winbind_open_pipe_sock(void)
{
struct sockaddr_un sunaddr;
static pid_t our_pid;
@@ -93,15 +103,12 @@ static int open_pipe_sock(void)
pstring path;
if (our_pid != getpid()) {
- if (established_socket != -1) {
- close(established_socket);
- }
- established_socket = -1;
+ close_sock();
our_pid = getpid();
}
- if (established_socket != -1) {
- return established_socket;
+ if (winbindd_fd != -1) {
+ return winbindd_fd;
}
/* Check permissions on unix socket directory */
@@ -147,18 +154,17 @@ static int open_pipe_sock(void)
/* Connect to socket */
- if ((established_socket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return -1;
}
- if (connect(established_socket, (struct sockaddr *)&sunaddr,
+ if (connect(winbindd_fd, (struct sockaddr *)&sunaddr,
sizeof(sunaddr)) == -1) {
close_sock();
- established_socket = -1;
return -1;
}
- return established_socket;
+ return winbindd_fd;
}
/* Write data to winbindd socket with timeout */
@@ -171,7 +177,7 @@ int write_sock(void *buffer, int count)
restart:
- if (open_pipe_sock() == -1) {
+ if (winbind_open_pipe_sock() == -1) {
return -1;
}
@@ -182,28 +188,26 @@ int write_sock(void *buffer, int count)
while(nwritten < count) {
struct timeval tv;
fd_set r_fds;
- int selret;
/* Catch pipe close on other end by checking if a read()
call would not block by calling select(). */
FD_ZERO(&r_fds);
- FD_SET(established_socket, &r_fds);
+ FD_SET(winbindd_fd, &r_fds);
ZERO_STRUCT(tv);
- if ((selret = select(established_socket + 1, &r_fds,
- NULL, NULL, &tv)) == -1) {
+ if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
close_sock();
return -1; /* Select error */
}
/* Write should be OK if fd not available for reading */
- if (!FD_ISSET(established_socket, &r_fds)) {
+ if (!FD_ISSET(winbindd_fd, &r_fds)) {
/* Do the write */
- result = write(established_socket,
+ result = write(winbindd_fd,
(char *)buffer + nwritten,
count - nwritten);
@@ -239,7 +243,7 @@ static int read_sock(void *buffer, int count)
while(nread < count) {
- result = read(established_socket, (char *)buffer + nread,
+ result = read(winbindd_fd, (char *)buffer + nread,
count - nread);
if ((result == -1) || (result == 0)) {
@@ -296,6 +300,7 @@ int read_reply(struct winbindd_response *response)
if ((result2 = read_sock(response->extra_data, extra_data_len))
== -1) {
+ free_response(response);
return -1;
}
}
@@ -305,26 +310,13 @@ int read_reply(struct winbindd_response *response)
return result1 + result2;
}
-/* Free a response structure */
-
-void free_response(struct winbindd_response *response)
-{
- /* Free any allocated extra_data */
-
- if (response && response->extra_data) {
- free(response->extra_data);
- response->extra_data = NULL;
- }
-}
-
-/* Handle simple types of requests */
+/*
+ * send simple types of requests
+ */
-NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response)
+NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
{
struct winbindd_request lrequest;
- struct winbindd_response lresponse;
/* Check for our tricky environment variable */
@@ -338,11 +330,6 @@ NSS_STATUS winbindd_request(int req_type,
return NSS_STATUS_NOTFOUND;
}
- if (!response) {
- ZERO_STRUCT(lresponse);
- response = &lresponse;
- }
-
if (!request) {
ZERO_STRUCT(lrequest);
request = &lrequest;
@@ -351,12 +338,29 @@ NSS_STATUS winbindd_request(int req_type,
/* Fill in request and send down pipe */
init_request(request, req_type);
- init_response(response);
if (write_sock(request, sizeof(*request)) == -1) {
return NSS_STATUS_UNAVAIL;
}
+ return NSS_STATUS_SUCCESS;
+}
+
+/*
+ * Get results from winbindd request
+ */
+
+NSS_STATUS winbindd_get_response(struct winbindd_response *response)
+{
+ struct winbindd_response lresponse;
+
+ if (!response) {
+ ZERO_STRUCT(lresponse);
+ response = &lresponse;
+ }
+
+ init_response(response);
+
/* Wait for reply */
if (read_reply(response) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -374,3 +378,17 @@ NSS_STATUS winbindd_request(int req_type,
return NSS_STATUS_SUCCESS;
}
+
+/* Handle simple types of requests */
+
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ NSS_STATUS status;
+
+ status = winbindd_send_request(req_type, request);
+ if (status != NSS_STATUS_SUCCESS)
+ return(status);
+ return winbindd_get_response(response);
+}
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index d29b144147d..fceb0e86342 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -59,6 +59,56 @@ static BOOL wbinfo_get_usergroups(char *user)
return True;
}
+/* Convert NetBIOS name to IP */
+
+static BOOL wbinfo_wins_byname(char *name)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ /* Send request */
+
+ fstrcpy(request.data.name, name);
+ if (winbindd_request(WINBINDD_WINS_BYNAME, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
+ return False;
+ }
+
+ /* Display response */
+
+ printf("%s\n", response.data.name.name);
+
+ return True;
+}
+
+/* Convert IP to NetBIOS name */
+
+static BOOL wbinfo_wins_byip(char *ip)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ /* Send request */
+
+ fstrcpy(request.data.name, ip);
+ if (winbindd_request(WINBINDD_WINS_BYIP, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
+ return False;
+ }
+
+ /* Display response */
+
+ printf("%s\n", response.data.name.name);
+
+ return True;
+}
+
/* List trusted domains */
static BOOL wbinfo_list_domains(void)
@@ -244,6 +294,13 @@ static BOOL wbinfo_lookupname(char *name)
struct winbindd_request request;
struct winbindd_response response;
+ /*
+ * Don't do the lookup if the name has no separator.
+ */
+
+ if (!strchr(name, *lp_winbind_separator()))
+ return False;
+
/* Send off request */
ZERO_STRUCT(request);
@@ -271,6 +328,13 @@ static BOOL wbinfo_auth(char *username)
NSS_STATUS result;
char *p;
+ /*
+ * Don't do the lookup if the name has no separator.
+ */
+
+ if (!strchr(username, *lp_winbind_separator()))
+ return False;
+
/* Send off request */
ZERO_STRUCT(request);
@@ -306,6 +370,13 @@ static BOOL wbinfo_auth_crap(char *username)
fstring pass;
char *p;
+ /*
+ * Don't do the lookup if the name has no separator.
+ */
+
+ if (!strchr(username, *lp_winbind_separator()))
+ return False;
+
/* Send off request */
ZERO_STRUCT(request);
@@ -399,14 +470,44 @@ static BOOL print_domain_groups(void)
return True;
}
+/* Set the authorised user for winbindd access in secrets.tdb */
+
+static BOOL wbinfo_set_auth_user(char *username)
+{
+ char *password;
+
+ /* Separate into user and password */
+
+ password = strchr(username, '%');
+
+ if (password) {
+ *password = 0;
+ password++;
+ } else
+ password = "";
+
+ /* Store in secrets.tdb */
+
+ if (!secrets_init() ||
+ !secrets_store(SECRETS_AUTH_USER, username, strlen(username) + 1) ||
+ !secrets_store(SECRETS_AUTH_PASSWORD, password, strlen(password) + 1)) {
+ fprintf(stderr, "error storing authenticated user info\n");
+ return False;
+ }
+
+ return True;
+}
+
/* Print program usage */
static void usage(void)
{
printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
- "| -a user%%password\n");
+ "| -aA user%%password\n");
printf("\t-u\t\t\tlists all domain users\n");
printf("\t-g\t\t\tlists all domain groups\n");
+ printf("\t-h name\t\t\tconverts NetBIOS hostname to IP\n");
+ printf("\t-i ip\t\t\tconverts IP address to NetBIOS name\n");
printf("\t-n name\t\t\tconverts name to sid\n");
printf("\t-s sid\t\t\tconverts sid to name\n");
printf("\t-U uid\t\t\tconverts uid to sid\n");
@@ -417,6 +518,7 @@ static void usage(void)
printf("\t-m\t\t\tlist trusted domains\n");
printf("\t-r user\t\t\tget user groups\n");
printf("\t-a user%%password\tauthenticate user\n");
+ printf("\t-A user%%password\tstore session setup auth password\n");
}
/* Main program */
@@ -440,8 +542,12 @@ int main(int argc, char **argv)
TimeInit();
+ codepage_initialise(lp_client_code_page());
+ charset_initialise();
+
if (!lp_load(CONFIGFILE, True, False, False)) {
- DEBUG(0, ("error opening config file\n"));
+ fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
+ CONFIGFILE, strerror(errno));
exit(1);
}
@@ -454,7 +560,7 @@ int main(int argc, char **argv)
return 1;
}
- while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:a:")) != EOF) {
+ while ((opt = getopt(argc, argv, "h:i:ugs:n:U:G:S:Y:tmr:a:A:")) != EOF) {
switch (opt) {
case 'u':
if (!print_domain_users()) {
@@ -468,6 +574,18 @@ int main(int argc, char **argv)
return 1;
}
break;
+ case 'h':
+ if (!wbinfo_wins_byname(optarg)) {
+ printf("Could not lookup WINS by hostname %s\n", optarg);
+ return 1;
+ }
+ break;
+ case 'i':
+ if (!wbinfo_wins_byip(optarg)) {
+ printf("Could not lookup WINS by IP %s\n", optarg);
+ return 1;
+ }
+ break;
case 's':
if (!wbinfo_lookupsid(optarg)) {
printf("Could not lookup sid %s\n", optarg);
@@ -547,6 +665,12 @@ int main(int argc, char **argv)
break;
}
+ case 'A': {
+ if (!(wbinfo_set_auth_user(optarg))) {
+ return 1;
+ }
+ break;
+ }
/* Invalid option */
default:
diff --git a/source/nsswitch/winbind_nss.c b/source/nsswitch/winbind_nss.c
index a2816bfdd3f..cbfea3b1027 100644
--- a/source/nsswitch/winbind_nss.c
+++ b/source/nsswitch/winbind_nss.c
@@ -25,16 +25,499 @@
#include "winbind_nss_config.h"
#include "winbindd_nss.h"
-/* Prototypes from common.c */
+#ifdef HAVE_NS_API_H
+#undef VOLATILE
+
+#include <ns_daemon.h>
+#endif
+
+#define MAX_GETPWENT_USERS 250
+#define MAX_GETGRENT_USERS 250
+
+/* Prototypes from wb_common.c */
+
+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 */
+
+static int send_next_request(nsd_file_t *, struct winbindd_request *);
+static int do_list(int state, nsd_file_t *rq);
+
+static nsd_file_t *current_rq = NULL;
+static int current_winbind_xid = 0;
+static int next_winbind_xid = 0;
+
+typedef struct winbind_xid {
+ int xid;
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+ struct winbind_xid *next;
+} winbind_xid_t;
+
+static winbind_xid_t *winbind_xids = (winbind_xid_t *)0;
+
+static int
+winbind_xid_new(int xid, nsd_file_t *rq, struct winbindd_request *request)
+{
+ winbind_xid_t *new;
+
+ nsd_logprintf(NSD_LOG_LOW,
+ "entering winbind_xid_new xid = %d rq = 0x%x, request = 0x%x\n",
+ xid, rq, request);
+ new = (winbind_xid_t *)nsd_calloc(1,sizeof(winbind_xid_t));
+ if (!new) {
+ nsd_logprintf(NSD_LOG_RESOURCE,"winbind_xid_new: failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ new->xid = xid;
+ new->rq = rq;
+ new->request = request;
+ new->next = winbind_xids;
+ winbind_xids = new;
+
+ return NSD_CONTINUE;
+}
+
+/*
+** This routine will look down the xid list and return the request
+** associated with an xid. We remove the record if it is found.
+*/
+nsd_file_t *
+winbind_xid_lookup(int xid, struct winbindd_request **requestp)
+{
+ winbind_xid_t **last, *dx;
+ nsd_file_t *result=0;
+
+ for (last = &winbind_xids, dx = winbind_xids; dx && (dx->xid != xid);
+ last = &dx->next, dx = dx->next);
+ if (dx) {
+ *last = dx->next;
+ result = dx->rq;
+ *requestp = dx->request;
+ SAFE_FREE(dx);
+ }
+ nsd_logprintf(NSD_LOG_LOW,
+ "entering winbind_xid_lookup xid = %d rq = 0x%x, request = 0x%x\n",
+ xid, result, dx->request);
+
+ return result;
+}
+
+static int
+winbind_startnext_timeout(nsd_file_t **rqp, nsd_times_t *to)
+{
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind startnext)\n");
+ rq = to->t_file;
+ *rqp = rq;
+ nsd_timeout_remove(rq);
+ request = to->t_clientdata;
+ return(send_next_request(rq, request));
+}
+
+static void
+dequeue_request()
+{
+ nsd_file_t *rq;
+ struct winbindd_request *request;
+
+ /*
+ * Check for queued requests
+ */
+ if (winbind_xids) {
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind) unqueue xid %d\n",
+ current_winbind_xid);
+ rq = winbind_xid_lookup(current_winbind_xid++, &request);
+ /* cause a timeout on the queued request so we can send it */
+ nsd_timeout_new(rq,1,winbind_startnext_timeout,request);
+ }
+}
+
+static int
+do_request(nsd_file_t *rq, struct winbindd_request *request)
+{
+ if (winbind_xids == NULL) {
+ /*
+ * No outstanding requests.
+ * Send off the request to winbindd
+ */
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) sending request\n");
+ return(send_next_request(rq, request));
+ } else {
+ /*
+ * Just queue it up for now - previous callout or timout
+ * will start it up
+ */
+ nsd_logprintf(NSD_LOG_MIN,
+ "lookup (winbind): queue request xid = %d\n",
+ next_winbind_xid);
+ return(winbind_xid_new(next_winbind_xid++, rq, request));
+ }
+}
+
+static int
+winbind_callback(nsd_file_t **rqp, int fd)
+{
+ struct winbindd_response response;
+ struct winbindd_pw *pw = &response.data.pw;
+ struct winbindd_gr *gr = &response.data.gr;
+ nsd_file_t *rq;
+ NSS_STATUS status;
+ char result[1024];
+ char *members;
+ int i;
+
+ dequeue_request();
+
+ nsd_logprintf(NSD_LOG_MIN, "entering callback (winbind)\n");
+
+ rq = current_rq;
+ *rqp = rq;
+
+ nsd_timeout_remove(rq);
+ nsd_callback_remove(fd);
+
+ ZERO_STRUCT(response);
+ status = winbindd_get_response(&response);
+
+ if (status != NSS_STATUS_SUCCESS) {
+ /* free any extra data area in response structure */
+ free_response(&response);
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) returning not found, status = %d\n",
+ status);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+ switch ((int)rq->f_cmd_data) {
+ case WINBINDD_WINS_BYNAME:
+ case WINBINDD_WINS_BYIP:
+ snprintf(result,1023,"%s\n",response.data.name.name);
+ break;
+ case WINBINDD_GETPWNAM_FROM_UID:
+ case WINBINDD_GETPWNAM_FROM_USER:
+ snprintf(result,1023,"%s:%s:%d:%d:%s:%s:%s\n",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+ break;
+ case WINBINDD_GETGRNAM_FROM_GROUP:
+ case WINBINDD_GETGRNAM_FROM_GID:
+ if (gr->num_gr_mem && response.extra_data)
+ members = response.extra_data;
+ else
+ members = "";
+ snprintf(result,1023,"%s:%s:%d:%s\n",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid, members);
+ break;
+ case WINBINDD_SETGRENT:
+ case WINBINDD_SETPWENT:
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - SETPWENT/SETGRENT\n");
+ free_response(&response);
+ return(do_list(1,rq));
+ case WINBINDD_GETGRENT:
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) - %d GETGRENT responses\n",
+ response.data.num_entries);
+ if (response.data.num_entries) {
+ gr = (struct winbindd_gr *)response.extra_data;
+ if (! gr ) {
+ nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
+ free_response(&response);
+ return NSD_ERROR;
+ }
+ members = (char *)response.extra_data +
+ (response.data.num_entries * sizeof(struct winbindd_gr));
+ for (i = 0; i < response.data.num_entries; i++) {
+ snprintf(result,1023,"%s:%s:%d:%s\n",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid,
+ &members[gr->gr_mem_ofs]);
+ nsd_logprintf(NSD_LOG_MIN, " GETGRENT %s\n",result);
+ nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
+ gr++;
+ }
+ }
+ i = response.data.num_entries;
+ free_response(&response);
+ if (i < MAX_GETPWENT_USERS)
+ return(do_list(2,rq));
+ else
+ return(do_list(1,rq));
+ case WINBINDD_GETPWENT:
+ nsd_logprintf(NSD_LOG_MIN,
+ "callback (winbind) - %d GETPWENT responses\n",
+ response.data.num_entries);
+ if (response.data.num_entries) {
+ pw = (struct winbindd_pw *)response.extra_data;
+ if (! pw ) {
+ nsd_logprintf(NSD_LOG_MIN, " no extra_data\n");
+ free_response(&response);
+ return NSD_ERROR;
+ }
+ for (i = 0; i < response.data.num_entries; i++) {
+ snprintf(result,1023,"%s:%s:%d:%d:%s:%s:%s",
+ pw->pw_name,
+ pw->pw_passwd,
+ pw->pw_uid,
+ pw->pw_gid,
+ pw->pw_gecos,
+ pw->pw_dir,
+ pw->pw_shell);
+ nsd_logprintf(NSD_LOG_MIN, " GETPWENT %s\n",result);
+ nsd_append_element(rq,NS_SUCCESS,result,strlen(result));
+ pw++;
+ }
+ }
+ i = response.data.num_entries;
+ free_response(&response);
+ if (i < MAX_GETPWENT_USERS)
+ return(do_list(2,rq));
+ else
+ return(do_list(1,rq));
+ case WINBINDD_ENDGRENT:
+ case WINBINDD_ENDPWENT:
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - ENDPWENT/ENDGRENT\n");
+ nsd_append_element(rq,NS_SUCCESS,"\n",1);
+ free_response(&response);
+ return NSD_NEXT;
+ default:
+ free_response(&response);
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) - no valid command\n");
+ return NSD_NEXT;
+ }
+ nsd_logprintf(NSD_LOG_MIN, "callback (winbind) %s\n", result);
+ /* free any extra data area in response structure */
+ free_response(&response);
+ nsd_set_result(rq,NS_SUCCESS,result,strlen(result),VOLATILE);
+ return NSD_OK;
+}
+
+static int
+winbind_timeout(nsd_file_t **rqp, nsd_times_t *to)
+{
+ nsd_file_t *rq;
+
+ dequeue_request();
+
+ nsd_logprintf(NSD_LOG_MIN, "timeout (winbind)\n");
+
+ rq = to->t_file;
+ *rqp = rq;
+
+ /* Remove the callback and timeout */
+ nsd_callback_remove(winbindd_fd);
+ nsd_timeout_remove(rq);
+
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+}
+
+static int
+send_next_request(nsd_file_t *rq, struct winbindd_request *request)
+{
+ NSS_STATUS status;
+ long timeout;
+
+ timeout = 1000;
+
+ nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) %d to = %d\n",
+ rq->f_cmd_data, timeout);
+ status = winbindd_send_request((int)rq->f_cmd_data,request);
+ SAFE_FREE(request);
+
+ if (status != NSS_STATUS_SUCCESS) {
+ nsd_logprintf(NSD_LOG_MIN,
+ "send_next_request (winbind) error status = %d\n",status);
+ rq->f_status = status;
+ return NSD_NEXT;
+ }
+
+ current_rq = rq;
+
+ /*
+ * Set up callback and timeouts
+ */
+ nsd_logprintf(NSD_LOG_MIN, "send_next_request (winbind) fd = %d\n",winbindd_fd);
+ nsd_callback_new(winbindd_fd,winbind_callback,NSD_READ);
+ nsd_timeout_new(rq,timeout,winbind_timeout,(void *)0);
+ return NSD_CONTINUE;
+}
+
+int init(void)
+{
+ nsd_logprintf(NSD_LOG_MIN, "entering init (winbind)\n");
+ return(NSD_OK);
+}
+
+int lookup(nsd_file_t *rq)
+{
+ char *map;
+ char *key;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering lookup (winbind)\n");
+ if (! rq)
+ return NSD_ERROR;
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
+ if (! map || ! key) {
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) table or key not defined\n");
+ rq->f_status = NS_BADREQ;
+ return NSD_ERROR;
+ }
+
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind %s)\n",map);
+
+ request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
+ if (! request) {
+ nsd_logprintf(NSD_LOG_RESOURCE,
+ "lookup (winbind): failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ if (strcasecmp(map,"passwd.byuid") == 0) {
+ request->data.uid = atoi(key);
+ rq->f_cmd_data = (void *)WINBINDD_GETPWNAM_FROM_UID;
+ } else if (strcasecmp(map,"passwd.byname") == 0) {
+ strncpy(request->data.username, key,
+ sizeof(request->data.username) - 1);
+ request->data.username[sizeof(request->data.username) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_GETPWNAM_FROM_USER;
+ } else if (strcasecmp(map,"group.byname") == 0) {
+ strncpy(request->data.groupname, key,
+ sizeof(request->data.groupname) - 1);
+ request->data.groupname[sizeof(request->data.groupname) - 1] = '\0';
+ rq->f_cmd_data = (void *)WINBINDD_GETGRNAM_FROM_GROUP;
+ } else if (strcasecmp(map,"group.bygid") == 0) {
+ request->data.gid = atoi(key);
+ rq->f_cmd_data = (void *)WINBINDD_GETGRNAM_FROM_GID;
+ } else if (strcasecmp(map,"hosts.byname") == 0) {
+ strncpy(request->data.name, key, sizeof(request->data.name) - 1);
+ rq->f_cmd_data = (void *)WINBINDD_WINS_BYNAME;
+ } else if (strcasecmp(map,"hosts.byaddr") == 0) {
+ strncpy(request->data.name, key, sizeof(request->data.name) - 1);
+ rq->f_cmd_data = (void *)WINBINDD_WINS_BYIP;
+ } else {
+ /*
+ * Don't understand this map - just return not found
+ */
+ nsd_logprintf(NSD_LOG_MIN, "lookup (winbind) unknown table\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+
+ return(do_request(rq, request));
+}
+
+int list(nsd_file_t *rq)
+{
+ char *map;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering list (winbind)\n");
+ if (! rq)
+ return NSD_ERROR;
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ if (! map ) {
+ nsd_logprintf(NSD_LOG_MIN, "list (winbind) table not defined\n");
+ rq->f_status = NS_BADREQ;
+ return NSD_ERROR;
+ }
+
+ nsd_logprintf(NSD_LOG_MIN, "list (winbind %s)\n",map);
+
+ return (do_list(0,rq));
+}
+
+static int
+do_list(int state, nsd_file_t *rq)
+{
+ char *map;
+ struct winbindd_request *request;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering do_list (winbind) state = %d\n",state);
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ request = (struct winbindd_request *)nsd_calloc(1,sizeof(struct winbindd_request));
+ if (! request) {
+ nsd_logprintf(NSD_LOG_RESOURCE,
+ "do_list (winbind): failed malloc\n");
+ return NSD_ERROR;
+ }
+
+ if (strcasecmp(map,"passwd.byname") == 0) {
+ switch (state) {
+ case 0:
+ rq->f_cmd_data = (void *)WINBINDD_SETPWENT;
+ break;
+ case 1:
+ request->data.num_entries = MAX_GETPWENT_USERS;
+ rq->f_cmd_data = (void *)WINBINDD_GETPWENT;
+ break;
+ case 2:
+ rq->f_cmd_data = (void *)WINBINDD_ENDPWENT;
+ break;
+ default:
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+ } else if (strcasecmp(map,"group.byname") == 0) {
+ switch (state) {
+ case 0:
+ rq->f_cmd_data = (void *)WINBINDD_SETGRENT;
+ break;
+ case 1:
+ request->data.num_entries = MAX_GETGRENT_USERS;
+ rq->f_cmd_data = (void *)WINBINDD_GETGRENT;
+ break;
+ case 2:
+ rq->f_cmd_data = (void *)WINBINDD_ENDGRENT;
+ break;
+ default:
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown state\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+ } else {
+ /*
+ * Don't understand this map - just return not found
+ */
+ nsd_logprintf(NSD_LOG_MIN, "do_list (winbind) unknown table\n");
+ SAFE_FREE(request);
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+ }
+
+ return(do_request(rq, request));
+}
+
+#else
+
/* Allocate some space from the nss static buffer. The buffer and buflen
are the pointers passed in by the C library to the _nss_ntdom_*
functions. */
@@ -50,16 +533,6 @@ static char *get_static(char **buffer, int *buflen, int len)
return NULL;
}
- /* Some architectures, like Sparc, need pointers aligned on
- boundaries */
-#if _ALIGNMENT_REQUIRED
- {
- int mod = len % _MAX_ALIGNMENT;
- if(mod != 0)
- len += _MAX_ALIGNMENT - mod;
- }
-#endif
-
/* Return an index into the static buffer */
result = *buffer;
@@ -194,6 +667,7 @@ static int fill_grent(struct group *result, struct winbindd_gr *gr,
{
fstring name;
int i;
+ char *tst;
/* Group name */
@@ -229,14 +703,20 @@ static int fill_grent(struct group *result, struct winbindd_gr *gr,
gr->num_gr_mem = 0;
}
- if ((result->gr_mem =
- (char **)get_static(buffer, buflen, (gr->num_gr_mem + 1) *
- sizeof(char *))) == NULL) {
+ /* this next value is a pointer to a pointer so let's align it */
+
+ /* Calculate number of extra bytes needed to align on pointer size boundry */
+ if ((i = (int)*buffer % sizeof(char*)) != 0)
+ i = sizeof(char*) - i;
+
+ if ((tst = get_static(buffer, buflen, ((gr->num_gr_mem + 1) *
+ sizeof(char *)+i))) == NULL) {
/* Out of memory */
return NSS_STATUS_TRYAGAIN;
}
+ result->gr_mem = (char **)(tst + i);
if (gr->num_gr_mem == 0) {
@@ -318,8 +798,6 @@ _nss_winbind_endpwent(void)
/* Fetch the next password entry from ntdom password database */
-#define MAX_GETPWENT_USERS 250
-
NSS_STATUS
_nss_winbind_getpwent_r(struct passwd *result, char *buffer,
size_t buflen, int *errnop)
@@ -562,8 +1040,6 @@ _nss_winbind_endgrent(void)
/* Get next entry from ntdom group database */
-#define MAX_GETGRENT_USERS 250
-
NSS_STATUS
_nss_winbind_getgrent_r(struct group *result,
char *buffer, size_t buflen, int *errnop)
@@ -785,9 +1261,9 @@ _nss_winbind_getgrgid_r(gid_t gid,
/* Initialise supplementary groups */
NSS_STATUS
-_nss_winbind_initgroups(char *user, gid_t group, long int *start,
- long int *size, gid_t *groups, long int limit,
- int *errnop)
+_nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
+ long int *size, gid_t **groups, long int limit,
+ int *errnop)
{
NSS_STATUS ret;
struct winbindd_request request;
@@ -822,13 +1298,15 @@ _nss_winbind_initgroups(char *user, gid_t group, long int *start,
/* Add to buffer */
if (*start == *size && limit <= 0) {
- groups = realloc(
- groups, 2 * (*size) * sizeof(*groups));
- if (!groups) goto done;
- *size *= 2;
+ (*groups) = realloc(
+ (*groups), (2 * (*size) + 1) * sizeof(**groups));
+ if (! *groups) goto done;
+ *size = 2 * (*size) + 1;
}
- groups[*start] = gid_list[i];
+ if (*start == *size) goto done;
+
+ (*groups)[*start] = gid_list[i];
*start += 1;
/* Filled buffer? */
@@ -842,3 +1320,5 @@ _nss_winbind_initgroups(char *user, gid_t group, long int *start,
done:
return ret;
}
+
+#endif
diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h
index 88561ee8084..5612f207774 100644
--- a/source/nsswitch/winbind_nss_config.h
+++ b/source/nsswitch/winbind_nss_config.h
@@ -88,6 +88,7 @@ NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid,
struct group *result, char *buffer,
size_t buflen, int *errnop);
+#ifndef _SMB_MACROS_H
/* I'm trying really hard not to include anything from smb.h with the
result of some silly looking redeclaration of structures. */
@@ -134,7 +135,7 @@ typedef int BOOL;
/* zero a structure given a pointer to the structure */
#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
-
+
/* Some systems (SCO) treat UNIX domain sockets as FIFOs */
#ifndef S_IFSOCK
@@ -145,4 +146,5 @@ typedef int BOOL;
#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
#endif
+#endif /* _SMB_MACROS_H */
#endif
diff --git a/source/nsswitch/winbind_nss_solaris.c b/source/nsswitch/winbind_nss_solaris.c
index de8a63b90bf..e349acc2131 100644
--- a/source/nsswitch/winbind_nss_solaris.c
+++ b/source/nsswitch/winbind_nss_solaris.c
@@ -11,11 +11,10 @@
#include <string.h>
#include <pwd.h>
#include <syslog.h>
-#include <sys/syslog.h>
#include "includes.h"
#include "winbind_nss_config.h"
-#ifdef HAVE_NSS_COMMON_H
+#if defined(HAVE_NSS_COMMON_H) || defined(HPUX)
#undef NSS_DEBUG
@@ -117,7 +116,7 @@ _nss_winbind_getpwuid_solwrap(nss_backend_t* be, void* args)
static NSS_STATUS _nss_winbind_passwd_destr (nss_backend_t * be, void *args)
{
- free(be);
+ SAFE_FREE(be);
NSS_DEBUG("_nss_winbind_passwd_destr");
return NSS_STATUS_SUCCESS;
}
@@ -241,7 +240,7 @@ _nss_winbind_getgroupsbymember_solwrap(nss_backend_t* be, void* args)
static NSS_STATUS
_nss_winbind_group_destr (nss_backend_t* be, void* args)
{
- free(be);
+ SAFE_FREE(be);
NSS_DEBUG("_nss_winbind_group_destr");
return NSS_STATUS_SUCCESS;
}
@@ -274,6 +273,4 @@ _nss_winbind_group_constr (const char* db_name,
return be;
}
-#endif /* SUN_NSS */
-
-
+#endif /* defined(HAVE_NSS_COMMON_H) || defined(HPUX) */
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 1a76396d9c6..637260214ae 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -1,10 +1,10 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0
+ Version 3.0
Winbind daemon for ntdom nss module
- Copyright (C) Tim Potter 2000
+ Copyright (C) by Tim Potter 2000, 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,6 +35,7 @@ static int num_clients;
static BOOL reload_services_file(BOOL test)
{
BOOL ret;
+ pstring logfile;
if (lp_loaded()) {
pstring fname;
@@ -46,26 +47,82 @@ static BOOL reload_services_file(BOOL test)
}
}
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
+ lp_set_logfile(logfile);
reopen_logs();
+
ret = lp_load(servicesf,False,False,True);
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
+ lp_set_logfile(logfile);
reopen_logs();
load_interfaces();
return(ret);
}
-void winbindd_dump_status(void)
+#if DUMP_CORE
+
+/**************************************************************************** **
+ Prepare to dump a core file - carefully!
+ **************************************************************************** */
+
+static BOOL dump_core(void)
+{
+ char *p;
+ pstring dname;
+ pstrcpy( dname, lp_logfile() );
+ if ((p=strrchr(dname,'/')))
+ *p=0;
+ pstrcat( dname, "/corefiles" );
+ mkdir( dname, 0700 );
+ sys_chown( dname, getuid(), getgid() );
+ chmod( dname, 0700 );
+ if ( chdir(dname) )
+ return( False );
+ umask( ~(0700) );
+
+#ifdef HAVE_GETRLIMIT
+#ifdef RLIMIT_CORE
+ {
+ struct rlimit rlp;
+ getrlimit( RLIMIT_CORE, &rlp );
+ rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
+ setrlimit( RLIMIT_CORE, &rlp );
+ getrlimit( RLIMIT_CORE, &rlp );
+ DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
+ }
+#endif
+#endif
+
+ DEBUG(0,("Dumping core in %s\n",dname));
+ abort();
+ return( True );
+} /* dump_core */
+#endif
+
+/**************************************************************************** **
+ Handle a fault..
+ **************************************************************************** */
+
+static void fault_quit(void)
+{
+#if DUMP_CORE
+ dump_core();
+#endif
+}
+
+static void winbindd_status(void)
{
struct winbindd_cli_state *tmp;
- DEBUG(0, ("Global status for winbindd:\n"));
+ DEBUG(0, ("winbindd status:\n"));
/* Print client state information */
DEBUG(0, ("\t%d clients currently active\n", num_clients));
- if (DEBUGLEVEL >= 2) {
+ if (DEBUGLEVEL >= 2 && num_clients) {
DEBUG(2, ("\tclient list:\n"));
for(tmp = client_list; tmp; tmp = tmp->next) {
DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
@@ -77,16 +134,17 @@ void winbindd_dump_status(void)
/* Print winbindd status to log file */
-static void do_print_winbindd_status(void)
+static void print_winbindd_status(void)
{
- winbindd_dump_status();
- winbindd_idmap_dump_status();
- winbindd_cache_dump_status();
+ winbindd_status();
+ winbindd_idmap_status();
+ winbindd_cache_status();
+ winbindd_cm_status();
}
/* Flush client cache */
-static void do_flush_caches(void)
+static void flush_caches(void)
{
/* Clear cached user and group enumation info */
@@ -95,181 +153,199 @@ static void do_flush_caches(void)
/* Handle the signal by unlinking socket and exiting */
-static void termination_handler(int signum)
+static void terminate(void)
{
pstring path;
+ /* Close idmap. */
+ winbindd_idmap_close();
+
/* Remove socket file */
-
snprintf(path, sizeof(path), "%s/%s",
WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
unlink(path);
-
exit(0);
}
-static BOOL print_winbindd_status;
+static BOOL do_sigterm;
+
+static void termination_handler(int signum)
+{
+ do_sigterm = True;
+ sys_select_signal();
+}
+
+static BOOL do_sigusr1;
static void sigusr1_handler(int signum)
{
- BlockSignals(True, SIGUSR1);
- print_winbindd_status = True;
- BlockSignals(False, SIGUSR1);
+ do_sigusr1 = True;
+ sys_select_signal();
}
static BOOL do_sighup;
static void sighup_handler(int signum)
{
- BlockSignals(True, SIGHUP);
do_sighup = True;
- BlockSignals(False, SIGHUP);
+ sys_select_signal();
}
/* Create winbindd socket */
static int create_sock(void)
{
- struct sockaddr_un sunaddr;
- struct stat st;
- int sock;
- mode_t old_umask;
- pstring path;
-
- /* Create the socket directory or reuse the existing one */
-
- if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
-
- if (errno == ENOENT) {
-
- /* Create directory */
-
- if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) {
- DEBUG(0, ("error creating socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, strerror(errno)));
- return -1;
- }
-
+ struct sockaddr_un sunaddr;
+ struct stat st;
+ int sock;
+ mode_t old_umask;
+ pstring path;
+
+ /* Create the socket directory or reuse the existing one */
+
+ if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
+
+ if (errno == ENOENT) {
+
+ /* Create directory */
+
+ if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) {
+ DEBUG(0, ("error creating socket directory "
+ "%s: %s\n", WINBINDD_SOCKET_DIR,
+ strerror(errno)));
+ return -1;
+ }
+
+ } else {
+
+ DEBUG(0, ("lstat failed on socket directory %s: %s\n",
+ WINBINDD_SOCKET_DIR, strerror(errno)));
+ return -1;
+ }
+
} else {
-
- DEBUG(0, ("lstat failed on socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, strerror(errno)));
- return -1;
+
+ /* Check ownership and permission on existing directory */
+
+ if (!S_ISDIR(st.st_mode)) {
+ DEBUG(0, ("socket directory %s isn't a directory\n",
+ WINBINDD_SOCKET_DIR));
+ return -1;
+ }
+
+ if ((st.st_uid != sec_initial_uid()) ||
+ ((st.st_mode & 0777) != 0755)) {
+ DEBUG(0, ("invalid permissions on socket directory "
+ "%s\n", WINBINDD_SOCKET_DIR));
+ return -1;
+ }
}
-
- } else {
-
- /* Check ownership and permission on existing directory */
- if (!S_ISDIR(st.st_mode)) {
- DEBUG(0, ("socket directory %s isn't a directory\n",
- WINBINDD_SOCKET_DIR));
- return -1;
+ /* Create the socket file */
+
+ old_umask = umask(0);
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (sock == -1) {
+ perror("socket");
+ return -1;
}
- if ((st.st_mode & 0777) != 0755) {
- DEBUG(0, ("invalid permissions on socket directory %s\n",
- WINBINDD_SOCKET_DIR));
- return -1;
+ snprintf(path, sizeof(path), "%s/%s",
+ WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
+
+ unlink(path);
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_UNIX;
+ safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
+
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
+ DEBUG(0, ("bind failed on winbind socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ return -1;
}
- }
-
- /* Create the socket file */
-
- old_umask = umask(0);
-
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
- if (sock == -1) {
- perror("socket");
- return -1;
- }
-
- snprintf(path, sizeof(path), "%s/%s",
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
-
- unlink(path);
- memset(&sunaddr, 0, sizeof(sunaddr));
- sunaddr.sun_family = AF_UNIX;
- safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
-
- if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
- DEBUG(0, ("bind failed on winbind socket %s: %s\n",
- path,
- strerror(errno)));
- close(sock);
- return -1;
- }
-
- if (listen(sock, 5) == -1) {
- DEBUG(0, ("listen failed on winbind socket %s: %s\n",
- path,
- strerror(errno)));
- close(sock);
- return -1;
- }
-
- umask(old_umask);
-
- /* Success! */
-
- return sock;
+
+ if (listen(sock, 5) == -1) {
+ DEBUG(0, ("listen failed on winbind socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ return -1;
+ }
+
+ umask(old_umask);
+
+ /* Success! */
+
+ return sock;
}
struct dispatch_table {
enum winbindd_cmd cmd;
enum winbindd_result (*fn)(struct winbindd_cli_state *state);
+ char *winbindd_cmd_name;
};
static struct dispatch_table dispatch_table[] = {
/* User functions */
- { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user },
- { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid },
- { WINBINDD_SETPWENT, winbindd_setpwent },
- { WINBINDD_ENDPWENT, winbindd_endpwent },
- { WINBINDD_GETPWENT, winbindd_getpwent },
- { WINBINDD_GETGROUPS, winbindd_getgroups },
+ { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user, "GETPWNAM_FROM_USER" },
+ { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid, "GETPWNAM_FROM_UID" },
+
+ { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" },
+ { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" },
+ { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" },
+
+ { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" },
/* Group functions */
- { WINBINDD_GETGRNAM_FROM_GROUP, winbindd_getgrnam_from_group },
- { WINBINDD_GETGRNAM_FROM_GID, winbindd_getgrnam_from_gid },
- { WINBINDD_SETGRENT, winbindd_setgrent },
- { WINBINDD_ENDGRENT, winbindd_endgrent },
- { WINBINDD_GETGRENT, winbindd_getgrent },
+ { WINBINDD_GETGRNAM_FROM_GROUP, winbindd_getgrnam_from_group, "GETGRNAM_FROM_GROUP" },
+ { WINBINDD_GETGRNAM_FROM_GID, winbindd_getgrnam_from_gid, "GETGRNAM_FROM_GID" },
+ { WINBINDD_SETGRENT, winbindd_setgrent, "SETGRENT" },
+ { WINBINDD_ENDGRENT, winbindd_endgrent, "ENDGRENT" },
+ { WINBINDD_GETGRENT, winbindd_getgrent, "GETGRENT" },
/* PAM auth functions */
- { WINBINDD_PAM_AUTH, winbindd_pam_auth },
- { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok },
+ { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },
+ { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
+ { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
/* Enumeration functions */
- { WINBINDD_LIST_USERS, winbindd_list_users },
- { WINBINDD_LIST_GROUPS, winbindd_list_groups },
- { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains },
+ { WINBINDD_LIST_USERS, winbindd_list_users, "LIST_USERS" },
+ { WINBINDD_LIST_GROUPS, winbindd_list_groups, "LIST_GROUPS" },
+ { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains, "LIST_TRUSTDOM" },
/* SID related functions */
- { WINBINDD_LOOKUPSID, winbindd_lookupsid },
- { WINBINDD_LOOKUPNAME, winbindd_lookupname },
+ { WINBINDD_LOOKUPSID, winbindd_lookupsid, "LOOKUPSID" },
+ { WINBINDD_LOOKUPNAME, winbindd_lookupname, "LOOKUPNAME" },
- /* S*RS related functions */
+ /* Lookup related functions */
- { WINBINDD_SID_TO_UID, winbindd_sid_to_uid },
- { WINBINDD_SID_TO_GID, winbindd_sid_to_gid },
- { WINBINDD_GID_TO_SID, winbindd_gid_to_sid },
- { WINBINDD_UID_TO_SID, winbindd_uid_to_sid },
+ { WINBINDD_SID_TO_UID, winbindd_sid_to_uid, "SID_TO_UID" },
+ { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
+ { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
+ { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
/* Miscellaneous */
- { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct },
+ { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" },
+
+ /* WINS functions */
+
+ { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
+ { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
/* End of list */
- { WINBINDD_NUM_CMDS, NULL }
+ { WINBINDD_NUM_CMDS, NULL, "NONE" }
};
static void process_request(struct winbindd_cli_state *state)
@@ -279,7 +355,7 @@ static void process_request(struct winbindd_cli_state *state)
/* Free response data - we may be interrupted and receive another
command before being able to send this data off. */
- safe_free(state->response.extra_data);
+ SAFE_FREE(state->response.extra_data);
ZERO_STRUCT(state->response);
@@ -288,20 +364,21 @@ static void process_request(struct winbindd_cli_state *state)
/* Process command */
- if (!server_state.lsa_handle_open) return;
-
for (table = dispatch_table; table->fn; table++) {
if (state->request.cmd == table->cmd) {
+ DEBUG(10,("process_request: request fn %s\n", table->winbindd_cmd_name ));
state->response.result = table->fn(state);
break;
}
}
+ if (!table->fn)
+ DEBUG(10,("process_request: unknown request fn number %d\n", (int)state->request.cmd ));
+
/* In case extra data pointer is NULL */
- if (!state->response.extra_data) {
+ if (!state->response.extra_data)
state->response.length = sizeof(struct winbindd_response);
- }
}
/* Process a new connection by adding it to the client connection list */
@@ -316,21 +393,21 @@ static void new_connection(int accept_sock)
/* Accept connection */
len = sizeof(sunaddr);
- if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len))
- == -1) {
-
+
+ do {
+ sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len);
+ } while (sock == -1 && errno == EINTR);
+
+ if (sock == -1)
return;
- }
DEBUG(6,("accepted socket %d\n", sock));
/* Create new connection structure */
- if ((state = (struct winbindd_cli_state *)
- malloc(sizeof(*state))) == NULL) {
-
+ if ((state = (struct winbindd_cli_state *)
+ malloc(sizeof(*state))) == NULL)
return;
- }
ZERO_STRUCTP(state);
state->sock = sock;
@@ -361,12 +438,12 @@ static void remove_client(struct winbindd_cli_state *state)
/* We may have some extra data that was not freed if the
client was killed unexpectedly */
- safe_free(state->response.extra_data);
+ SAFE_FREE(state->response.extra_data);
/* Remove from list and free */
DLIST_REMOVE(client_list, state);
- free(state);
+ SAFE_FREE(state);
num_clients--;
}
}
@@ -395,9 +472,14 @@ static void client_read(struct winbindd_cli_state *state)
/* Read data */
- n = read(state->sock, state->read_buf_len + (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
+ do {
+ n = read(state->sock, state->read_buf_len + (char *)&state->request,
+ sizeof(state->request) - state->read_buf_len);
+ } while (n == -1 && errno == EINTR);
+ DEBUG(10,("client_read: read %d bytes. Need %d more for a full request.\n", n,
+ sizeof(state->request) - n - state->read_buf_len ));
+
/* Read failed, kill client */
if (n == -1 || n == 0) {
@@ -440,8 +522,12 @@ static void client_write(struct winbindd_cli_state *state)
state->write_buf_len;
}
- num_written = write(state->sock, data, state->write_buf_len);
+ do {
+ num_written = write(state->sock, data, state->write_buf_len);
+ } while (num_written == -1 && errno == EINTR);
+ DEBUG(10,("client_write: wrote %d bytes.\n", num_written ));
+
/* Write failed, kill cilent */
if (num_written == -1 || num_written == 0) {
@@ -452,8 +538,7 @@ static void client_write(struct winbindd_cli_state *state)
state->finished = True;
- safe_free(state->response.extra_data);
- state->response.extra_data = NULL;
+ SAFE_FREE(state->response.extra_data);
return;
}
@@ -470,11 +555,12 @@ static void client_write(struct winbindd_cli_state *state)
if (state->write_extra_data) {
- safe_free(state->response.extra_data);
- state->response.extra_data = NULL;
+ SAFE_FREE(state->response.extra_data);
state->write_extra_data = False;
+ DEBUG(10,("client_write: client_write: complete response written.\n"));
+
} else if (state->response.length >
sizeof(struct winbindd_response)) {
@@ -484,6 +570,8 @@ static void client_write(struct winbindd_cli_state *state)
state->response.length -
sizeof(struct winbindd_response);
+ DEBUG(10,("client_write: need to write %d extra data bytes.\n", (int)state->write_buf_len));
+
state->write_extra_data = True;
}
}
@@ -508,10 +596,6 @@ static void process_loop(int accept_sock)
lp_talloc_free();
- /* Do any connection establishment that is needed */
-
- establish_connections(False); /* Honour timeout */
-
/* Initialise fd lists for select() */
FD_ZERO(&r_fds);
@@ -540,51 +624,28 @@ static void process_loop(int accept_sock)
/* Select requires we know the highest fd used */
- if (state->sock > maxfd) maxfd = state->sock;
+ if (state->sock > maxfd)
+ maxfd = state->sock;
/* Add fd for reading */
- if (state->read_buf_len != sizeof(state->request)) {
+ if (state->read_buf_len != sizeof(state->request))
FD_SET(state->sock, &r_fds);
- }
/* Add fd for writing */
- if (state->write_buf_len) {
+ if (state->write_buf_len)
FD_SET(state->sock, &w_fds);
- }
state = state->next;
}
- /* Check signal handling things */
-
- if (do_sighup) {
-
- /* Flush winbindd cache */
-
- do_flush_caches();
- reload_services_file(True);
-
- /* Close and re-open all connections. This will also
- refresh the trusted domains list */
-
- winbindd_kill_all_connections();
- establish_connections(True); /* Force re-establish */
-
- do_sighup = False;
- }
-
- if (print_winbindd_status) {
- do_print_winbindd_status();
- print_winbindd_status = False;
- }
-
/* Call select */
- selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
+ selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
- if (selret == 0) continue;
+ if (selret == 0)
+ continue;
if ((selret == -1 && errno != EINTR) || selret == 0) {
@@ -598,9 +659,8 @@ static void process_loop(int accept_sock)
if (selret > 0) {
- if (FD_ISSET(accept_sock, &r_fds)) {
+ if (FD_ISSET(accept_sock, &r_fds))
new_connection(accept_sock);
- }
/* Process activity on client connections */
@@ -613,7 +673,31 @@ static void process_loop(int accept_sock)
/* Read data */
client_read(state);
-
+
+#if 0
+ /* JRA - currently there's no length field in the request... */
+ /*
+ * If we have the start of a
+ * packet, then check the
+ * length field to make sure
+ * the client's not talking
+ * Mock Swedish.
+ */
+
+ if (state->read_buf_len >= sizeof(int)
+ && *(int *) state->buf != sizeof(state->request)) {
+
+ struct winbindd_cli_state *rem_state = state;
+
+ DEBUG(0,("process_loop: Invalid request size (%d) send, should be (%d)\n",
+ *(int *) rem_state->buf, sizeof(rem_state->request) ));
+
+ state = state_next;
+ remove_client(rem_state);
+ continue;
+ }
+#endif
+
/* A request packet might be
complete */
@@ -625,11 +709,29 @@ static void process_loop(int accept_sock)
/* Data available for writing */
- if (FD_ISSET(state->sock, &w_fds)) {
+ if (FD_ISSET(state->sock, &w_fds))
client_write(state);
- }
}
}
+
+ /* Check signal handling things */
+
+ if (do_sigterm)
+ terminate();
+
+ if (do_sighup) {
+
+ /* Flush winbindd cache */
+
+ flush_caches();
+ reload_services_file(True);
+ do_sighup = False;
+ }
+
+ if (do_sigusr1) {
+ print_winbindd_status();
+ do_sigusr1 = False;
+ }
}
}
@@ -640,16 +742,31 @@ struct winbindd_state server_state; /* Server state information */
int main(int argc, char **argv)
{
extern pstring global_myname;
- extern pstring debugf;
+ extern fstring global_myworkgroup;
+ extern BOOL append_log;
+ pstring logfile;
int accept_sock;
BOOL interactive = False;
int opt, new_debuglevel = -1;
- extern fstring global_myworkgroup;
+
+ /* glibc (?) likes to print "User defined signal 1" and exit if a
+ SIGUSR1 is received before a handler is installed */
+
+ CatchSignal(SIGUSR1, SIG_IGN);
+
+ TimeInit();
+
+ charset_initialise(); /* For *&#^%'s sake don't remove this */
+
+ fault_setup((void (*)(void *))fault_quit );
+
+ /* Initialise for running in non-root mode */
sec_init();
/* Set environment variable so we don't recursively call ourselves.
This may also be useful interactively. */
+
SETENV(WINBINDD_DONT_ENV, "1", 1);
/* Initialise samba/rpc client stuff */
@@ -657,7 +774,7 @@ int main(int argc, char **argv)
while ((opt = getopt(argc, argv, "id:s:")) != EOF) {
switch (opt) {
- /* Don't become a daemon */
+ /* Don't become a daemon */
case 'i':
interactive = True;
@@ -681,54 +798,73 @@ int main(int argc, char **argv)
}
}
- snprintf(debugf, sizeof(debugf), "%s/log.winbindd", LOGFILEBASE);
+
+ /* Append to log file by default as we are a single process daemon
+ program. */
+
+ append_log = True;
+
+ snprintf(logfile, sizeof(logfile), "%s/log.winbindd", LOGFILEBASE);
+ lp_set_logfile(logfile);
setup_logging("winbindd", interactive);
reopen_logs();
+ DEBUG(1, ("winbindd version %s started.\n", VERSION ) );
+ DEBUGADD( 1, ( "Copyright The Samba Team 2000-2001\n" ) );
+
+ if (!reload_services_file(False)) {
+ DEBUG(0, ("error opening config file\n"));
+ exit(1);
+ }
+
+ codepage_initialise(lp_client_code_page());
+
+ /* Setup names. */
if (!*global_myname) {
char *p;
fstrcpy(global_myname, myhostname());
p = strchr(global_myname, '.');
- if (p) {
+ if (p)
*p = 0;
- }
}
- TimeInit();
- charset_initialise();
-
- if (!reload_services_file(False)) {
- DEBUG(0, ("error opening config file\n"));
- exit(1);
- }
+ fstrcpy(global_myworkgroup, lp_workgroup());
- if (new_debuglevel != -1) {
+ if (new_debuglevel != -1)
DEBUGLEVEL = new_debuglevel;
- }
-
- codepage_initialise(lp_client_code_page());
- fstrcpy(global_myworkgroup, lp_workgroup());
- if (!interactive) {
+ if (!interactive)
become_daemon();
- }
+
+#if HAVE_SETPGID
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (interactive)
+ setpgid( (pid_t)0, (pid_t)0);
+#endif
load_interfaces();
secrets_init();
+ /* Get list of domains we look up requests for. This includes the
+ domain which we are a member of as well as any trusted
+ domains. */
+
+ get_domain_info();
+
ZERO_STRUCT(server_state);
/* Winbind daemon initialisation */
- if (!winbindd_param_init()) {
+ if (!winbindd_param_init())
return 1;
- }
- if (!winbindd_idmap_init()) {
+ if (!winbindd_idmap_init())
return 1;
- }
winbindd_cache_init();
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index f7e86a8a435..5d1b43527bd 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -30,10 +30,6 @@
#include "winbindd_nss.h"
-/* Naughty global stuff */
-
-extern int DEBUGLEVEL;
-
/* Client state structure */
struct winbindd_cli_state {
@@ -59,6 +55,7 @@ struct getent_state {
uint32 grp_query_start_ndx;
BOOL got_all_sam_entries, got_sam_entries;
struct winbindd_domain *domain;
+ POLICY_HND dom_pol; /* Cached SAMR domain handle. */
};
/* Storage for cached getpwent() user entries */
@@ -72,17 +69,11 @@ struct getpwent_user {
/* Server state structure */
struct winbindd_state {
- /* Netbios name of PDC */
- fstring controller;
-
+
/* User and group id pool */
+
uid_t uid_low, uid_high; /* Range of uids to allocate */
gid_t gid_low, gid_high; /* Range of gids to allocate */
-
- /* Cached handle to lsa pipe */
- CLI_POLICY_HND lsa_handle;
- BOOL lsa_handle_open;
- BOOL pwdb_initialised;
};
extern struct winbindd_state server_state; /* Server information */
@@ -90,26 +81,20 @@ extern struct winbindd_state server_state; /* Server information */
/* Structures to hold per domain information */
struct winbindd_domain {
-
- /* Domain information */
-
- fstring name; /* Domain name */
- fstring controller; /* NetBIOS name of DC */
-
+ fstring name; /* Domain name */
DOM_SID sid; /* SID for this domain */
- BOOL got_domain_info; /* Got controller and sid */
-
- /* Cached handles to samr pipe */
-
- CLI_POLICY_HND sam_handle, sam_dom_handle;
- BOOL sam_handle_open, sam_dom_handle_open;
- time_t last_check;
-
struct winbindd_domain *prev, *next; /* Linked list info */
};
extern struct winbindd_domain *domain_list; /* List of domains we know */
+/* Used to glue a policy handle and cli_state together */
+
+typedef struct {
+ struct cli_state *cli;
+ POLICY_HND pol;
+} CLI_POLICY_HND;
+
#include "winbindd_proto.h"
#include "rpc_parse.h"
@@ -132,4 +117,9 @@ extern struct winbindd_domain *domain_list; /* List of domains we know */
#define SETENV(name, value, overwrite) ;
#endif
+/* Authenticated user info is stored in secrets.tdb under these keys */
+
+#define SECRETS_AUTH_USER "SECRETS/AUTH_USER"
+#define SECRETS_AUTH_PASSWORD "SECRETS/AUTH_PASSWORD"
+
#endif /* _WINBINDD_H */
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 07b1cab5830..8ad5bc2e7d8 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -25,6 +25,8 @@
#define CACHE_TYPE_USER "USR"
#define CACHE_TYPE_GROUP "GRP"
+#define CACHE_TYPE_NAME "NAM" /* Stores mapping from SID to name. */
+#define CACHE_TYPE_SID "SID" /* Stores mapping from name to SID. */
/* Initialise caching system */
@@ -41,72 +43,132 @@ void winbindd_cache_init(void)
if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0,
TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
- 0600))) {
- DEBUG(0, ("Unable to open tdb cache - user and group caching "
- "disabled\n"));
+ 0600)))
+ DEBUG(0, ("Unable to open tdb cache - user and group caching disabled\n"));
+}
+
+/* find the sequence number for a domain */
+
+static uint32 domain_sequence_number(struct winbindd_domain *domain)
+{
+ TALLOC_CTX *mem_ctx;
+ CLI_POLICY_HND *hnd;
+ SAM_UNK_CTR ctr;
+ uint16 switch_value = 2;
+ NTSTATUS result;
+ uint32 seqnum = DOM_SEQUENCE_NONE;
+ POLICY_HND dom_pol;
+ BOOL got_dom_pol = False;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+
+ if (!(mem_ctx = talloc_init()))
+ return DOM_SEQUENCE_NONE;
+
+ /* Get sam handle */
+
+ if (!(hnd = cm_get_sam_handle(domain->name)))
+ goto done;
+
+ /* Get domain handle */
+
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ des_access, &domain->sid, &dom_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ got_dom_pol = True;
+
+ /* Query domain info */
+
+ result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
+ switch_value, &ctr);
+
+ if (NT_STATUS_IS_OK(result)) {
+ seqnum = ctr.info.inf2.seq_num;
+ DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
+ } else {
+ DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
+ (unsigned)seqnum, domain->name ));
}
+
+ done:
+
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
+
+ talloc_destroy(mem_ctx);
+
+ return seqnum;
}
/* get the domain sequence number, possibly re-fetching */
-static uint32 cached_sequence_number(char *domain_name)
+
+static uint32 cached_sequence_number(struct winbindd_domain *domain)
{
fstring keystr;
TDB_DATA dbuf;
struct cache_rec rec;
time_t t = time(NULL);
- snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain_name);
+ snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain->name);
dbuf = tdb_fetch_by_string(cache_tdb, keystr);
- if (!dbuf.dptr || dbuf.dsize != sizeof(rec)) {
+
+ if (!dbuf.dptr || dbuf.dsize != sizeof(rec))
goto refetch;
- }
+
memcpy(&rec, dbuf.dptr, sizeof(rec));
- free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
if (t < (rec.mod_time + lp_winbind_cache_time())) {
DEBUG(3,("cached sequence number for %s is %u\n",
- domain_name, (unsigned)rec.seq_num));
+ domain->name, (unsigned)rec.seq_num));
return rec.seq_num;
}
refetch:
- rec.seq_num = domain_sequence_number(domain_name);
+ rec.seq_num = domain_sequence_number(domain);
rec.mod_time = t;
+
tdb_store_by_string(cache_tdb, keystr, &rec, sizeof(rec));
return rec.seq_num;
}
/* Check whether a seq_num for a cached item has expired */
-static BOOL cache_domain_expired(char *domain_name, uint32 seq_num)
+static BOOL cache_domain_expired(struct winbindd_domain *domain,
+ uint32 seq_num)
{
- if (cached_sequence_number(domain_name) != seq_num) {
- DEBUG(3,("seq %u for %s has expired\n", (unsigned)seq_num,
- domain_name));
+ uint32 cache_seq = cached_sequence_number(domain);
+ if (cache_seq != seq_num) {
+ DEBUG(3,("seq %u for %s has expired (not == %u)\n", (unsigned)seq_num,
+ domain->name, (unsigned)cache_seq ));
return True;
}
+
return False;
}
-static void set_cache_sequence_number(char *domain_name, char *cache_type,
- char *subkey)
+static void set_cache_sequence_number(struct winbindd_domain *domain,
+ char *cache_type, char *subkey)
{
fstring keystr;
snprintf(keystr, sizeof(keystr),"CACHESEQ %s/%s/%s",
- domain_name, cache_type, subkey?subkey:"");
+ domain->name, cache_type, subkey?subkey:"");
- tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain_name));
+ tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain));
}
-static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
- char *subkey)
+static uint32 get_cache_sequence_number(struct winbindd_domain *domain,
+ char *cache_type, char *subkey)
{
fstring keystr;
uint32 seq_num;
snprintf(keystr, sizeof(keystr), "CACHESEQ %s/%s/%s",
- domain_name, cache_type, subkey?subkey:"");
+ domain->name, cache_type, subkey ? subkey : "");
+
seq_num = (uint32)tdb_fetch_int(cache_tdb, keystr);
DEBUG(3,("%s is %u\n", keystr, (unsigned)seq_num));
@@ -116,33 +178,38 @@ static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
/* Fill the user or group cache with supplied data */
-static void store_cache(char *domain_name, char *cache_type,
+static void store_cache(struct winbindd_domain *domain, char *cache_type,
void *sam_entries, int buflen)
{
fstring keystr;
- if (lp_winbind_cache_time() == 0) return;
+ if (lp_winbind_cache_time() == 0)
+ return;
/* Error check */
- if (!sam_entries || buflen == 0) return;
+
+ if (!sam_entries || buflen == 0)
+ return;
/* Store data as a mega-huge chunk in the tdb */
+
snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
- domain_name);
+ domain->name);
tdb_store_by_string(cache_tdb, keystr, sam_entries, buflen);
/* Stamp cache with current seq number */
- set_cache_sequence_number(domain_name, cache_type, NULL);
+
+ set_cache_sequence_number(domain, cache_type, NULL);
}
/* Fill the user cache with supplied data */
-void winbindd_store_user_cache(char *domain,
+void winbindd_store_user_cache(struct winbindd_domain *domain,
struct getpwent_user *sam_entries,
int num_sam_entries)
{
- DEBUG(3, ("storing user cache %s/%d entries\n", domain,
+ DEBUG(3, ("storing user cache %s/%d entries\n", domain->name,
num_sam_entries));
store_cache(domain, CACHE_TYPE_USER, sam_entries,
@@ -151,146 +218,185 @@ void winbindd_store_user_cache(char *domain,
/* Fill the group cache with supplied data */
-void winbindd_store_group_cache(char *domain,
+void winbindd_store_group_cache(struct winbindd_domain *domain,
struct acct_info *sam_entries,
int num_sam_entries)
{
- DEBUG(0, ("storing group cache %s/%d entries\n", domain,
+ DEBUG(0, ("storing group cache %s/%d entries\n", domain->name,
num_sam_entries));
store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
num_sam_entries * sizeof(struct acct_info));
}
-static void store_cache_entry(char *domain, char *cache_type, char *name,
- void *buf, int len)
+static void store_cache_entry(struct winbindd_domain *domain, char *cache_type,
+ char *name, void *buf, int len)
{
fstring keystr;
/* Create key for store */
- snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type,
+ domain->name, name);
/* Store it */
+
tdb_store_by_string(cache_tdb, keystr, buf, len);
}
+/* Fill a name cache entry */
+
+void winbindd_store_name_cache_entry(struct winbindd_domain *domain,
+ char *sid, struct winbindd_name *name)
+{
+ if (lp_winbind_cache_time() == 0)
+ return;
+
+ store_cache_entry(domain, CACHE_TYPE_NAME, sid, name,
+ sizeof(struct winbindd_name));
+
+ set_cache_sequence_number(domain, CACHE_TYPE_NAME, sid);
+}
+
+/* Fill a SID cache entry */
+
+void winbindd_store_sid_cache_entry(struct winbindd_domain *domain,
+ char *name, struct winbindd_sid *sid)
+{
+ if (lp_winbind_cache_time() == 0)
+ return;
+
+ store_cache_entry(domain, CACHE_TYPE_SID, name, sid,
+ sizeof(struct winbindd_sid));
+
+ set_cache_sequence_number(domain, CACHE_TYPE_SID, name);
+}
+
/* Fill a user info cache entry */
-void winbindd_store_user_cache_entry(char *domain, char *user_name,
- struct winbindd_pw *pw)
+void winbindd_store_user_cache_entry(struct winbindd_domain *domain,
+ char *user_name, struct winbindd_pw *pw)
{
- if (lp_winbind_cache_time() == 0) return;
+ if (lp_winbind_cache_time() == 0)
+ return;
- store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
- sizeof(struct winbindd_pw));
+ store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
+ sizeof(struct winbindd_pw));
set_cache_sequence_number(domain, CACHE_TYPE_USER, user_name);
}
/* Fill a user uid cache entry */
-void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
+void winbindd_store_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
struct winbindd_pw *pw)
{
- fstring uidstr;
+ fstring uidstr;
- if (lp_winbind_cache_time() == 0) return;
+ if (lp_winbind_cache_time() == 0)
+ return;
- snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
+ snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
- DEBUG(3, ("storing uid cache entry %s/%s\n", domain, uidstr));
+ DEBUG(3, ("storing uid cache entry %s/%s\n", domain->name, uidstr));
- store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
- sizeof(struct winbindd_pw));
+ store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
+ sizeof(struct winbindd_pw));
- set_cache_sequence_number(domain, CACHE_TYPE_USER, uidstr);
+ set_cache_sequence_number(domain, CACHE_TYPE_USER, uidstr);
}
/* Fill a group info cache entry */
-void winbindd_store_group_cache_entry(char *domain, char *group_name,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len)
+
+void winbindd_store_group_cache_entry(struct winbindd_domain *domain,
+ char *group_name, struct winbindd_gr *gr,
+ void *extra_data, int extra_data_len)
{
- fstring keystr;
+ fstring keystr;
+
+ if (lp_winbind_cache_time() == 0)
+ return;
- if (lp_winbind_cache_time() == 0) return;
+ DEBUG(3, ("storing group cache entry %s/%s\n", domain->name,
+ group_name));
- DEBUG(3, ("storing group cache entry %s/%s\n", domain, group_name));
+ /* Fill group data */
- /* Fill group data */
+ store_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr,
+ sizeof(struct winbindd_gr));
- store_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr,
- sizeof(struct winbindd_gr));
+ /* Fill extra data */
- /* Fill extra data */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain->name, group_name);
- snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
- domain, group_name);
- tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
+ tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, group_name);
}
/* Fill a group info cache entry */
-void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
+void winbindd_store_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
struct winbindd_gr *gr, void *extra_data,
int extra_data_len)
{
- fstring keystr;
+ fstring keystr;
fstring gidstr;
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
- if (lp_winbind_cache_time() == 0) return;
+ if (lp_winbind_cache_time() == 0)
+ return;
- DEBUG(3, ("storing gid cache entry %s/%s\n", domain, gidstr));
+ DEBUG(3, ("storing gid cache entry %s/%s\n", domain->name, gidstr));
- /* Fill group data */
+ /* Fill group data */
- store_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr,
- sizeof(struct winbindd_gr));
+ store_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr,
+ sizeof(struct winbindd_gr));
- /* Fill extra data */
+ /* Fill extra data */
- snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
- domain, gidstr);
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain->name, gidstr);
- tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
+ tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, gidstr);
}
/* Fetch some cached user or group data */
-static BOOL fetch_cache(char *domain_name, char *cache_type,
+
+static BOOL fetch_cache(struct winbindd_domain *domain, char *cache_type,
void **sam_entries, int *buflen)
{
- TDB_DATA data;
- fstring keystr;
+ TDB_DATA data;
+ fstring keystr;
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
/* Parameter check */
- if (!sam_entries || !buflen) {
+
+ if (!sam_entries || !buflen)
return False;
- }
/* Check cache data is current */
- if (cache_domain_expired(domain_name,
- get_cache_sequence_number(domain_name,
- cache_type,
- NULL))) {
+
+ if (cache_domain_expired(domain, get_cache_sequence_number(domain, cache_type, NULL)))
return False;
- }
- /* Create key */
- snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
- domain_name);
+ /* Create key */
+
+ snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type, domain->name);
- /* Fetch cache information */
+ /* Fetch cache information */
+
data = tdb_fetch_by_string(cache_tdb, keystr);
- if (!data.dptr) return False;
+ if (!data.dptr)
+ return False;
/* Copy across cached data. We can save a memcpy() by directly
assigning the data.dptr to the sam_entries pointer. It will
@@ -305,20 +411,20 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
/* Return cached entries for a domain. Return false if there are no cached
entries, or the cached information has expired for the domain. */
-BOOL winbindd_fetch_user_cache(char *domain_name,
+BOOL winbindd_fetch_user_cache(struct winbindd_domain *domain,
struct getpwent_user **sam_entries,
int *num_entries)
{
BOOL result;
int buflen;
- result = fetch_cache(domain_name, CACHE_TYPE_USER,
+ result = fetch_cache(domain, CACHE_TYPE_USER,
(void **)sam_entries, &buflen);
*num_entries = buflen / sizeof(struct getpwent_user);
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
- domain_name));
+ domain->name));
return result;
}
@@ -326,112 +432,169 @@ BOOL winbindd_fetch_user_cache(char *domain_name,
/* Return cached entries for a domain. Return false if there are no cached
entries, or the cached information has expired for the domain. */
-BOOL winbindd_fetch_group_cache(char *domain_name,
+BOOL winbindd_fetch_group_cache(struct winbindd_domain *domain,
struct acct_info **sam_entries,
int *num_entries)
{
BOOL result;
int buflen;
- result = fetch_cache(domain_name, CACHE_TYPE_GROUP,
+ result = fetch_cache(domain, CACHE_TYPE_GROUP,
(void **)sam_entries, &buflen);
*num_entries = buflen / sizeof(struct acct_info);
DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
- domain_name));
+ domain->name));
return result;
}
-static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name,
- void *buf, int len)
+static BOOL fetch_cache_entry(struct winbindd_domain *domain,
+ char *cache_type, char *name, void *buf, int len)
{
TDB_DATA data;
fstring keystr;
/* Create key for lookup */
- snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain->name, name);
/* Look up cache entry */
+
data = tdb_fetch_by_string(cache_tdb, keystr);
- if (!data.dptr) return False;
+
+ if (!data.dptr)
+ return False;
- /* Copy found entry into buffer */
- memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
- free(data.dptr);
+ /* Copy found entry into buffer */
+
+ memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
+ SAFE_FREE(data.dptr);
+
return True;
}
+/* Fetch an individual SID cache entry */
+
+BOOL winbindd_fetch_sid_cache_entry(struct winbindd_domain *domain,
+ char *name, struct winbindd_sid *sid)
+{
+ uint32 seq_num;
+
+ if (lp_winbind_cache_time() == 0)
+ return False;
+
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_SID, name);
+
+ if (cache_domain_expired(domain, seq_num))
+ return False;
+
+ return fetch_cache_entry(domain, CACHE_TYPE_SID, name, sid,
+ sizeof(struct winbindd_sid));
+}
+
+/* Fetch an individual name cache entry */
+
+BOOL winbindd_fetch_name_cache_entry(struct winbindd_domain *domain,
+ char *sid, struct winbindd_name *name)
+{
+ uint32 seq_num;
+
+ if (lp_winbind_cache_time() == 0)
+ return False;
+
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_NAME, sid);
+
+ if (cache_domain_expired(domain, seq_num))
+ return False;
+
+ return fetch_cache_entry(domain, CACHE_TYPE_NAME, sid, name,
+ sizeof(struct winbindd_name));
+}
+
/* Fetch an individual user cache entry */
-BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
- struct winbindd_pw *pw)
+
+BOOL winbindd_fetch_user_cache_entry(struct winbindd_domain *domain,
+ char *user, struct winbindd_pw *pw)
{
uint32 seq_num;
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
- user);
- if (cache_domain_expired(domain_name, seq_num)) return False;
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_USER, user);
- return fetch_cache_entry(domain_name, CACHE_TYPE_USER, user, pw,
- sizeof(struct winbindd_pw));
+ if (cache_domain_expired(domain, seq_num))
+ return False;
+
+ return fetch_cache_entry(domain, CACHE_TYPE_USER, user, pw,
+ sizeof(struct winbindd_pw));
}
/* Fetch an individual uid cache entry */
-BOOL winbindd_fetch_uid_cache_entry(char *domain_name, uid_t uid,
+
+BOOL winbindd_fetch_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
struct winbindd_pw *pw)
{
fstring uidstr;
uint32 seq_num;
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
- uidstr);
- if (cache_domain_expired(domain_name, seq_num)) return False;
- return fetch_cache_entry(domain_name, CACHE_TYPE_USER, uidstr, pw,
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_USER, uidstr);
+
+ if (cache_domain_expired(domain, seq_num))
+ return False;
+
+ return fetch_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
sizeof(struct winbindd_pw));
}
/* Fetch an individual group cache entry. This function differs from the
user cache code as we need to store the group membership data. */
-BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
- struct winbindd_gr *gr,
+BOOL winbindd_fetch_group_cache_entry(struct winbindd_domain *domain,
+ char *group, struct winbindd_gr *gr,
void **extra_data, int *extra_data_len)
{
- TDB_DATA data;
- fstring keystr;
+ TDB_DATA data;
+ fstring keystr;
uint32 seq_num;
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
- group);
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_GROUP, group);
- if (cache_domain_expired(domain_name, seq_num)) return False;
+ if (cache_domain_expired(domain, seq_num))
+ return False;
- /* Fetch group data */
- if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr,
- sizeof(struct winbindd_gr))) {
+ /* Fetch group data */
+
+ if (!fetch_cache_entry(domain, CACHE_TYPE_GROUP, group, gr, sizeof(struct winbindd_gr)))
return False;
- }
- /* Fetch extra data */
- snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
- domain_name, group);
+ /* Fetch extra data */
- data = tdb_fetch_by_string(cache_tdb, keystr);
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain->name, group);
- if (!data.dptr) return False;
+ data = tdb_fetch_by_string(cache_tdb, keystr);
+
+ if (!data.dptr)
+ return False;
/* Extra data freed when data has been sent */
- if (extra_data) *extra_data = data.dptr;
- if (extra_data_len) *extra_data_len = data.dsize;
+
+ if (extra_data)
+ *extra_data = data.dptr;
+
+ if (extra_data_len)
+ *extra_data_len = data.dsize;
return True;
}
@@ -440,44 +603,54 @@ BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
/* Fetch an individual gid cache entry. This function differs from the
user cache code as we need to store the group membership data. */
-BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
+BOOL winbindd_fetch_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
struct winbindd_gr *gr,
void **extra_data, int *extra_data_len)
{
- TDB_DATA data;
- fstring keystr;
+ TDB_DATA data;
+ fstring keystr;
fstring gidstr;
uint32 seq_num;
snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
- if (lp_winbind_cache_time() == 0) return False;
+ if (lp_winbind_cache_time() == 0)
+ return False;
+
+ seq_num = get_cache_sequence_number(domain, CACHE_TYPE_GROUP, gidstr);
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
- gidstr);
+ if (cache_domain_expired(domain, seq_num))
+ return False;
- if (cache_domain_expired(domain_name, seq_num)) return False;
+ /* Fetch group data */
- /* Fetch group data */
- if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP,
- gidstr, gr, sizeof(struct winbindd_gr))) {
+ if (!fetch_cache_entry(domain, CACHE_TYPE_GROUP,
+ gidstr, gr, sizeof(struct winbindd_gr)))
return False;
- }
- /* Fetch extra data */
- snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
- domain_name, gidstr);
- data = tdb_fetch_by_string(cache_tdb, keystr);
- if (!data.dptr) return False;
+ /* Fetch extra data */
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain->name, gidstr);
+
+ data = tdb_fetch_by_string(cache_tdb, keystr);
+
+ if (!data.dptr)
+ return False;
/* Extra data freed when data has been sent */
- if (extra_data) *extra_data = data.dptr;
- if (extra_data_len) *extra_data_len = data.dsize;
+
+ if (extra_data)
+ *extra_data = data.dptr;
+
+ if (extra_data_len)
+ *extra_data_len = data.dsize;
return True;
}
/* Flush cache data - easiest to just reopen the tdb */
+
void winbindd_flush_cache(void)
{
tdb_close(cache_tdb);
@@ -485,6 +658,7 @@ void winbindd_flush_cache(void)
}
/* Print cache status information */
-void winbindd_cache_dump_status(void)
+
+void winbindd_cache_status(void)
{
}
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 332e15e0e63..ac5534780b7 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -1,10 +1,11 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0
+ Version 2.2.
Winbind daemon for ntdom nss module
Copyright (C) Tim Potter 2000
+ Copyright (C) Jeremy Allison 2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,6 +24,12 @@
#include "winbindd.h"
+/***************************************************************
+ Empty static struct for negative caching.
+****************************************************************/
+
+static struct winbindd_gr negative_gr_cache_entry;
+
/* Fill a grent structure from various other information */
static BOOL fill_grent(struct winbindd_gr *gr, char *gr_name,
@@ -48,13 +55,15 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
int *num_gr_mem, char **gr_mem, int *gr_mem_len)
{
uint32 *rid_mem = NULL, num_names = 0;
- enum SID_NAME_USE *name_types = NULL;
+ uint32 *name_types = NULL;
int buf_len, buf_ndx, i;
char **names = NULL, *buf;
BOOL result = False;
-
- if (!num_gr_mem || !gr_mem || !gr_mem_len) return False;
-
+ TALLOC_CTX *mem_ctx;
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
/* Initialise group membership information */
DEBUG(10, ("fill_grent_mem(): group %s rid 0x%x\n",
@@ -65,28 +74,27 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
if (group_name_type != SID_NAME_DOM_GRP) {
DEBUG(1, ("fill_grent_mem(): rid %d in domain %s isn't a "
"domain group\n", group_rid, domain->name));
- return False;
+ goto done;
}
/* Lookup group members */
- if (!winbindd_lookup_groupmem(domain, group_rid, &num_names,
+ if (!winbindd_lookup_groupmem(domain, mem_ctx, group_rid, &num_names,
&rid_mem, &names, &name_types)) {
DEBUG(1, ("fill_grent_mem(): could not lookup membership "
"for group rid %d in domain %s\n",
group_rid, domain->name));
- return False;
+ goto done;
}
DEBUG(10, ("fill_grent_mem(): looked up %d names\n", num_names));
if (DEBUGLEVEL >= 10) {
- for (i = 0; i < num_names; i++) {
+ for (i = 0; i < num_names; i++)
DEBUG(10, ("\t%20s %x %d\n", names[i], rid_mem[i],
name_types[i]));
- }
}
/* Add members to list */
@@ -103,9 +111,12 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
the_name = names[i];
- DEBUG(10, ("fill_grent_mem(): processing name %s\n", the_name));
+ DEBUG(10, ("fill_grent_mem(): processing name %s\n",
+ the_name));
- /* Only add domain users */
+ /* FIXME: need to cope with groups within groups. These
+ occur in Universal groups on a Windows 2000 native mode
+ server. */
if (name_types[i] != SID_NAME_USER) {
DEBUG(3, ("fill_grent_mem(): name %s isn't a domain "
@@ -151,7 +162,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
if (!(buf = malloc(buf_len))) {
DEBUG(1, ("fill_grent_mem(): out of memory\n"));
result = False;
- goto cleanup;
+ goto done;
}
memset(buf, 0, buf_len);
goto again;
@@ -164,19 +175,14 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
*gr_mem = buf;
*gr_mem_len = buf_len;
- DEBUG(10, ("fill_grent_mem(): num_mem = %d, len = %d, mem = %s\n", *num_gr_mem,
- buf_len, buf));
+ DEBUG(10, ("fill_grent_mem(): num_mem = %d, len = %d, mem = %s\n",
+ *num_gr_mem, buf_len, num_gr_mem ? buf : "NULL"));
result = True;
- cleanup:
-
- /* Free memory allocated in winbindd_lookup_groupmem() */
-
- safe_free(name_types);
- safe_free(rid_mem);
-
- free_char_array(num_names, names);
+done:
+
+ talloc_destroy(mem_ctx);
DEBUG(10, ("fill_grent_mem(): returning %d\n", result));
@@ -185,8 +191,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
/* Return a group structure from a group name */
-enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
- *state)
+enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state)
{
DOM_SID group_sid;
struct winbindd_domain *domain;
@@ -205,14 +210,8 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
memset(name_group, 0, sizeof(fstring));
tmp = state->request.data.groupname;
- parse_domain_user(tmp, name_domain, name_group);
-
- /* Reject names that don't have a domain - i.e name_domain contains
- the entire name. */
-
- if (strequal(name_group, "")) {
+ if (!parse_domain_user(tmp, name_domain, name_group))
return WINBINDD_ERROR;
- }
/* Get info for the domain */
@@ -222,16 +221,19 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
- }
-
/* Check for cached group entry */
- if (winbindd_fetch_group_cache_entry(name_domain, name_group,
+ if (winbindd_fetch_group_cache_entry(domain, name_group,
&state->response.data.gr,
&state->response.extra_data,
&extra_data_len)) {
+
+ /* Check if this is a negative cache entry. */
+
+ if (memcmp(&negative_gr_cache_entry, &state->response.data.gr,
+ sizeof(state->response.data.gr)) == 0)
+ return WINBINDD_ERROR;
+
state->response.length += extra_data_len;
return WINBINDD_OK;
}
@@ -243,12 +245,20 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
if (!winbindd_lookup_sid_by_name(name, &group_sid, &name_type)) {
DEBUG(1, ("group %s in domain %s does not exist\n",
name_group, name_domain));
+
+ winbindd_store_group_cache_entry(domain, name_group,
+ &negative_gr_cache_entry, NULL, 0);
+
return WINBINDD_ERROR;
}
if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
DEBUG(1, ("from_group: name '%s' is not a local or domain "
"group: %d\n", name_group, name_type));
+
+ winbindd_store_group_cache_entry(domain, name_group,
+ &negative_gr_cache_entry, NULL, 0);
+
return WINBINDD_ERROR;
}
@@ -258,6 +268,10 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
DEBUG(1, ("error sursing unix gid for sid\n"));
+
+ winbindd_store_group_cache_entry(domain, name_group,
+ &negative_gr_cache_entry, NULL, 0);
+
return WINBINDD_ERROR;
}
@@ -266,6 +280,10 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
!fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr.num_gr_mem,
&gr_mem, &gr_mem_len)) {
+
+ winbindd_store_group_cache_entry(domain, name_group,
+ &negative_gr_cache_entry, NULL, 0);
+
return WINBINDD_ERROR;
}
@@ -278,7 +296,7 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
/* Update cached group info */
- winbindd_store_group_cache_entry(name_domain, name_group,
+ winbindd_store_group_cache_entry(domain, name_group,
&state->response.data.gr,
state->response.extra_data,
gr_mem_len);
@@ -299,15 +317,14 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
int extra_data_len, gr_mem_len;
char *gr_mem;
+ DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
+ state->request.data.gid));
+
/* Bug out if the gid isn't in the winbind range */
if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high)) {
+ (state->request.data.gid > server_state.gid_high))
return WINBINDD_ERROR;
- }
-
- DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
- state->request.data.gid));
/* Get rid from gid */
@@ -318,17 +335,20 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
- }
-
/* Try a cached entry */
- if (winbindd_fetch_gid_cache_entry(domain->name,
+ if (winbindd_fetch_gid_cache_entry(domain,
state->request.data.gid,
&state->response.data.gr,
&state->response.extra_data,
&extra_data_len)) {
+
+ /* Check if this is a negative cache entry. */
+
+ if (memcmp(&negative_gr_cache_entry, &state->response.data.gr,
+ sizeof(state->response.data.gr)) == 0)
+ return WINBINDD_ERROR;
+
state->response.length += extra_data_len;
return WINBINDD_OK;
}
@@ -343,10 +363,9 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- if (strcmp(lp_winbind_separator(),"\\")) {
+ if (strcmp(lp_winbind_separator(),"\\"))
string_sub(group_name, "\\", lp_winbind_separator(),
sizeof(fstring));
- }
if (!((name_type == SID_NAME_ALIAS) ||
(name_type == SID_NAME_DOM_GRP))) {
@@ -361,10 +380,8 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
state->request.data.gid) ||
!fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr.num_gr_mem,
- &gr_mem, &gr_mem_len)) {
+ &gr_mem, &gr_mem_len))
return WINBINDD_ERROR;
- }
-
/* Group membership lives at start of extra data */
@@ -375,7 +392,7 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
/* Update cached group info */
- winbindd_store_gid_cache_entry(domain->name, state->request.data.gid,
+ winbindd_store_gid_cache_entry(domain, state->request.data.gid,
&state->response.data.gr,
state->response.extra_data,
gr_mem_len);
@@ -395,13 +412,10 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
DEBUG(3, ("[%5d]: setgrent\n", state->pid));
- if (state == NULL) return WINBINDD_ERROR;
-
/* Check user has enabled this */
- if (!lp_winbind_enum_groups()) {
+ if (!lp_winbind_enum_groups())
return WINBINDD_ERROR;
- }
/* Free old static data if it exists */
@@ -412,6 +426,9 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
/* Create sam pipes for each domain we know about */
+ if (domain_list == NULL)
+ get_domain_info();
+
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
struct getent_state *domain_state;
@@ -420,22 +437,20 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
if ((strcmp(state->request.domain, "") != 0) &&
!check_domain_env(state->request.domain, tmp->name)) {
+ DEBUG(5, ("skipping domain %s because of env var\n",
+ tmp->name));
continue;
}
/* Create a state record for this domain */
-
- if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL) {
-
- return WINBINDD_ERROR;
+ if ((domain_state = create_getent_state(tmp)) == NULL) {
+ DEBUG(5, ("error connecting to dc for domain %s\n",
+ tmp->name));
+ continue;
}
-
- ZERO_STRUCTP(domain_state);
-
+
/* Add to list of open domains */
- domain_state->domain = tmp;
DLIST_ADD(state->getgrent_state, domain_state);
}
@@ -448,8 +463,6 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
{
DEBUG(3, ("[%5d]: endgrent\n", state->pid));
- if (state == NULL) return WINBINDD_ERROR;
-
free_getent_state(state->getgrent_state);
state->getgrent_state = NULL;
@@ -465,74 +478,73 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
static BOOL get_sam_group_entries(struct getent_state *ent)
{
- uint32 status, num_entries;
+ NTSTATUS status;
+ uint32 num_entries;
struct acct_info *name_list = NULL, *tnl;
+ TALLOC_CTX *mem_ctx;
+ BOOL result = False;
- if (ent->got_all_sam_entries) {
+ if (ent->got_all_sam_entries)
return False;
- }
#if 0
- if (winbindd_fetch_group_cache(ent->domain->name,
+ if (winbindd_fetch_group_cache(ent->domain,
&ent->sam_entries,
- &ent->num_sam_entries)) {
+ &ent->num_sam_entries))
return True;
- }
#endif
-
- /* Fetch group entries */
-
- if (!domain_handles_open(ent->domain)) {
- return False;
- }
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
/* Free any existing group info */
- if (ent->sam_entries) {
- free(ent->sam_entries);
- ent->sam_entries = NULL;
- ent->num_sam_entries = 0;
- }
+ SAFE_FREE(ent->sam_entries);
+ ent->num_sam_entries = 0;
/* Enumerate domain groups */
do {
struct acct_info *sam_grp_entries = NULL;
+ CLI_POLICY_HND *hnd;
num_entries = 0;
- status = wb_samr_enum_dom_groups(&ent->domain->sam_dom_handle,
- &ent->grp_query_start_ndx,
- 0x8000, /* buffer size? */
- (struct acct_info **)
- &sam_grp_entries,
- &num_entries);
+ if (!(hnd = cm_get_sam_handle(ent->domain->name)))
+ break;
+
+ status = cli_samr_enum_dom_groups(
+ hnd->cli, mem_ctx, &ent->dom_pol,
+ &ent->grp_query_start_ndx,
+ 0x8000, /* buffer size? */
+ (struct acct_info **) &sam_grp_entries, &num_entries);
/* Copy entries into return buffer */
if (num_entries) {
tnl = Realloc(name_list,
- sizeof(struct acct_info) *
- (ent->num_sam_entries + num_entries));
- if(tnl == NULL) {
- DEBUG(0,("get_sam_group_entries: unable ro realloc a structure!\n"));
+ sizeof(struct acct_info) *
+ (ent->num_sam_entries +
+ num_entries));
+
+ if (tnl == NULL) {
+ DEBUG(0,("get_sam_group_entries: unable to "
+ "realloc a structure!\n"));
SAFE_FREE(name_list);
- return False;
- }
- else
+
+ goto done;
+ } else
name_list = tnl;
memcpy(&name_list[ent->num_sam_entries],
sam_grp_entries,
num_entries * sizeof(struct acct_info));
-
- safe_free(sam_grp_entries);
}
ent->num_sam_entries += num_entries;
- if (status != STATUS_MORE_ENTRIES)
+ if (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES))
break;
} while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES);
@@ -540,7 +552,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
#if 0
/* Fill cache with received entries */
- winbindd_store_group_cache(ent->domain->name, ent->sam_entries,
+ winbindd_store_group_cache(ent->domain, ent->sam_entries,
ent->num_sam_entries);
#endif
@@ -548,9 +560,16 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
ent->sam_entries = name_list;
ent->sam_entry_index = 0;
- ent->got_all_sam_entries = (status != STATUS_MORE_ENTRIES);
+ ent->got_all_sam_entries = (NT_STATUS_V(status) !=
+ NT_STATUS_V(STATUS_MORE_ENTRIES));
+
+ result = (ent->num_sam_entries > 0);
+
+ done:
- return ent->num_sam_entries > 0;
+ talloc_destroy(mem_ctx);
+
+ return result;
}
/* Fetch next group entry from ntdom database */
@@ -566,29 +585,24 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
DEBUG(3, ("[%5d]: getgrent\n", state->pid));
- if (state == NULL) return WINBINDD_ERROR;
-
/* Check user has enabled this */
- if (!lp_winbind_enum_groups()) {
+ if (!lp_winbind_enum_groups())
return WINBINDD_ERROR;
- }
num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries);
if ((state->response.extra_data =
- malloc(num_groups * sizeof(struct winbindd_gr))) == NULL) {
+ malloc(num_groups * sizeof(struct winbindd_gr))) == NULL)
return WINBINDD_ERROR;
- }
state->response.data.num_entries = 0;
group_list = (struct winbindd_gr *)state->response.extra_data;
sep = lp_winbind_separator();
- if (!(ent = state->getgrent_state)) {
+ if (!(ent = state->getgrent_state))
return WINBINDD_ERROR;
- }
/* Start sending back groups */
@@ -597,6 +611,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
fstring domain_group_name;
uint32 result;
gid_t group_gid;
+ int gr_mem_len;
+ char *gr_mem, *new_gr_mem_list;
/* Do we need to fetch another chunk of groups? */
@@ -615,19 +631,19 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Free state information for this domain */
- safe_free(ent->sam_entries);
- ent->sam_entries = NULL;
+ SAFE_FREE(ent->sam_entries);
next_ent = ent->next;
DLIST_REMOVE(state->getgrent_state, ent);
- free(ent);
+ SAFE_FREE(ent);
ent = next_ent;
}
/* No more domains */
- if (!ent) break;
+ if (!ent)
+ break;
}
name_list = ent->sam_entries;
@@ -661,8 +677,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Fill in group membership entry */
if (result) {
- int gr_mem_len;
- char *gr_mem, *new_gr_mem_list;
/* Get group membership */
@@ -672,7 +686,9 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
SID_NAME_DOM_GRP,
&group_list[group_list_ndx].num_gr_mem,
&gr_mem, &gr_mem_len);
+ }
+ if (result) {
/* Append to group membership list */
new_gr_mem_list = Realloc(
@@ -681,7 +697,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
if (!new_gr_mem_list && (group_list[group_list_ndx].num_gr_mem != 0)) {
DEBUG(0, ("getgrent(): out of memory\n"));
- free(gr_mem_list);
+ SAFE_FREE(gr_mem_list);
gr_mem_list_len = 0;
break;
}
@@ -694,7 +710,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
memcpy(&gr_mem_list[gr_mem_list_len], gr_mem,
gr_mem_len);
- safe_free(gr_mem);
+ SAFE_FREE(gr_mem);
group_list[group_list_ndx].gr_mem_ofs =
gr_mem_list_len;
@@ -725,9 +741,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Copy the list of group memberships to the end of the extra data */
- if (group_list_ndx == 0) {
+ if (group_list_ndx == 0)
goto done;
- }
new_extra_data = Realloc(
state->response.extra_data,
@@ -736,9 +751,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
if (!new_extra_data) {
DEBUG(0, ("out of memory\n"));
group_list_ndx = 0;
- safe_free(state->response.extra_data);
- state->response.extra_data = NULL;
- safe_free(gr_mem_list);
+ SAFE_FREE(state->response.extra_data);
+ SAFE_FREE(gr_mem_list);
return WINBINDD_ERROR;
}
@@ -749,7 +763,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
[group_list_ndx * sizeof(struct winbindd_gr)],
gr_mem_list, gr_mem_list_len);
- safe_free(gr_mem_list);
+ SAFE_FREE(gr_mem_list);
state->response.length += gr_mem_list_len;
@@ -759,6 +773,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
/* Out of domains */
done:
+
return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
}
@@ -769,64 +784,67 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
uint32 total_entries = 0;
uint32 num_domain_entries;
struct winbindd_domain *domain;
- struct getent_state groups;
+ struct getent_state *groups;
char *extra_data = NULL;
char *ted = NULL;
int extra_data_len = 0, i;
- char *sam_entries = NULL;
+ void *sam_entries = NULL;
DEBUG(3, ("[%5d]: list groups\n", state->pid));
/* Enumerate over trusted domains */
+
ZERO_STRUCT(groups);
+
+ if (domain_list == NULL)
+ get_domain_info();
+
for (domain = domain_list; domain; domain = domain->next) {
/* Skip domains other than WINBINDD_DOMAIN environment
variable */
if ((strcmp(state->request.domain, "") != 0) &&
- !check_domain_env(state->request.domain, domain->name)) {
+ !check_domain_env(state->request.domain, domain->name))
continue;
- }
/* Get list of sam groups */
- ZERO_STRUCT(groups);
- groups.domain = domain;
+ if ((groups = create_getent_state(domain)) == NULL)
+ continue;
/*
* iterate through all groups
- * total_entries : maintains a total count over **all domains**
- * num_domain_entries : is the running count for this domain
+ * total_entries: maintains a total count over **all domains**
+ * num_domain_entries: is the running count for this domain
*/
num_domain_entries = 0;
- while (get_sam_group_entries(&groups)) {
+
+ while (get_sam_group_entries(groups)) {
int new_size;
int offset;
- char *new_sam_entries;
-
+
offset = sizeof(struct acct_info) * num_domain_entries;
new_size = sizeof(struct acct_info)
- * (groups.num_sam_entries + num_domain_entries);
- new_sam_entries = Realloc(sam_entries, new_size);
-
- if (new_sam_entries)
- sam_entries = new_sam_entries;
- else {
- safe_free(sam_entries);
+ * (groups->num_sam_entries + num_domain_entries);
+ sam_entries = Realloc(sam_entries, new_size);
+
+ if (!sam_entries) {
+ free_getent_state(groups);
return WINBINDD_ERROR;
- }
-
- num_domain_entries += groups.num_sam_entries;
- memcpy (sam_entries+offset, groups.sam_entries,
- sizeof(struct acct_info) * groups.num_sam_entries);
+ }
+ num_domain_entries += groups->num_sam_entries;
+ memcpy (((char *)sam_entries)+offset,
+ groups->sam_entries,
+ sizeof(struct acct_info) *
+ groups->num_sam_entries);
- groups.sam_entries = NULL;
- groups.num_sam_entries = 0;
+ SAFE_FREE(groups->sam_entries);
+ groups->num_sam_entries = 0;
}
- /* skip remainder of loop if we didn't retrieve any groups */
+ /* skip remainder of loop if we idn;t retrieve any groups */
if (num_domain_entries == 0)
continue;
@@ -834,32 +852,35 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
/* setup the groups struct to contain all the groups
retrieved for this domain */
- groups.num_sam_entries = num_domain_entries;
- groups.sam_entries = sam_entries;
+ groups->num_sam_entries = num_domain_entries;
+ groups->sam_entries = sam_entries;
+
+ sam_entries = NULL;
/* keep track the of the total number of groups seen so
far over all domains */
- total_entries += groups.num_sam_entries;
+ total_entries += groups->num_sam_entries;
/* Allocate some memory for extra data. Note that we limit
account names to sizeof(fstring) = 128 characters. */
- ted = Realloc(extra_data, sizeof(fstring) * total_entries);
+ ted = Realloc(extra_data, sizeof(fstring) * total_entries);
if (!ted) {
- DEBUG(0,("winbindd_list_groups: failed to enlarge buffer!\n"));
- SAFE_FREE(groups.sam_entries);
+ DEBUG(0,("winbindd_list_groups: failed to enlarge "
+ "buffer!\n"));
SAFE_FREE(extra_data);
+ free_getent_state(groups);
return WINBINDD_ERROR;
} else
extra_data = ted;
/* Pack group list into extra data fields */
- for (i = 0; i < groups.num_sam_entries; i++) {
+ for (i = 0; i < groups->num_sam_entries; i++) {
char *group_name = ((struct acct_info *)
- groups.sam_entries)[i].acct_name;
+ groups->sam_entries)[i].acct_name;
fstring name;
/* Convert unistring to ascii */
@@ -869,11 +890,15 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
/* Append to extra data */
- memcpy(&extra_data[extra_data_len], name, strlen(name));
+ memcpy(&extra_data[extra_data_len], name,
+ strlen(name));
+
extra_data_len += strlen(name);
extra_data[extra_data_len++] = ',';
}
+
+ free_getent_state(groups);
}
/* Assign extra_data fields in response structure */
@@ -901,37 +926,29 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
uint32 user_rid, num_groups, num_gids;
DOM_GID *user_groups = NULL;
struct winbindd_domain *domain;
- enum winbindd_result result;
+ enum winbindd_result result = WINBINDD_ERROR;
gid_t *gid_list;
int i;
+ TALLOC_CTX *mem_ctx;
DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
state->request.data.username));
- if (state == NULL) return WINBINDD_ERROR;
+ if (!(mem_ctx = talloc_init()))
+ return WINBINDD_ERROR;
/* Parse domain and username */
- parse_domain_user(state->request.data.username, name_domain,
- name_user);
-
- /* Reject names that don't have a domain - i.e name_domain contains
- the entire name. */
-
- if (strequal(name_domain, "")) {
- return WINBINDD_ERROR;
- }
+ if (!parse_domain_user(state->request.data.username, name_domain,
+ name_user))
+ goto done;
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(0, ("could not find domain entry for domain %s\n",
name_domain));
- return WINBINDD_ERROR;
- }
-
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
+ goto done;
}
slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user);
@@ -940,31 +957,30 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
DEBUG(1, ("user '%s' does not exist\n", name_user));
- return WINBINDD_ERROR;
+ goto done;
}
if (name_type != SID_NAME_USER) {
DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
name_type));
- return WINBINDD_ERROR;
+ goto done;
}
sid_split_rid(&user_sid, &user_rid);
- if (!winbindd_lookup_usergroups(domain, user_rid, &num_groups,
- &user_groups)) {
- return WINBINDD_ERROR;
- }
+ if (!winbindd_lookup_usergroups(domain, mem_ctx, user_rid,
+ &num_groups, &user_groups))
+ goto done;
/* Copy data back to client */
num_gids = 0;
gid_list = malloc(sizeof(gid_t) * num_groups);
+ if (gid_list == NULL)
+ goto done;
- if (state->response.extra_data) {
- result = WINBINDD_ERROR;
+ if (state->response.extra_data)
goto done;
- }
for (i = 0; i < num_groups; i++) {
if (!winbindd_idmap_get_gid_from_rid(
@@ -986,7 +1002,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
result = WINBINDD_OK;
done:
- safe_free(user_groups);
+
+ talloc_destroy(mem_ctx);
return result;
}
diff --git a/source/nsswitch/winbindd_idmap.c b/source/nsswitch/winbindd_idmap.c
index 5f667a621bc..06d442c5655 100644
--- a/source/nsswitch/winbindd_idmap.c
+++ b/source/nsswitch/winbindd_idmap.c
@@ -104,7 +104,7 @@ static BOOL get_id_from_rid(char *domain_name, uint32 rid, uid_t *id,
result = True;
}
- free(data.dptr);
+ SAFE_FREE(data.dptr);
} else {
@@ -187,7 +187,7 @@ BOOL get_rid_from_id(int id, uint32 *rid, struct winbindd_domain **domain,
result = True;
}
done:
- free(data.dptr);
+ SAFE_FREE(data.dptr);
}
return result;
@@ -240,6 +240,13 @@ BOOL winbindd_idmap_init(void)
return True;
}
+BOOL winbindd_idmap_close(void)
+{
+ if (idmap_tdb)
+ return (tdb_close(idmap_tdb) == 0);
+ return True;
+}
+
/* Dump status information to log file. Display different stuff based on
the debug level:
@@ -251,11 +258,11 @@ BOOL winbindd_idmap_init(void)
#define DUMP_INFO 0
-void winbindd_idmap_dump_status(void)
+void winbindd_idmap_status(void)
{
int user_hwm, group_hwm;
- DEBUG(0, ("Status for winbindd idmap:\n"));
+ DEBUG(0, ("winbindd idmap status:\n"));
/* Get current high water marks */
diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c
index fdef3ff2be4..2718a753856 100644
--- a/source/nsswitch/winbindd_misc.c
+++ b/source/nsswitch/winbindd_misc.c
@@ -25,52 +25,36 @@
extern pstring global_myname;
-/* Some routines to fetch the trust account password from a HEAD
- version of Samba. Yuck. )-: */
-
-/************************************************************************
-form a key for fetching a domain trust password from
-************************************************************************/
-static char *trust_keystr(char *domain)
-{
- static fstring keystr;
-
- snprintf(keystr,sizeof(keystr),"%s/%s", SECRETS_MACHINE_ACCT_PASS,
- domain);
-
- return keystr;
-}
-
/************************************************************************
Routine to get the trust account password for a domain
************************************************************************/
-BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
- time_t *pass_last_set_time)
+static BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
+ time_t *pass_last_set_time)
{
struct machine_acct_pass *pass;
size_t size;
if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
- size != sizeof(*pass)) return False;
+ size != sizeof(*pass))
+ return False;
+
+ if (pass_last_set_time)
+ *pass_last_set_time = pass->mod_time;
- if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
memcpy(ret_pwd, pass->hash, 16);
- free(pass);
+ SAFE_FREE(pass);
+
return True;
}
/* Check the machine account password is valid */
-enum winbindd_result winbindd_check_machine_acct(
- struct winbindd_cli_state *state)
+enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state)
{
- int result = WINBINDD_ERROR;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uchar trust_passwd[16];
- struct in_addr *ip_list = NULL;
- int count;
- fstring controller, trust_account;
int num_retries = 0;
-
+ struct cli_state *cli;
DEBUG(3, ("[%5d]: check machine account\n", state->pid));
/* Get trust account password */
@@ -82,32 +66,17 @@ enum winbindd_result winbindd_check_machine_acct(
goto done;
}
- /* Get domain controller */
-
- if (!get_dc_list(True, lp_workgroup(), &ip_list, &count) ||
- !lookup_pdc_name(global_myname, lp_workgroup(), &ip_list[0],
- controller)) {
- DEBUG(0, ("could not find domain controller for "
- "domain %s\n", lp_workgroup()));
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- goto done;
- }
-
- DEBUG(3, ("contacting controller %s to check secret\n", controller));
+ /* This call does a cli_nt_setup_creds() which implicitly checks
+ the trust account password. */
- /* Contact domain controller to check secret */
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
- slprintf(trust_account, sizeof(trust_account) - 1, "%s$",
- global_myname);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
+ goto done;
+ }
-#if 0 /* XXX */
- {
- uint16 validation_level;
- result = cli_nt_setup_creds(controller, lp_workgroup(), global_myname,
- trust_account, trust_passwd,
- SEC_CHAN_WKSTA, &validation_level);
- }
-#endif
+ cli_shutdown(cli);
/* There is a race condition between fetching the trust account
password and joining the domain so it's possible that the trust
@@ -117,7 +86,7 @@ enum winbindd_result winbindd_check_machine_acct(
#define MAX_RETRIES 8
if ((num_retries < MAX_RETRIES) &&
- result == NT_STATUS_ACCESS_DENIED) {
+ NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
num_retries++;
goto again;
}
@@ -125,11 +94,12 @@ enum winbindd_result winbindd_check_machine_acct(
/* Pass back result code - zero for success, other values for
specific failures. */
- DEBUG(3, ("secret is %s\n", (result == NT_STATUS_OK) ?
- "good" : "bad"));
+ DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
+ "good" : "bad"));
done:
- state->response.data.num_entries = result;
+ state->response.data.num_entries = NT_STATUS_V(result);
+
return WINBINDD_OK;
}
@@ -142,6 +112,9 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
DEBUG(3, ("[%5d]: list trusted domains\n", state->pid));
+ if (domain_list == NULL)
+ get_domain_info();
+
for(domain = domain_list; domain; domain = domain->next) {
/* Skip own domain */
@@ -151,16 +124,15 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
/* Add domain to list */
total_entries++;
- ted = Realloc(extra_data, sizeof(fstring) *
- total_entries);
+ ted = Realloc(extra_data, sizeof(fstring) *
+ total_entries);
if (!ted) {
DEBUG(0,("winbindd_list_trusted_domains: failed to enlarge buffer!\n"));
- if (extra_data)
- free(extra_data);
+ SAFE_FREE(extra_data);
return WINBINDD_ERROR;
- } else
- extra_data = ted;
+ } else
+ extra_data = ted;
memcpy(&extra_data[extra_data_len], domain->name,
strlen(domain->name));
@@ -170,7 +142,8 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
}
if (extra_data) {
- if (extra_data_len > 1) extra_data[extra_data_len - 1] = '\0';
+ if (extra_data_len > 1)
+ extra_data[extra_data_len - 1] = '\0';
state->response.extra_data = extra_data;
state->response.length += extra_data_len;
}
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index ed7a0d4a28b..255a14e3d62 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -22,6 +22,10 @@
Boston, MA 02111-1307, USA.
*/
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
#ifndef _WINBINDD_NTDOM_H
#define _WINBINDD_NTDOM_H
@@ -55,13 +59,13 @@ enum winbindd_cmd {
/* PAM authenticate and password change */
WINBINDD_PAM_AUTH,
- WINBINDD_PAM_AUTH_CRAP,
+ WINBINDD_PAM_AUTH_CRAP,
WINBINDD_PAM_CHAUTHTOK,
/* List various things */
- WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
- WINBINDD_LIST_GROUPS, /* Ditto */
+ WINBINDD_LIST_USERS, /* List w/o rid->id mapping */
+ WINBINDD_LIST_GROUPS, /* Ditto */
WINBINDD_LIST_TRUSTDOM,
/* SID conversion */
@@ -69,7 +73,7 @@ enum winbindd_cmd {
WINBINDD_LOOKUPSID,
WINBINDD_LOOKUPNAME,
- /* S*RS functions */
+ /* Lookup functions */
WINBINDD_SID_TO_UID,
WINBINDD_SID_TO_GID,
@@ -80,6 +84,11 @@ enum winbindd_cmd {
WINBINDD_CHECK_MACHACC, /* Check machine account pw works */
+ /* WINS commands */
+
+ WINBINDD_WINS_BYIP,
+ WINBINDD_WINS_BYNAME,
+
/* Placeholder for end of cmd list */
WINBINDD_NUM_CMDS
@@ -117,7 +126,7 @@ struct winbindd_request {
fstring name; /* lookupname */
uint32 num_entries; /* getpwent, getgrent */
} data;
- fstring domain; /* {set,get,end}{pw,gr}ent() */
+ fstring domain; /* {set,get,end}{pw,gr}ent() */
};
/* Response values */
@@ -163,11 +172,11 @@ struct winbindd_response {
} gr;
uint32 num_entries; /* getpwent, getgrent */
- struct {
+ struct winbindd_sid {
fstring sid; /* lookupname, [ug]id_to_sid */
int type;
} sid;
- struct {
+ struct winbindd_name {
fstring name; /* lookupsid */
int type;
} name;
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 44d1e0ac99d..3e968c14737 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -24,25 +24,23 @@
#include "winbindd.h"
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
- form DOMAIN/user into a domain and a user */
+ form DOMAIN\user into a domain and a user */
-static void parse_domain_user(char *domuser, fstring domain, fstring user)
+static BOOL wb_parse_domain_user(char *domuser, fstring domain, fstring user)
{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- strupper(domain);
+ char *p;
+ char *sep = lp_winbind_separator();
+
+ p = strchr(domuser,*sep);
+
+ if (!p)
+ return False;
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper(domain);
+ return True;
}
/* Return a password structure from a username. Specify whether cached data
@@ -59,12 +57,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
/* Parse domain and username */
- parse_domain_user(state->request.data.auth.user, name_domain,
- name_user);
-
- /* don't allow the null domain */
-
- if (strcmp(name_domain,"") == 0)
+ if (!wb_parse_domain_user(state->request.data.auth.user, name_domain,
+ name_user))
return WINBINDD_ERROR;
passlen = strlen(state->request.data.auth.pass);
@@ -77,46 +71,106 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
state->request.data.auth.pass,
passlen,
state->request.data.auth.pass,
- passlen, &user_exists);
+ passlen, &user_exists, NULL);
return result ? WINBINDD_OK : WINBINDD_ERROR;
}
+/* Challenge Response Authentication Protocol */
+
+enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
+{
+ NTSTATUS result;
+ fstring name_domain, name_user;
+ unsigned char trust_passwd[16];
+ time_t last_change_time;
+ uint32 smb_uid_low;
+ NET_USER_INFO_3 info3;
+ NET_ID_INFO_CTR ctr;
+ struct cli_state *cli;
+
+ DEBUG(3, ("[%5d]: pam auth crap %s\n", state->pid,
+ state->request.data.auth_crap.user));
+
+ /* Parse domain and username */
+
+ if (!wb_parse_domain_user(state->request.data.auth_crap.user, name_domain,
+ name_user))
+ return WINBINDD_ERROR;
+
+ /*
+ * Get the machine account password for our primary domain
+ */
+
+ if (!secrets_fetch_trust_account_password(
+ lp_workgroup(), trust_passwd, &last_change_time)) {
+ DEBUG(0, ("winbindd_pam_auth_crap: could not fetch trust account "
+ "password for domain %s\n", lp_workgroup()));
+ return WINBINDD_ERROR;
+ }
+
+ /* We really don't care what LUID we give the user. */
+
+ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
+
+ ZERO_STRUCT(info3);
+
+ result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
+ goto done;
+ }
+
+ result = cli_nt_login_network(cli, name_domain, name_user, smb_uid_low,
+ state->request.data.auth_crap.chal,
+ state->request.data.auth_crap.lm_resp,
+ state->request.data.auth_crap.nt_resp,
+ &ctr, &info3);
+
+ cli_shutdown(cli);
+
+ done:
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
/* Change a user password */
enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
{
- char *oldpass, *newpass;
- fstring domain, user;
- uchar nt_oldhash[16];
- uchar lm_oldhash[16];
+ char *oldpass, *newpass;
+ fstring domain, user;
+ uchar nt_oldhash[16];
+ uchar lm_oldhash[16];
- DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
- state->request.data.chauthtok.user));
+ DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
+ state->request.data.chauthtok.user));
- /* Setup crap */
+ /* Setup crap */
- if (state == NULL) return WINBINDD_ERROR;
+ if (state == NULL)
+ return WINBINDD_ERROR;
- parse_domain_user(state->request.data.chauthtok.user, domain, user);
+ if (!wb_parse_domain_user(state->request.data.chauthtok.user, domain, user))
+ return WINBINDD_ERROR;
- oldpass = state->request.data.chauthtok.oldpass;
- newpass = state->request.data.chauthtok.newpass;
+ oldpass = state->request.data.chauthtok.oldpass;
+ newpass = state->request.data.chauthtok.newpass;
- nt_lm_owf_gen(oldpass, nt_oldhash, lm_oldhash);
+ nt_lm_owf_gen(oldpass, nt_oldhash, lm_oldhash);
- /* Change password */
+ /* Change password */
#if 0
- /* XXX */
+ /* XXX */
- if (!msrpc_sam_ntchange_pwd(server_state.controller, domain, user,
- lm_oldhash, nt_oldhash, newpass)) {
- DEBUG(0, ("password change failed for user %s/%s\n", domain, user));
- return WINBINDD_ERROR;
- }
+ if (!msrpc_sam_ntchange_pwd(server_state.controller, domain, user,
+ lm_oldhash, nt_oldhash, newpass)) {
+ DEBUG(0, ("password change failed for user %s/%s\n", domain, user));
+ return WINBINDD_ERROR;
+ }
#endif
- return WINBINDD_OK;
+ return WINBINDD_OK;
}
diff --git a/source/nsswitch/winbindd_proto.h b/source/nsswitch/winbindd_proto.h
index 11a3bc4f864..37448bd1987 100644
--- a/source/nsswitch/winbindd_proto.h
+++ b/source/nsswitch/winbindd_proto.h
@@ -5,51 +5,71 @@
/*The following definitions come from nsswitch/winbindd.c */
-void winbindd_dump_status(void);
int main(int argc, char **argv);
/*The following definitions come from nsswitch/winbindd_cache.c */
void winbindd_cache_init(void);
-void winbindd_store_user_cache(char *domain,
+void winbindd_store_user_cache(struct winbindd_domain *domain,
struct getpwent_user *sam_entries,
int num_sam_entries);
-void winbindd_store_group_cache(char *domain,
+void winbindd_store_group_cache(struct winbindd_domain *domain,
struct acct_info *sam_entries,
int num_sam_entries);
-void winbindd_store_user_cache_entry(char *domain, char *user_name,
- struct winbindd_pw *pw);
-void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
+void winbindd_store_name_cache_entry(struct winbindd_domain *domain,
+ char *sid, struct winbindd_name *name);
+void winbindd_store_sid_cache_entry(struct winbindd_domain *domain,
+ char *name, struct winbindd_sid *sid);
+void winbindd_store_user_cache_entry(struct winbindd_domain *domain,
+ char *user_name, struct winbindd_pw *pw);
+void winbindd_store_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
struct winbindd_pw *pw);
-void winbindd_store_group_cache_entry(char *domain, char *group_name,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len);
-void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
+void winbindd_store_group_cache_entry(struct winbindd_domain *domain,
+ char *group_name, struct winbindd_gr *gr,
+ void *extra_data, int extra_data_len);
+void winbindd_store_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
struct winbindd_gr *gr, void *extra_data,
int extra_data_len);
-BOOL winbindd_fetch_user_cache(char *domain_name,
+BOOL winbindd_fetch_user_cache(struct winbindd_domain *domain,
struct getpwent_user **sam_entries,
int *num_entries);
-BOOL winbindd_fetch_group_cache(char *domain_name,
+BOOL winbindd_fetch_group_cache(struct winbindd_domain *domain,
struct acct_info **sam_entries,
int *num_entries);
-BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
- struct winbindd_pw *pw);
-BOOL winbindd_fetch_uid_cache_entry(char *domain_name, uid_t uid,
+BOOL winbindd_fetch_sid_cache_entry(struct winbindd_domain *domain,
+ char *name, struct winbindd_sid *sid);
+BOOL winbindd_fetch_name_cache_entry(struct winbindd_domain *domain,
+ char *sid, struct winbindd_name *name);
+BOOL winbindd_fetch_user_cache_entry(struct winbindd_domain *domain,
+ char *user, struct winbindd_pw *pw);
+BOOL winbindd_fetch_uid_cache_entry(struct winbindd_domain *domain, uid_t uid,
struct winbindd_pw *pw);
-BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
- struct winbindd_gr *gr,
+BOOL winbindd_fetch_group_cache_entry(struct winbindd_domain *domain,
+ char *group, struct winbindd_gr *gr,
void **extra_data, int *extra_data_len);
-BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
+BOOL winbindd_fetch_gid_cache_entry(struct winbindd_domain *domain, gid_t gid,
struct winbindd_gr *gr,
void **extra_data, int *extra_data_len);
void winbindd_flush_cache(void);
-void winbindd_cache_dump_status(void);
+void winbindd_cache_status(void);
+
+/*The following definitions come from nsswitch/winbindd_cm.c */
+
+void cm_init_creds(struct ntuser_creds *creds);
+CLI_POLICY_HND *cm_get_lsa_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain, DOM_SID *domain_sid);
+CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, DOM_SID *domain_sid,
+ uint32 user_rid);
+CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
+ uint32 group_rid);
+NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
+ struct cli_state **cli);
+void winbindd_cm_status(void);
/*The following definitions come from nsswitch/winbindd_group.c */
-enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
- *state);
+enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
*state);
enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state);
@@ -71,20 +91,19 @@ BOOL winbindd_idmap_get_rid_from_uid(uid_t uid, uint32 *user_rid,
BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid,
struct winbindd_domain **domain);
BOOL winbindd_idmap_init(void);
-void winbindd_idmap_dump_status(void);
+BOOL winbindd_idmap_close(void);
+void winbindd_idmap_status(void);
/*The following definitions come from nsswitch/winbindd_misc.c */
-BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
- time_t *pass_last_set_time);
-enum winbindd_result winbindd_check_machine_acct(
- struct winbindd_cli_state *state);
+enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state);
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
*state);
/*The following definitions come from nsswitch/winbindd_pam.c */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) ;
enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_sid.c */
@@ -98,10 +117,8 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_user.c */
-enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
- *state) ;
-enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
- *state);
+enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state *state);
enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state);
@@ -109,37 +126,41 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_util.c */
-void debug_conn_state(void);
-BOOL domain_handles_open(struct winbindd_domain *domain);
-void winbindd_kill_connections(struct winbindd_domain *domain);
-void winbindd_kill_all_connections(void);
-void establish_connections(BOOL force_reestablish) ;
+struct winbindd_domain *find_domain_from_name(char *domain_name);
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
+BOOL get_domain_info(void);
+void free_domain_info(void);
BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain);
-BOOL get_domain_info(struct winbindd_domain *domain);
-BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
- enum SID_NAME_USE *type);
-BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
- enum SID_NAME_USE *type);
-BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
- uint32 user_rid, SAM_USERINFO_CTR **user_info);
+BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type);
+BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
+ fstring name,
+ enum SID_NAME_USE *type);
+BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx, uint32 user_rid,
+ SAM_USERINFO_CTR **user_info);
BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 user_rid, uint32 *num_groups,
DOM_GID **user_groups);
-BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
- uint32 group_rid, GROUP_INFO_CTR *info);
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
- enum SID_NAME_USE **name_types);
-struct winbindd_domain *find_domain_from_name(char *domain_name);
-struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
+ uint32 **name_types);
+BOOL create_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol);
+void close_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol);
void free_getent_state(struct getent_state *state);
+struct getent_state *create_getent_state(struct winbindd_domain *domain);
BOOL winbindd_param_init(void);
-char *winbindd_cmd_to_string(enum winbindd_cmd cmd);
-uint32 domain_sequence_number(char *domain_name);
-uint32 winbindd_query_dispinfo(struct winbindd_domain *domain,
- uint32 *start_ndx, uint16 info_level,
- uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
+NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx, POLICY_HND *pdom_pol,
+ uint32 *start_ndx, uint16 info_level,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
BOOL check_domain_env(char *domain_env, char *domain);
-void parse_domain_user(char *domuser, fstring domain, fstring user);
+BOOL parse_domain_user(char *domuser, fstring domain, fstring user);
+
+/*The following definitions come from nsswitch/winbindd_wins.c */
+
+enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state);
#endif /* _PROTO_H_ */
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index bc014f26918..689ad34c4e0 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -74,7 +74,8 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
DEBUG(3, ("[%5d]: lookupname %s\n", state->pid,
state->request.data.name));
- parse_domain_user(state->request.data.name, name_domain, name_user);
+ if (!parse_domain_user(state->request.data.name, name_domain, name_user))
+ return WINBINDD_ERROR;
snprintf(name, sizeof(name), "%s\\%s", name_domain, name_user);
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index 15eb6054f19..3185e261cd4 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -1,10 +1,11 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0
+ Version 2.2
Winbind daemon - user related functions
Copyright (C) Tim Potter 2000
+ Copyright (C) Jeremy Allison 2001.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,15 +28,14 @@
static BOOL winbindd_fill_pwent(char *domain_name, char *name,
uint32 user_rid, uint32 group_rid,
- char *full_name, struct winbindd_pw *pw)
+ char *full_name, struct winbindd_pw *pw)
{
extern userdom_struct current_user_info;
fstring name_domain, name_user;
pstring homedir;
- if (!pw || !name) {
+ if (!pw || !name)
return False;
- }
/* Resolve the uid number */
@@ -60,12 +60,15 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name,
/* Full name (gecos) */
safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
-
+
/* Home directory and shell - use template config parameters. The
defaults are /tmp for the home directory and /bin/false for
shell. */
- parse_domain_user(name, name_domain, name_user);
+ if (!parse_domain_user(name, name_domain, name_user)) {
+ DEBUG(1, ("error parsing domain user for %s\n", name_user ));
+ return False;
+ }
/* The substitution of %U and %D in the 'template homedir' is done
by lp_string() calling standard_sub_basic(). */
@@ -88,65 +91,63 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name,
return True;
}
+/************************************************************************
+ Empty static struct for negative caching.
+*************************************************************************/
+
+static struct winbindd_pw negative_pw_cache_entry;
+
/* Return a password structure from a username. Specify whether cached data
can be returned. */
-enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
- *state)
+enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state)
{
uint32 user_rid, group_rid;
SAM_USERINFO_CTR *user_info;
DOM_SID user_sid;
fstring name_domain, name_user, name, gecos_name;
- struct winbindd_domain *domain;
enum SID_NAME_USE name_type;
-
+ struct winbindd_domain *domain;
+ TALLOC_CTX *mem_ctx;
+
DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
state->request.data.username));
/* Parse domain and username */
- parse_domain_user(state->request.data.username, name_domain,
- name_user);
-
- /* Reject names that don't have a domain - i.e name_domain contains
- the entire name. */
-
- if (strequal(name_domain, "")) {
+ if (!parse_domain_user(state->request.data.username, name_domain,
+ name_user))
return WINBINDD_ERROR;
- }
-
- /* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n",
- name_domain));
- return WINBINDD_ERROR;
- }
-
- if (!domain_handles_open(domain)) {
+ DEBUG(5, ("No such domain: %s\n", name_domain));
return WINBINDD_ERROR;
}
/* Check for cached user entry */
- if (winbindd_fetch_user_cache_entry(name_domain, name_user,
- &state->response.data.pw)) {
+ if (winbindd_fetch_user_cache_entry(domain, name_user, &state->response.data.pw)) {
+ /* Check if this is a negative cache entry. */
+ if (memcmp(&negative_pw_cache_entry, &state->response.data.pw,
+ sizeof(state->response.data.pw)) == 0)
+ return WINBINDD_ERROR;
return WINBINDD_OK;
}
-
+
slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user);
- /* Get rid and name type from name. The following costs 1 packet */
+ /* Get rid and name type from name */
if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
DEBUG(1, ("user '%s' does not exist\n", name_user));
+ winbindd_store_user_cache_entry(domain, name_user, &negative_pw_cache_entry);
return WINBINDD_ERROR;
}
if (name_type != SID_NAME_USER) {
DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
name_type));
+ winbindd_store_user_cache_entry(domain, name_user, &negative_pw_cache_entry);
return WINBINDD_ERROR;
}
@@ -154,38 +155,47 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
from the winbind_lookup_by_name() call and use it in a
winbind_lookup_userinfo() */
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(1, ("out of memory\n"));
+ return WINBINDD_ERROR;
+ }
+
sid_split_rid(&user_sid, &user_rid);
- /* The following costs 3 packets */
-
- if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
+ if (!winbindd_lookup_userinfo(domain, mem_ctx, user_rid, &user_info)) {
DEBUG(1, ("pwnam_from_user(): error getting user info for "
"user '%s'\n", name_user));
+ winbindd_store_user_cache_entry(domain, name_user, &negative_pw_cache_entry);
+ talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
}
group_rid = user_info->info.id21->group_rid;
+
unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
sizeof(gecos_name) - 1);
-
+
+ talloc_destroy(mem_ctx);
+ user_info = NULL;
+
/* Now take all this information and fill in a passwd structure */
- if (!winbindd_fill_pwent(domain->name, state->request.data.username,
+ if (!winbindd_fill_pwent(name_domain, state->request.data.username,
user_rid, group_rid, gecos_name,
&state->response.data.pw)) {
+ winbindd_store_user_cache_entry(domain, name_user, &negative_pw_cache_entry);
+ /* talloc_destroy(mem_ctx); Surely this is wrong */
return WINBINDD_ERROR;
}
- winbindd_store_user_cache_entry(name_domain, name_user,
- &state->response.data.pw);
+ winbindd_store_user_cache_entry(domain, name_user, &state->response.data.pw);
return WINBINDD_OK;
}
/* Return a password structure given a uid number */
-enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
- *state)
+enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state *state)
{
DOM_SID user_sid;
struct winbindd_domain *domain;
@@ -194,13 +204,13 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
enum SID_NAME_USE name_type;
SAM_USERINFO_CTR *user_info;
gid_t gid;
+ TALLOC_CTX *mem_ctx;
/* Bug out if the uid isn't in the winbind range */
if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high)) {
+ (state->request.data.uid > server_state.uid_high))
return WINBINDD_ERROR;
- }
DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
state->request.data.uid));
@@ -214,18 +224,18 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
- }
-
/* Check for cached uid entry */
- if (winbindd_fetch_uid_cache_entry(domain->name,
+ if (winbindd_fetch_uid_cache_entry(domain,
state->request.data.uid,
&state->response.data.pw)) {
+ /* Check if this is a negative cache entry. */
+ if (memcmp(&negative_pw_cache_entry, &state->response.data.pw,
+ sizeof(state->response.data.pw)) == 0)
+ return WINBINDD_ERROR;
return WINBINDD_OK;
}
-
+
/* Get name and name type from rid */
sid_copy(&user_sid, &domain->sid);
@@ -236,19 +246,27 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
sid_to_string(temp, &user_sid);
DEBUG(1, ("Could not lookup sid %s\n", temp));
+
+ winbindd_store_uid_cache_entry(domain, state->request.data.uid, &negative_pw_cache_entry);
return WINBINDD_ERROR;
}
- if (strcmp("\\", lp_winbind_separator())) {
+ if (strcmp("\\", lp_winbind_separator()))
string_sub(user_name, "\\", lp_winbind_separator(),
sizeof(fstring));
- }
/* Get some user info */
- if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(1, ("out of memory\n"));
+ return WINBINDD_ERROR;
+ }
+
+ if (!winbindd_lookup_userinfo(domain, mem_ctx, user_rid, &user_info)) {
DEBUG(1, ("pwnam_from_uid(): error getting user info for "
"user '%s'\n", user_name));
+ winbindd_store_uid_cache_entry(domain, state->request.data.uid, &negative_pw_cache_entry);
+ talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
}
@@ -256,6 +274,9 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
sizeof(gecos_name) - 1);
+ talloc_destroy(mem_ctx);
+ user_info = NULL;
+
/* Resolve gid number */
if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
@@ -267,11 +288,11 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
if (!winbindd_fill_pwent(domain->name, user_name, user_rid, group_rid,
gecos_name, &state->response.data.pw)) {
+ winbindd_store_uid_cache_entry(domain, state->request.data.uid, &negative_pw_cache_entry);
return WINBINDD_ERROR;
}
- winbindd_store_uid_cache_entry(domain->name, state->request.data.uid,
- &state->response.data.pw);
+ winbindd_store_uid_cache_entry(domain, state->request.data.uid, &state->response.data.pw);
return WINBINDD_OK;
}
@@ -284,68 +305,68 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
{
- struct winbindd_domain *tmp;
-
- DEBUG(3, ("[%5d]: setpwent\n", state->pid));
-
- if (state == NULL) return WINBINDD_ERROR;
-
- /* Check user has enabled this */
-
- if (!lp_winbind_enum_users()) {
- return WINBINDD_ERROR;
- }
-
- /* Free old static data if it exists */
-
- if (state->getpwent_state != NULL) {
- free_getent_state(state->getpwent_state);
- state->getpwent_state = NULL;
- }
-
- /* Create sam pipes for each domain we know about */
-
- for(tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- struct getent_state *domain_state;
-
- /* Skip domains other than WINBINDD_DOMAIN environment variable */
-
- if ((strcmp(state->request.domain, "") != 0) &&
- !check_domain_env(state->request.domain, tmp->name)) {
- continue;
- }
-
- /* Create a state record for this domain */
-
- if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL) {
-
- return WINBINDD_ERROR;
- }
-
- ZERO_STRUCTP(domain_state);
- domain_state->domain = tmp;
-
- /* Add to list of open domains */
+ struct winbindd_domain *tmp;
+
+ DEBUG(3, ("[%5d]: setpwent\n", state->pid));
+
+ /* Check user has enabled this */
+
+ if (!lp_winbind_enum_users())
+ return WINBINDD_ERROR;
- DLIST_ADD(state->getpwent_state, domain_state)
- }
+ /* Free old static data if it exists */
+
+ if (state->getpwent_state != NULL) {
+ free_getent_state(state->getpwent_state);
+ state->getpwent_state = NULL;
+ }
+
+ /* Create sam pipes for each domain we know about */
+
+ if (domain_list == NULL)
+ get_domain_info();
+
+ for(tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ struct getent_state *domain_state;
+
+ /*
+ * Skip domains other than WINBINDD_DOMAIN environment
+ * variable.
+ */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, tmp->name)) {
+ DEBUG(5, ("skipping domain %s because of env var\n",
+ tmp->name));
+ continue;
+ }
- return WINBINDD_OK;
+ /* Create a state record for this domain */
+
+ if ((domain_state = create_getent_state(tmp)) == NULL) {
+ DEBUG(5, ("error connecting to dc for domain %s\n",
+ tmp->name));
+ continue;
+ }
+
+ /* Add to list of open domains */
+
+ DLIST_ADD(state->getpwent_state, domain_state);
+ }
+
+ return WINBINDD_OK;
}
/* Close file pointer to ntdom passwd database */
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: endpwent\n", state->pid));
-
- if (state == NULL) return WINBINDD_ERROR;
+ DEBUG(3, ("[%5d]: endpwent\n", state->pid));
- free_getent_state(state->getpwent_state);
- state->getpwent_state = NULL;
-
- return WINBINDD_OK;
+ free_getent_state(state->getpwent_state);
+ state->getpwent_state = NULL;
+
+ return WINBINDD_OK;
}
/* Get partial list of domain users for a domain. We fill in the sam_entries,
@@ -357,15 +378,20 @@ enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
static BOOL get_sam_user_entries(struct getent_state *ent)
{
- uint32 status, num_entries;
+ NTSTATUS status;
+ uint32 num_entries;
SAM_DISPINFO_1 info1;
SAM_DISPINFO_CTR ctr;
struct getpwent_user *name_list = NULL;
uint32 group_rid;
+ BOOL result = False;
+ TALLOC_CTX *mem_ctx;
- if (ent->got_all_sam_entries) {
+ if (ent->got_all_sam_entries)
+ return False;
+
+ if (!(mem_ctx = talloc_init()))
return False;
- }
ZERO_STRUCT(info1);
ZERO_STRUCT(ctr);
@@ -375,7 +401,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
#if 0
/* Look in cache for entries, else get them direct */
- if (winbindd_fetch_user_cache(ent->domain->name,
+ if (winbindd_fetch_user_cache(ent->domain,
(struct getpwent_user **)
&ent->sam_entries,
&ent->num_sam_entries)) {
@@ -391,18 +417,11 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
group_rid = DOMAIN_GROUP_RID_USERS;
- if (!domain_handles_open(ent->domain)) {
- return WINBINDD_ERROR;
- }
-
/* Free any existing user info */
- if (ent->sam_entries) {
- free(ent->sam_entries);
- ent->sam_entries = NULL;
- ent->num_sam_entries = 0;
- }
-
+ SAFE_FREE(ent->sam_entries);
+ ent->num_sam_entries = 0;
+
/* Call query_dispinfo to get a list of usernames and user rids */
do {
@@ -410,7 +429,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
num_entries = 0;
- status = winbindd_query_dispinfo(ent->domain,
+ status = winbindd_query_dispinfo(ent->domain, mem_ctx, &ent->dom_pol,
&ent->dispinfo_ndx, 1,
&num_entries, &ctr);
@@ -424,9 +443,8 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
if (!tnl) {
DEBUG(0,("get_sam_user_entries: Realloc failed.\n"));
- if (name_list)
- free(name_list);
- return WINBINDD_ERROR;
+ SAFE_FREE(name_list);
+ goto done;
} else
name_list = tnl;
}
@@ -456,16 +474,15 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
ent->num_sam_entries += num_entries;
- if (status != STATUS_MORE_ENTRIES) {
+ if (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES))
break;
- }
} while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES);
#if 0
/* Fill cache with received entries */
- winbindd_store_user_cache(ent->domain->name, ent->sam_entries,
+ winbindd_store_user_cache(ent->domain, ent->sam_entries,
ent->num_sam_entries);
#endif
@@ -473,9 +490,15 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
ent->sam_entries = name_list;
ent->sam_entry_index = 0;
- ent->got_all_sam_entries = (status != STATUS_MORE_ENTRIES);
+ ent->got_all_sam_entries = (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES));
+
+ result = ent->num_sam_entries > 0;
- return ent->num_sam_entries > 0;
+ done:
+
+ talloc_destroy(mem_ctx);
+
+ return result;
}
/* Fetch next passwd entry from ntdom database */
@@ -491,22 +514,18 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
DEBUG(3, ("[%5d]: getpwent\n", state->pid));
- if (state == NULL) return WINBINDD_ERROR;
-
/* Check user has enabled this */
- if (!lp_winbind_enum_users()) {
+ if (!lp_winbind_enum_users())
return WINBINDD_ERROR;
- }
/* Allocate space for returning a chunk of users */
num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries);
if ((state->response.extra_data =
- malloc(num_users * sizeof(struct winbindd_pw))) == NULL) {
+ malloc(num_users * sizeof(struct winbindd_pw))) == NULL)
return WINBINDD_ERROR;
- }
memset(state->response.extra_data, 0, num_users *
sizeof(struct winbindd_pw));
@@ -514,9 +533,8 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
user_list = (struct winbindd_pw *)state->response.extra_data;
sep = lp_winbind_separator();
- if (!(ent = state->getpwent_state)) {
+ if (!(ent = state->getpwent_state))
return WINBINDD_ERROR;
- }
/* Start sending back users */
@@ -534,19 +552,19 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
/* Free state information for this domain */
- safe_free(ent->sam_entries);
- ent->sam_entries = NULL;
+ SAFE_FREE(ent->sam_entries);
next_ent = ent->next;
DLIST_REMOVE(state->getpwent_state, ent);
- free(ent);
+ SAFE_FREE(ent);
ent = next_ent;
}
/* No more domains */
- if (!ent) break;
+ if (!ent)
+ break;
}
name_list = ent->sam_entries;
@@ -585,11 +603,9 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
state->response.length +=
sizeof(struct winbindd_pw);
- } else {
+ } else
DEBUG(1, ("could not lookup domain user %s\n",
domain_user_name));
- }
-
}
/* Out of domains */
@@ -607,40 +623,47 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
uint32 num_entries = 0, total_entries = 0;
char *ted, *extra_data = NULL;
int extra_data_len = 0;
+ TALLOC_CTX *mem_ctx;
+ enum winbindd_result rv = WINBINDD_ERROR;
DEBUG(3, ("[%5d]: list users\n", state->pid));
+ if (!(mem_ctx = talloc_init()))
+ return WINBINDD_ERROR;
+
/* Enumerate over trusted domains */
ctr.sam.info1 = &info1;
+ if (domain_list == NULL)
+ get_domain_info();
+
for (domain = domain_list; domain; domain = domain->next) {
- uint32 status, start_ndx = 0;
+ NTSTATUS status;
+ uint32 start_ndx = 0;
+ POLICY_HND dom_pol;
/* Skip domains other than WINBINDD_DOMAIN environment
variable */
if ((strcmp(state->request.domain, "") != 0) &&
- !check_domain_env(state->request.domain, domain->name)) {
+ !check_domain_env(state->request.domain, domain->name))
continue;
- }
- if (!domain_handles_open(domain)) {
+ if (!create_samr_domain_handle(domain, &dom_pol))
continue;
- }
/* Query display info */
do {
int i;
- status = winbindd_query_dispinfo(domain, &start_ndx,
- 1, &num_entries,
- &ctr);
+ status = winbindd_query_dispinfo(
+ domain, mem_ctx, &dom_pol, &start_ndx,
+ 1, &num_entries, &ctr);
- if (num_entries == 0) {
+ if (num_entries == 0)
continue;
- }
/* Allocate some memory for extra data */
@@ -648,13 +671,12 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
ted = Realloc(extra_data, sizeof(fstring) *
total_entries);
-
+
if (!ted) {
DEBUG(0,("winbindd_list_users: failed to enlarge buffer!\n"));
- if (extra_data)
- free(extra_data);
- return WINBINDD_ERROR;
- } else
+ SAFE_FREE(extra_data);
+ goto done;
+ } else
extra_data = ted;
/* Pack user list into extra data fields */
@@ -682,7 +704,9 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
extra_data[extra_data_len++] = ',';
}
- } while (status == STATUS_MORE_ENTRIES);
+ } while (NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES));
+
+ close_samr_domain_handle(domain, &dom_pol);
}
/* Assign extra_data fields in response structure */
@@ -696,5 +720,11 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
/* No domains responded but that's still OK so don't return an
error. */
- return WINBINDD_OK;
+ rv = WINBINDD_OK;
+
+ done:
+
+ talloc_destroy(mem_ctx);
+
+ return rv;
}
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index aadc709da2b..c0c7b6ae0dd 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -1,10 +1,10 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0
Winbind daemon for ntdom nss module
- Copyright (C) Tim Potter 2000
+ Copyright (C) Tim Potter 2000-2001
+ Copyright (C) 2001 by Martin Pool <mbp@samba.org>
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
@@ -24,858 +24,865 @@
#include "winbindd.h"
#include "sids.h"
-/* Debug connection state */
+/**
+ * @file winbindd_util.c
+ *
+ * Winbind daemon for NT domain authentication nss module.
+ **/
-void debug_conn_state(void)
+
+/**
+ * Used to clobber name fields that have an undefined value.
+ *
+ * Correct code should never look at a field that has this value.
+ **/
+static const fstring name_deadbeef = "<deadbeef>";
+
+
+/* Globals for domain list stuff */
+
+struct winbindd_domain *domain_list = NULL;
+
+/* Given a domain name, return the struct winbindd domain info for it
+ if it is actually working. */
+
+struct winbindd_domain *find_domain_from_name(char *domain_name)
{
- struct winbindd_domain *domain;
+ struct winbindd_domain *tmp;
+
+ if (domain_list == NULL)
+ get_domain_info();
- DEBUG(3, ("server: dc=%s, pwdb_init=%d, lsa_hnd=%d\n",
- server_state.controller,
- server_state.pwdb_initialised,
- server_state.lsa_handle_open));
+ /* Search through list */
- for (domain = domain_list; domain; domain = domain->next) {
- DEBUG(3, ("%s: dc=%s, got_sid=%d, sam_hnd=%d sam_dom_hnd=%d\n",
- domain->name, domain->controller,
- domain->got_domain_info, domain->sam_handle_open,
- domain->sam_dom_handle_open));
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if (strcmp(domain_name, tmp->name) == 0)
+ return tmp;
}
+
+ /* Not found */
+
+ return NULL;
}
-/* Add a trusted domain to our list of domains */
+/* Given a domain name, return the struct winbindd domain info for it */
-static struct winbindd_domain *add_trusted_domain(char *domain_name)
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
{
- struct winbindd_domain *domain, *tmp;
-
- for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (strcmp(domain_name, tmp->name) == 0) {
- DEBUG(3, ("domain %s already in trusted list\n",
- domain_name));
- return tmp;
- }
- }
-
- DEBUG(1, ("adding trusted domain %s\n", domain_name));
+ struct winbindd_domain *tmp;
- /* Create new domain entry */
+ if (domain_list == NULL)
+ get_domain_info();
- if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL) {
- return NULL;
- }
+ /* Search through list */
- /* Fill in fields */
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if (sid_equal(sid, &tmp->sid))
+ return tmp;
+ }
- ZERO_STRUCTP(domain);
+ /* Not found */
- if (domain_name) {
- fstrcpy(domain->name, domain_name);
- }
+ return NULL;
+}
- /* Link to domain list */
+/* Add a trusted domain to our list of domains */
- DLIST_ADD(domain_list, domain);
+static struct winbindd_domain *add_trusted_domain(char *domain_name,
+ DOM_SID *domain_sid)
+{
+ struct winbindd_domain *domain, *tmp;
+
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if (strcmp(domain_name, tmp->name) == 0) {
+ DEBUG(3, ("domain %s already in domain list\n", domain_name));
+ return tmp;
+ }
+ }
+
+ DEBUG(1, ("adding domain %s\n", domain_name));
+
+ /* Create new domain entry */
+
+ if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain))) == NULL)
+ return NULL;
- return domain;
+ /* Fill in fields */
+
+ ZERO_STRUCTP(domain);
+ fstrcpy(domain->name, domain_name);
+ sid_copy(&domain->sid, domain_sid);
+
+ /* Link to domain list */
+
+ DLIST_ADD(domain_list, domain);
+
+ return domain;
}
/* Look up global info for the winbind daemon */
-static BOOL get_trusted_domains(void)
+BOOL get_domain_info(void)
{
- uint32 enum_ctx = 0;
- uint32 num_doms = 0;
+ uint32 enum_ctx = 0, num_doms = 0;
char **domains = NULL;
- DOM_SID *sids = NULL;
- BOOL result;
+ DOM_SID *sids = NULL, domain_sid;
+ NTSTATUS result;
+ CLI_POLICY_HND *hnd;
int i;
+ fstring level5_dom;
+ BOOL rv = False;
+ TALLOC_CTX *mem_ctx;
DEBUG(1, ("getting trusted domain list\n"));
- /* Add our workgroup - keep handle to look up trusted domains */
- if (!add_trusted_domain(lp_workgroup())) {
- DEBUG(0, ("could not add record for domain %s\n",
- lp_workgroup()));
+ if (!(mem_ctx = talloc_init()))
return False;
- }
-
- /* Enumerate list of trusted domains */
- result = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
- &num_doms, &domains, &sids);
-
- if (!result || !domains) return False;
-
- /* Add each domain to the trusted domain list */
- for(i = 0; i < num_doms; i++) {
- if (!add_trusted_domain(domains[i])) {
- DEBUG(0, ("could not add record for domain %s\n",
- domains[i]));
- result = False;
- }
- }
-
- return True;
-}
-
-/* Open sam and sam domain handles */
-static BOOL open_sam_handles(struct winbindd_domain *domain)
-{
- /* Get domain info (sid and controller name) */
+ /* Add our workgroup - keep handle to look up trusted domains */
- if (!domain->got_domain_info) {
- domain->got_domain_info = get_domain_info(domain);
- if (!domain->got_domain_info) return False;
- }
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ goto done;
- /* Shut down existing sam handles */
+ result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
+ &hnd->pol, 0x05, level5_dom, &domain_sid);
- if (domain->sam_dom_handle_open) {
- wb_samr_close(&domain->sam_dom_handle);
- domain->sam_dom_handle_open = False;
- }
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- if (domain->sam_handle_open) {
- wb_samr_close(&domain->sam_handle);
- domain->sam_handle_open = False;
- }
+ add_trusted_domain(lp_workgroup(), &domain_sid);
+
+ /* Enumerate list of trusted domains */
- /* Open sam handle */
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ goto done;
- domain->sam_handle_open =
- wb_samr_connect(domain->controller,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sam_handle);
+ result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
+ &hnd->pol, &enum_ctx, &num_doms, &domains, &sids);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Add each domain to the trusted domain list */
- if (!domain->sam_handle_open) return False;
+ for(i = 0; i < num_doms; i++)
+ add_trusted_domain(domains[i], &sids[i]);
- /* Open sam domain handle */
+ rv = True;
- domain->sam_dom_handle_open =
- wb_samr_open_domain(&domain->sam_handle,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sid,
- &domain->sam_dom_handle);
+ done:
- if (!domain->sam_dom_handle_open) return False;
-
- return True;
-}
+ talloc_destroy(mem_ctx);
-static BOOL rpc_hnd_ok(CLI_POLICY_HND *hnd)
-{
- return hnd->cli->fd != -1;
+ return rv;
}
-/* Return true if the SAM domain handles are open and responding. */
+/* Free global domain info */
-BOOL domain_handles_open(struct winbindd_domain *domain)
+void free_domain_info(void)
{
- time_t t;
- BOOL result;
-
- /* Check we haven't checked too recently */
-
- t = time(NULL);
-
- if ((t - domain->last_check) < WINBINDD_ESTABLISH_LOOP) {
- return domain->sam_handle_open &&
- domain->sam_dom_handle_open;
- }
-
- DEBUG(3, ("checking domain handles for domain %s\n", domain->name));
- debug_conn_state();
-
- domain->last_check = t;
-
- /* Open sam handles if they are marked as closed */
-
- if (!domain->sam_handle_open || !domain->sam_dom_handle_open) {
- reopen:
- DEBUG(3, ("opening sam handles\n"));
- return open_sam_handles(domain);
- }
-
- /* Check sam handles are ok - the domain controller may have failed
- and we need to move to a BDC. */
+ struct winbindd_domain *domain;
- if (!rpc_hnd_ok(&domain->sam_handle) ||
- !rpc_hnd_ok(&domain->sam_dom_handle)) {
+ /* Free list of domains */
- /* We want to close the current connection but attempt
- to open a new set, possibly to a new dc. If this
- doesn't work then return False as we have no dc
- to talk to. */
+ if (domain_list) {
+ struct winbindd_domain *next_domain;
- DEBUG(3, ("sam handles not responding\n"));
+ domain = domain_list;
- winbindd_kill_connections(domain);
- goto reopen;
+ while(domain) {
+ next_domain = domain->next;
+ SAFE_FREE(domain);
+ domain = next_domain;
+ }
}
-
- result = domain->sam_handle_open && domain->sam_dom_handle_open;
-
- return result;
}
-/* Shut down connections to all domain controllers */
+/* Connect to a domain controller using get_any_dc_name() to discover
+ the domain name and sid */
-void winbindd_kill_connections(struct winbindd_domain *domain)
+BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
{
- /* Kill all connections */
-
- if (!domain) {
- struct winbindd_domain *tmp;
+ fstring level5_dom;
+ uint32 enum_ctx = 0, num_doms = 0;
+ char **domains = NULL;
+ DOM_SID *sids = NULL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+ BOOL rv = False;
+ TALLOC_CTX *mem_ctx;
+
+ DEBUG(1, ("looking up sid for domain %s\n", domain_name));
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
+ if (!(hnd = cm_get_lsa_handle(domain_name)))
+ goto done;
+
+ /* Do a level 5 query info policy if we are looking up the SID for
+ our own domain. */
+
+ if (strequal(domain_name, lp_workgroup())) {
+
+ result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
+ &hnd->pol, 0x05, level5_dom,
+ &domain->sid);
+
+ rv = NT_STATUS_IS_OK(result);
+ goto done;
+ }
+
+ /* Use lsaenumdomains to get sid for this domain */
+
+ result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, &hnd->pol,
+ &enum_ctx, &num_doms, &domains, &sids);
+
+ /* Look for domain name */
+
+ if (NT_STATUS_IS_OK(result) && domains && sids) {
+ BOOL found = False;
+ int i;
+
+ for(i = 0; i < num_doms; i++) {
+ if (strequal(domain_name, domains[i])) {
+ sid_copy(&domain->sid, &sids[i]);
+ found = True;
+ break;
+ }
+ }
+
+ rv = found;
+ goto done;
+ }
+
+ rv = False; /* An error occured with a trusted domain */
- for (tmp = domain_list; tmp; tmp = tmp->next) {
- winbindd_kill_connections(domain);
- }
+ done:
- return;
- }
+ talloc_destroy(mem_ctx);
- /* Log a level 0 message - this is probably a domain controller
- failure */
+ return rv;
+}
- if (!domain->controller[0])
- return;
+/* Store a SID in a domain indexed by name in the cache. */
- DEBUG(0, ("killing connections to domain %s with controller %s\n",
- domain->name, domain->controller));
+static void store_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE type)
+{
+ fstring domain_str;
+ char *p;
+ struct winbindd_sid sid_val;
+ struct winbindd_domain *domain;
- debug_conn_state();
+ /* Get name from domain. */
+ fstrcpy( domain_str, name);
+ p = strchr(domain_str, '\\');
+ if (p)
+ *p = '\0';
- /* Close LSA connections if we are killing connections to the dc
- that has them open. */
+ if ((domain = find_domain_from_name(domain_str)) == NULL)
+ return;
- if (strequal(server_state.controller, domain->controller)) {
- server_state.pwdb_initialised = False;
- server_state.lsa_handle_open = False;
- wb_lsa_close(&server_state.lsa_handle);
- }
-
- /* Close domain sam handles but don't free them as this
- severely traumatises the getent state. The connections
- will be reopened later. */
+ sid_to_string(sid_val.sid, sid);
+ sid_val.type = (int)type;
- if (domain->sam_dom_handle_open) {
- wb_samr_close(&domain->sam_dom_handle);
- domain->sam_dom_handle_open = False;
- }
-
- if (domain->sam_handle_open) {
- wb_samr_close(&domain->sam_handle);
- domain->sam_handle_open = False;
- }
+ DEBUG(10,("store_sid_by_name_in_cache: storing cache entry %s -> SID %s\n",
+ name, sid_val.sid ));
- /* Re-lookup domain info which includes domain controller name */
-
- domain->got_domain_info = False;
+ winbindd_store_sid_cache_entry(domain, name, &sid_val);
}
-/* Kill connections to all servers */
+/* Lookup a SID in a domain indexed by name in the cache. */
-void winbindd_kill_all_connections(void)
+static BOOL winbindd_lookup_sid_by_name_in_cache(fstring name, DOM_SID *sid, enum SID_NAME_USE *type)
{
+ fstring domain_str;
+ char *p;
+ struct winbindd_sid sid_ret;
struct winbindd_domain *domain;
- /* Iterate over domain list */
-
- domain = domain_list;
-
- while (domain) {
- struct winbindd_domain *next;
-
- /* Kill conections */
-
- winbindd_kill_connections(domain);
+ /* Get name from domain. */
+ fstrcpy( domain_str, name);
+ p = strchr(domain_str, '\\');
+ if (p)
+ *p = '\0';
- /* Remove domain from list */
-
- next = domain->next;
- DLIST_REMOVE(domain_list, domain);
- free(domain);
+ if ((domain = find_domain_from_name(domain_str)) == NULL)
+ return False;
- domain = next;
- }
-}
+ if (!winbindd_fetch_sid_cache_entry(domain, name, &sid_ret))
+ return False;
-static BOOL get_any_dc_name(char *domain, fstring srv_name)
-{
- struct in_addr *ip_list, dc_ip;
- extern pstring global_myname;
- int count, i;
+ string_to_sid( sid, sid_ret.sid);
+ *type = (enum SID_NAME_USE)sid_ret.type;
- /* Lookup domain controller name */
-
- if (!get_dc_list(False, domain, &ip_list, &count))
- return False;
-
- /* Firstly choose a PDC/BDC who has the same network address as any
- of our interfaces. */
-
- for (i = 0; i < count; i++) {
- if(!is_local_net(ip_list[i]))
- goto got_ip;
- }
-
- i = (sys_random() % count);
-
- got_ip:
- dc_ip = ip_list[i];
- free(ip_list);
-
- if (!lookup_pdc_name(global_myname, domain, &dc_ip, srv_name))
- return False;
+ DEBUG(10,("winbindd_lookup_sid_by_name_in_cache: Cache hit for name %s. SID = %s\n",
+ name, sid_ret.sid ));
return True;
}
-/* Attempt to connect to all domain controllers we know about */
+/* Store a name in a domain indexed by SID in the cache. */
-void establish_connections(BOOL force_reestablish)
+static void store_name_by_sid_in_cache(DOM_SID *sid, fstring name, enum SID_NAME_USE type)
{
- static time_t lastt;
- time_t t;
+ fstring sid_str;
+ uint32 rid;
+ DOM_SID domain_sid;
+ struct winbindd_name name_val;
+ struct winbindd_domain *domain;
- /* Check we haven't checked too recently */
+ /* Split sid into domain sid and user rid */
+ sid_copy(&domain_sid, sid);
+ sid_split_rid(&domain_sid, &rid);
- t = time(NULL);
- if ((t - lastt < WINBINDD_ESTABLISH_LOOP) && !force_reestablish) {
- return;
- }
- lastt = t;
+ if ((domain = find_domain_from_sid(&domain_sid)) == NULL)
+ return;
- DEBUG(3, ("establishing connections\n"));
- debug_conn_state();
+ sid_to_string(sid_str, sid);
+ fstrcpy( name_val.name, name );
+ name_val.type = (int)type;
- /* Maybe the connection died - if so then close up and restart */
+ DEBUG(10,("store_name_by_sid_in_cache: storing cache entry SID %s -> %s\n",
+ sid_str, name_val.name ));
- if (server_state.pwdb_initialised &&
- server_state.lsa_handle_open &&
- !rpc_hnd_ok(&server_state.lsa_handle)) {
- winbindd_kill_connections(NULL);
- }
+ winbindd_store_name_cache_entry(domain, sid_str, &name_val);
+}
- if (!server_state.pwdb_initialised) {
+/* Lookup a name in a domain indexed by SID in the cache. */
- /* Lookup domain controller name */
+static BOOL winbindd_lookup_name_by_sid_in_cache(DOM_SID *sid, fstring name, enum SID_NAME_USE *type)
+{
+ fstring sid_str;
+ uint32 rid;
+ DOM_SID domain_sid;
+ struct winbindd_name name_ret;
+ struct winbindd_domain *domain;
- if (!get_any_dc_name(lp_workgroup(),
- server_state.controller)) {
- DEBUG(3, ("could not find any domain controllers "
- "for domain %s\n", lp_workgroup()));
- return;
- }
+ /* Split sid into domain sid and user rid */
+ sid_copy(&domain_sid, sid);
+ sid_split_rid(&domain_sid, &rid);
- /* Initialise password database and sids */
-
- /* server_state.pwdb_initialised = pwdb_initialise(False); */
- server_state.pwdb_initialised = True;
+ if ((domain = find_domain_from_sid(&domain_sid)) == NULL)
+ return False;
- if (!server_state.pwdb_initialised) {
- DEBUG(3, ("could not initialise pwdb\n"));
- return;
- }
- }
+ sid_to_string(sid_str, sid);
- /* Open lsa handle if it isn't already open */
-
- if (!server_state.lsa_handle_open) {
-
- server_state.lsa_handle_open =
- wb_lsa_open_policy(server_state.controller,
- False, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &server_state.lsa_handle);
-
- if (!server_state.lsa_handle_open) {
- DEBUG(0, ("error opening lsa handle on dc %s\n",
- server_state.controller));
- return;
- }
+ if (!winbindd_fetch_name_cache_entry(domain, sid_str, &name_ret))
+ return False;
- /* Now we can talk to the server we can get some info */
+ fstrcpy( name, name_ret.name );
+ *type = (enum SID_NAME_USE)name_ret.type;
- get_trusted_domains();
- }
+ DEBUG(10,("winbindd_lookup_name_by_sid_in_cache: Cache hit for SID = %s, name %s\n",
+ sid_str, name ));
- debug_conn_state();
+ return True;
}
-/* Connect to a domain controller using get_any_dc_name() to discover
- the domain name and sid */
+/* Lookup a sid in a domain from a name */
-BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
+BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid, enum SID_NAME_USE *type)
{
- fstring level5_dom;
- BOOL res;
- uint32 enum_ctx = 0;
- uint32 num_doms = 0;
- char **domains = NULL;
- DOM_SID *sids = NULL;
-
- if (domain == NULL) {
- return False;
- }
-
- DEBUG(1, ("looking up sid for domain %s\n", domain_name));
-
- /* Get controller name for domain */
+ int num_sids = 0, num_names = 1;
+ DOM_SID *sids = NULL;
+ uint32 *types = NULL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+ TALLOC_CTX *mem_ctx;
+ BOOL rv = False;
+
+ /* Don't bother with machine accounts */
+
+ if (name[strlen(name) - 1] == '$')
+ return False;
- if (!get_any_dc_name(domain_name, domain->controller)) {
- DEBUG(0, ("Could not resolve domain controller for domain %s\n",
- domain_name));
- return False;
- }
+ /* First check cache. */
+ if (winbindd_lookup_sid_by_name_in_cache(name, sid, type)) {
+ if (*type == SID_NAME_USE_NONE)
+ return False; /* Negative cache hit. */
+ return True;
+ }
- /* Do a level 5 query info policy if we are looking up our own SID */
+ /* Lookup name */
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ goto done;
+
+ result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol,
+ num_names, (char **)&name, &sids,
+ &types, &num_sids);
+
+ /* Return rid and type if lookup successful */
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ /* Return sid */
+
+ if ((sid != NULL) && (sids != NULL))
+ sid_copy(sid, &sids[0]);
+
+ /* Return name type */
+
+ if ((type != NULL) && (types != NULL))
+ *type = types[0];
+
+ /* Store the forward and reverse map of this lookup in the cache. */
+ store_sid_by_name_in_cache(name, &sids[0], types[0]);
+ store_name_by_sid_in_cache(&sids[0], name, types[0]);
+ } else {
+ /* JRA. Here's where we add the -ve cache store with a name type of SID_NAME_USE_NONE. */
+ DOM_SID nullsid;
+
+ ZERO_STRUCT(nullsid);
+ store_sid_by_name_in_cache(name, &nullsid, SID_NAME_USE_NONE);
+ *type = SID_NAME_UNKNOWN;
+ }
- if (strequal(domain_name, lp_workgroup())) {
- return wb_lsa_query_info_pol(&server_state.lsa_handle, 0x05,
- level5_dom, &domain->sid);
- }
+ rv = NT_STATUS_IS_OK(result);
- /* Use lsaenumdomains to get sid for this domain */
-
- res = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
- &num_doms, &domains, &sids);
-
- /* Look for domain name */
-
- if (res && domains && sids) {
- int found = False;
- int i;
-
- for(i = 0; i < num_doms; i++) {
- if (strequal(domain_name, domains[i])) {
- sid_copy(&domain->sid, &sids[i]);
- found = True;
- break;
- }
- }
-
- res = found;
- }
-
- return res;
+ done:
+ talloc_destroy(mem_ctx);
+
+ return rv;
}
-/* Lookup domain controller and sid for a domain */
-
-BOOL get_domain_info(struct winbindd_domain *domain)
+/**
+ * @brief Lookup a name in a domain from a sid.
+ *
+ * @param sid Security ID you want to look up.
+ *
+ * @param name On success, set to the name corresponding to @p sid.
+ *
+ * @param type On success, contains the type of name: alias, group or
+ * user.
+ *
+ * @retval True if the name exists, in which case @p name and @p type
+ * are set, otherwise False.
+ **/
+BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
+ fstring name,
+ enum SID_NAME_USE *type)
{
- fstring sid_str;
-
- DEBUG(1, ("Getting domain info for domain %s\n", domain->name));
+ int num_sids = 1, num_names = 0;
+ uint32 *types = NULL;
+ char **names;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+ TALLOC_CTX *mem_ctx;
+ BOOL rv = False;
+
+ /* First check cache. */
+ if (winbindd_lookup_name_by_sid_in_cache(sid, name, type)) {
+ if (*type == SID_NAME_USE_NONE) {
+ fstrcpy(name, name_deadbeef);
+ *type = SID_NAME_UNKNOWN;
+ return False; /* Negative cache hit. */
+ } else
+ return True;
+ }
- /* Lookup domain sid */
+ /* Lookup name */
- if (!lookup_domain_sid(domain->name, domain)) {
- DEBUG(0, ("could not find sid for domain %s\n", domain->name));
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ goto done;
+
+ result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
+ num_sids, sid, &names, &types,
+ &num_names);
- /* Could be a DC failure - shut down connections to this domain */
+ /* Return name and type if successful */
+
+ if ((rv = NT_STATUS_IS_OK(result))) {
+
+ /* Return name */
+
+ if ((names != NULL) && (name != NULL))
+ fstrcpy(name, names[0]);
+
+ /* Return name type */
+
+ if ((type != NULL) && (types != NULL))
+ *type = types[0];
+
+ store_sid_by_name_in_cache(names[0], sid, types[0]);
+ store_name_by_sid_in_cache(sid, names[0], types[0]);
+ } else {
+ /* OK, so we tried to look up a name in this sid, and
+ * didn't find it. Therefore add a negative cache
+ * entry. */
+ store_name_by_sid_in_cache(sid, "", SID_NAME_USE_NONE);
+ *type = SID_NAME_UNKNOWN;
+ fstrcpy(name, name_deadbeef);
+ }
- winbindd_kill_connections(domain);
+
+ done:
+ talloc_destroy(mem_ctx);
- return False;
- }
-
- /* Lookup OK */
+ return rv;
+}
- domain->got_domain_info = 1;
+/* Lookup user information from a rid */
- sid_to_string(sid_str, &domain->sid);
- DEBUG(1, ("found sid %s for domain %s\n", sid_str, domain->name));
+BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx, uint32 user_rid,
+ SAM_USERINFO_CTR **user_info)
+{
+ CLI_POLICY_HND *hnd;
+ uint16 info_level = 0x15;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ POLICY_HND dom_pol, user_pol;
+ BOOL got_dom_pol = False, got_user_pol = False;
- return True;
-}
+ /* Get sam handle */
-/* Lookup a sid in a domain from a name */
+ if (!(hnd = cm_get_sam_handle(domain->name)))
+ goto done;
-BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- int num_sids = 0, num_names = 1;
- DOM_SID *sids = NULL;
- uint32 *types = NULL;
- BOOL res;
+ /* Get domain handle */
- /* Don't bother with machine accounts */
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ des_access, &domain->sid, &dom_pol);
- if (name[strlen(name) - 1] == '$') {
- return False;
- }
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- /* Lookup name */
+ got_dom_pol = True;
- res = wb_lsa_lookup_names(&server_state.lsa_handle, num_names,
- (char **)&name, &sids, &types, &num_sids);
+ /* Get user handle */
- /* Return rid and type if lookup successful */
+ result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
+ des_access, user_rid, &user_pol);
- if (res) {
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- /* Return sid */
+ /* Get user info */
- if ((sid != NULL) && (sids != NULL)) {
- sid_copy(sid, &sids[0]);
- }
+ result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
+ info_level, user_info);
- /* Return name type */
+ cli_samr_close(hnd->cli, mem_ctx, &user_pol);
- if ((type != NULL) && (types != NULL)) {
- *type = types[0];
- }
- }
-
- return res;
-}
+ done:
+ /* Clean up policy handles */
-/* Lookup a name in a domain from a sid */
+ if (got_user_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &user_pol);
-BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
- enum SID_NAME_USE *type)
-{
- int num_sids = 1, num_names = 0;
- uint32 *types = NULL;
- char **names;
- BOOL res;
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
- /* Lookup name */
+ return NT_STATUS_IS_OK(result);
+}
- res = wb_lsa_lookup_sids(&server_state.lsa_handle, num_sids, sid,
- &names, &types, &num_names);
+/* Lookup groups a user is a member of. I wish Unix had a call like this! */
- /* Return name and type if successful */
+BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 user_rid, uint32 *num_groups,
+ DOM_GID **user_groups)
+{
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND dom_pol, user_pol;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ BOOL got_dom_pol = False, got_user_pol = False;
- if (res) {
+ /* Get sam handle */
- /* Return name */
+ if (!(hnd = cm_get_sam_handle(domain->name)))
+ goto done;
- if ((names != NULL) && (name != NULL)) {
- fstrcpy(name, names[0]);
- }
+ /* Get domain handle */
- /* Return name type */
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ des_access, &domain->sid, &dom_pol);
- if ((type != NULL) && (types != NULL)) {
- *type = types[0];
- }
- }
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- return res;
-}
+ got_dom_pol = True;
-/* Lookup user information from a rid */
+ /* Get user handle */
-BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
- uint32 user_rid, SAM_USERINFO_CTR **user_info)
-{
- return wb_get_samr_query_userinfo(&domain->sam_dom_handle, 0x15,
- user_rid, user_info);
-}
+ result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
+ des_access, user_rid, &user_pol);
-/* Lookup groups a user is a member of. I wish Unix had a call like this! */
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
-BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
- uint32 user_rid, uint32 *num_groups,
- DOM_GID **user_groups)
-{
- POLICY_HND user_pol;
- BOOL result;
+ got_user_pol = True;
- if (!wb_samr_open_user(&domain->sam_dom_handle,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- user_rid, &user_pol)) {
- return False;
- }
+ /* Query user rids */
- if (cli_samr_query_usergroups(domain->sam_dom_handle.cli,
- domain->sam_dom_handle.mem_ctx,
- &user_pol, num_groups, user_groups)
- != NT_STATUS_OK) {
- result = False;
- goto done;
- }
+ result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
+ num_groups, user_groups);
- result = True;
+ done:
-done:
- cli_samr_close(domain->sam_dom_handle.cli,
- domain->sam_dom_handle.mem_ctx, &user_pol);
+ /* Clean up policy handles */
- return True;
-}
+ if (got_user_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &user_pol);
-/* Lookup group information from a rid */
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
-BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
- uint32 group_rid, GROUP_INFO_CTR *info)
-{
- return wb_get_samr_query_groupinfo(&domain->sam_dom_handle, 1,
- group_rid, info);
+ return NT_STATUS_IS_OK(result);
}
-/* Lookup group membership given a rid */
+/* Lookup group membership given a rid. */
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
- enum SID_NAME_USE **name_types)
+ uint32 **name_types)
{
- return wb_sam_query_groupmem(&domain->sam_dom_handle, group_rid,
- num_names, rid_mem, names, name_types);
-}
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 i, total_names = 0;
+ POLICY_HND dom_pol, group_pol;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ BOOL got_dom_pol = False, got_group_pol = False;
-/* Globals for domain list stuff */
+ /* Get sam handle */
-struct winbindd_domain *domain_list = NULL;
+ if (!(hnd = cm_get_sam_handle(domain->name)))
+ goto done;
-/* Given a domain name, return the struct winbindd domain info for it
- if it is actually working. */
+ /* Get domain handle */
-struct winbindd_domain *find_domain_from_name(char *domain_name)
-{
- struct winbindd_domain *tmp;
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ des_access, &domain->sid, &dom_pol);
- /* Search through list */
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (strcmp(domain_name, tmp->name) == 0) {
+ got_dom_pol = True;
- if (!tmp->got_domain_info) {
- get_domain_info(tmp);
- }
+ /* Get group handle */
- return tmp->got_domain_info ? tmp : NULL;
- }
- }
+ result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
+ des_access, group_rid, &group_pol);
- /* Not found */
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- return NULL;
-}
+ got_group_pol = True;
-/* Given a domain name, return the struct winbindd domain info for it */
+ /* Step #1: Get a list of user rids that are the members of the
+ group. */
-struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
-{
- struct winbindd_domain *tmp;
+ result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
+ &group_pol, num_names, rid_mem,
+ name_types);
- /* Search through list */
- for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (sid_equal(sid, &tmp->sid)) {
- if (!tmp->got_domain_info) return NULL;
- return tmp;
- }
- }
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- /* Not found */
- return NULL;
-}
+ /* Step #2: Convert list of rids into list of usernames. Do this
+ in bunches of ~1000 to avoid crashing NT4. It looks like there
+ is a buffer overflow or something like that lurking around
+ somewhere. */
-/* Free state information held for {set,get,end}{pw,gr}ent() functions */
+#define MAX_LOOKUP_RIDS 900
-void free_getent_state(struct getent_state *state)
-{
- struct getent_state *temp;
+ *names = talloc(mem_ctx, *num_names * sizeof(char *));
+ *name_types = talloc(mem_ctx, *num_names * sizeof(uint32));
- /* Iterate over state list */
+ for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
+ int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
+ uint32 tmp_num_names = 0;
+ char **tmp_names = NULL;
+ uint32 *tmp_types = NULL;
- temp = state;
+ /* Lookup a chunk of rids */
- while(temp != NULL) {
- struct getent_state *next;
+ result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
+ &dom_pol, 1000, /* flags */
+ num_lookup_rids,
+ &(*rid_mem)[i],
+ &tmp_num_names,
+ &tmp_names, &tmp_types);
- /* Free sam entries then list entry */
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
- safe_free(state->sam_entries);
- DLIST_REMOVE(state, state);
- next = temp->next;
+ /* Copy result into array. The talloc system will take
+ care of freeing the temporary arrays later on. */
- free(temp);
- temp = next;
- }
-}
+ memcpy(&(*names)[i], tmp_names, sizeof(char *) *
+ tmp_num_names);
-/* Parse list of arguments to winbind uid or winbind gid parameters */
+ memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
+ tmp_num_names);
-static BOOL parse_id_list(char *paramstr, BOOL is_user)
-{
- uid_t id_low, id_high = 0;
+ total_names += tmp_num_names;
+ }
- /* Give a nicer error message if no parameters specified */
+ *num_names = total_names;
- if (strequal(paramstr, "")) {
- DEBUG(0, ("winbind %s parameter missing\n", is_user ? "uid" : "gid"));
- return False;
- }
-
- /* Parse entry */
+ done:
+ if (got_group_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &group_pol);
- if (sscanf(paramstr, "%u-%u", &id_low, &id_high) != 2) {
- DEBUG(0, ("winbind %s parameter invalid\n",
- is_user ? "uid" : "gid"));
- return False;
- }
-
- /* Store id info */
-
- if (is_user) {
- server_state.uid_low = id_low;
- server_state.uid_high = id_high;
- } else {
- server_state.gid_low = id_low;
- server_state.gid_high = id_high;
- }
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
- return True;
+ return NT_STATUS_IS_OK(result);
}
-/* Initialise trusted domain info */
-
-BOOL winbindd_param_init(void)
+BOOL create_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol)
{
- /* Parse winbind uid and winbind_gid parameters */
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ TALLOC_CTX *mem_ctx = talloc_init();
- if (!(parse_id_list(lp_winbind_uid(), True) &&
- parse_id_list(lp_winbind_gid(), False))) {
- return False;
- }
-
- /* Check for reversed uid and gid ranges */
-
- if (server_state.uid_low > server_state.uid_high) {
- DEBUG(0, ("uid range invalid\n"));
- return False;
- }
-
- if (server_state.gid_low > server_state.gid_high) {
- DEBUG(0, ("gid range invalid\n"));
- return False;
- }
-
- return True;
-}
+ ZERO_STRUCTP(pdom_pol);
-/* Convert a enum winbindd_cmd to a string */
+ if (!mem_ctx)
+ return False;
-struct cmdstr_table {
- enum winbindd_cmd cmd;
- char *desc;
-};
+ /* Get sam handle */
-static struct cmdstr_table cmdstr_table[] = {
-
- /* User functions */
+ if (!(hnd = cm_get_sam_handle(domain->name))) {
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+ /* Get domain handle */
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ des_access, &domain->sid, pdom_pol);
- { WINBINDD_GETPWNAM_FROM_USER, "getpwnam from user" },
- { WINBINDD_GETPWNAM_FROM_UID, "getpwnam from uid" },
- { WINBINDD_SETPWENT, "setpwent" },
- { WINBINDD_ENDPWENT, "endpwent" },
- { WINBINDD_GETPWENT, "getpwent" },
- { WINBINDD_GETGROUPS, "getgroups" },
+ talloc_destroy(mem_ctx);
+ if (!NT_STATUS_IS_OK(result))
+ return False;
- /* Group functions */
+ return True;
+}
- { WINBINDD_GETGRNAM_FROM_GROUP, "getgrnam from group" },
- { WINBINDD_GETGRNAM_FROM_GID, "getgrnam from gid" },
- { WINBINDD_SETGRENT, "setgrent" },
- { WINBINDD_ENDGRENT, "endgrent" },
- { WINBINDD_GETGRENT, "getgrent" },
+void close_samr_domain_handle(struct winbindd_domain *domain, POLICY_HND *pdom_pol)
+{
+ static POLICY_HND zero_pol;
+ CLI_POLICY_HND *hnd;
+ TALLOC_CTX *mem_ctx = talloc_init();
- /* PAM auth functions */
+ if (!mem_ctx)
+ return;
- { WINBINDD_PAM_AUTH, "pam auth" },
- { WINBINDD_PAM_CHAUTHTOK, "pam chauthtok" },
+ if (memcmp(pdom_pol, &zero_pol, sizeof(zero_pol)) == 0)
+ return;
- /* List things */
+ if (!(hnd = cm_get_sam_handle(domain->name))) {
+ talloc_destroy(mem_ctx);
+ return;
+ }
- { WINBINDD_LIST_USERS, "list users" },
- { WINBINDD_LIST_GROUPS, "list groups" },
- { WINBINDD_LIST_TRUSTDOM, "list trusted domains" },
+ cli_samr_close(hnd->cli, mem_ctx, pdom_pol);
+ ZERO_STRUCTP(pdom_pol);
- /* SID related functions */
+ talloc_destroy(mem_ctx);
+}
- { WINBINDD_LOOKUPSID, "lookup sid" },
- { WINBINDD_LOOKUPNAME, "lookup name" },
+/* Free state information held for {set,get,end}{pw,gr}ent() functions */
- /* S*RS related functions */
+void free_getent_state(struct getent_state *state)
+{
+ struct getent_state *temp;
- { WINBINDD_SID_TO_UID, "sid to uid" },
- { WINBINDD_SID_TO_GID, "sid to gid " },
- { WINBINDD_GID_TO_SID, "gid to sid" },
- { WINBINDD_UID_TO_SID, "uid to sid" },
+ /* Iterate over state list */
- /* Miscellaneous other stuff */
+ temp = state;
- { WINBINDD_CHECK_MACHACC, "check machine acct pw" },
+ while(temp != NULL) {
+ struct getent_state *next;
- /* End of list */
+ /* Close SAMR cache handle. */
+ close_samr_domain_handle(temp->domain, &temp->dom_pol);
- { WINBINDD_NUM_CMDS, NULL }
-};
+ /* Free sam entries then list entry */
-char *winbindd_cmd_to_string(enum winbindd_cmd cmd)
-{
- struct cmdstr_table *table = cmdstr_table;
- char *result = NULL;
+ SAFE_FREE(state->sam_entries);
+ DLIST_REMOVE(state, state);
+ next = temp->next;
- for(table = cmdstr_table; table->desc; table++) {
- if (cmd == table->cmd) {
- result = table->desc;
- break;
- }
- }
-
- if (result == NULL) {
- result = "invalid command";
+ SAFE_FREE(temp);
+ temp = next;
}
+}
- return result;
-};
+struct getent_state *create_getent_state(struct winbindd_domain *domain)
+{
+ struct getent_state *state = (struct getent_state *)malloc(sizeof(struct getent_state));
-/* find the sequence number for a domain */
+ if (state == NULL)
+ return NULL;
-uint32 domain_sequence_number(char *domain_name)
-{
- struct winbindd_domain *domain;
- SAM_UNK_CTR ctr;
+ ZERO_STRUCTP(state);
+ state->domain = domain;
- domain = find_domain_from_name(domain_name);
- if (!domain) return DOM_SEQUENCE_NONE;
+ /* Create and cache a SAMR domain handle. */
+ if (!create_samr_domain_handle(state->domain, &state->dom_pol)) {
+ free_getent_state(state);
+ return NULL;
+ }
- if (!wb_samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
+ return state;
+}
- /* If this fails, something bad has gone wrong */
+/* Initialise trusted domain info */
- winbindd_kill_connections(domain);
+BOOL winbindd_param_init(void)
+{
+ /* Parse winbind uid and winbind_gid parameters */
- DEBUG(2,("domain sequence query failed\n"));
- return DOM_SEQUENCE_NONE;
- }
+ if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
+ DEBUG(0, ("winbind uid range missing or invalid\n"));
+ return False;
+ }
- DEBUG(4,("got domain sequence number for %s of %u\n",
- domain_name, (unsigned)ctr.info.inf2.seq_num));
-
- return ctr.info.inf2.seq_num;
+ if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
+ DEBUG(0, ("winbind gid range missing or invalid\n"));
+ return False;
+ }
+
+ return True;
}
/* Query display info for a domain. This returns enough information plus a
bit extra to give an overview of domain users for the User Manager
application. */
-uint32 winbindd_query_dispinfo(struct winbindd_domain *domain,
- uint32 *start_ndx, uint16 info_level,
- uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
+NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx, POLICY_HND *pdom_pol,
+ uint32 *start_ndx, uint16 info_level,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
{
- uint32 status;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ /* Get sam handle */
- status = wb_samr_query_dispinfo(&domain->sam_dom_handle, start_ndx,
- info_level, num_entries, ctr);
+ if (!(hnd = cm_get_sam_handle(domain->name)))
+ return NT_STATUS_UNSUCCESSFUL;
- return status;
+ /* Query display info */
+
+ result = cli_samr_query_dispinfo(hnd->cli, mem_ctx,
+ pdom_pol, start_ndx, info_level,
+ num_entries, 0xffff, ctr);
+
+ return result;
}
/* Check if a domain is present in a comma-separated list of domains */
@@ -886,32 +893,25 @@ BOOL check_domain_env(char *domain_env, char *domain)
char *tmp = domain_env;
while(next_token(&tmp, name, ",", sizeof(fstring))) {
- if (strequal(name, domain)) {
+ if (strequal(name, domain))
return True;
- }
}
return False;
}
-
/* Parse a string of the form DOMAIN/user into a domain and a user */
-void parse_domain_user(char *domuser, fstring domain, fstring user)
+BOOL parse_domain_user(char *domuser, fstring domain, fstring user)
{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
- }
+ char *p = strchr(domuser,*lp_winbind_separator());
+
+ if (!p)
+ return False;
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
strupper(domain);
+ return True;
}
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index d6e316ddaaa..a645172e53d 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -23,14 +23,19 @@
#define NO_SYSLOG
#include "includes.h"
-#include <nss.h>
+#ifdef HAVE_NS_API_H
+#undef VOLATILE
-extern int DEBUGLEVEL;
+#include <ns_daemon.h>
+#endif
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
+static int initialised;
+
+
/* Use our own create socket code so we don't recurse.... */
static int wins_lookup_open_socket_in(void)
@@ -58,31 +63,64 @@ static int wins_lookup_open_socket_in(void)
/* now we've got a socket - we need to bind it */
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
+ if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) {
+ close(res);
return(-1);
+ }
+
+ set_socket_options(res,"SO_BROADCAST");
return res;
}
-struct in_addr *lookup_backend(const char *name, int *count)
+
+static void nss_wins_init(void)
+{
+ initialised = 1;
+ DEBUGLEVEL = 10;
+
+ /* needed for lp_xx() functions */
+ charset_initialise();
+
+ TimeInit();
+ setup_logging("nss_wins",False);
+ lp_load(CONFIGFILE,True,False,False);
+ load_interfaces();
+ codepage_initialise(lp_client_code_page());
+}
+
+static struct node_status *lookup_byaddr_backend(char *addr, int *count)
+{
+ int fd;
+ struct in_addr ip;
+ struct nmb_name nname;
+ struct node_status *status;
+
+ if (!initialised) {
+ nss_wins_init();
+ }
+
+ fd = wins_lookup_open_socket_in();
+ if (fd == -1)
+ return NULL;
+
+ make_nmb_name(&nname, "*", 0);
+ ip = *interpret_addr2(addr);
+ status = node_status_query(fd,&nname,ip, count);
+
+ close(fd);
+ return status;
+}
+
+static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd;
- static int initialised;
struct in_addr *ret = NULL;
struct in_addr p;
int j;
if (!initialised) {
- initialised = 1;
- DEBUGLEVEL = 0;
-
- /* needed for lp_xx() functions */
- charset_initialise();
-
- TimeInit();
- setup_logging("nss_wins",True);
- lp_load(CONFIGFILE,True,False,False);
- load_interfaces();
+ nss_wins_init();
}
*count = 0;
@@ -91,15 +129,6 @@ struct in_addr *lookup_backend(const char *name, int *count)
if (fd == -1)
return NULL;
- set_socket_options(fd,"SO_BROADCAST");
-
-/* The next four lines commented out by JHT
- and replaced with the four lines following */
-/* if( !zero_ip( wins_ip ) ) {
- * ret = name_query( fd, name, 0x20, False, True, wins_src_ip(), count );
- * goto out;
- * }
- */
p = wins_srv_ip();
if( !zero_ip(p) ) {
ret = name_query(fd,name,0x20,False,True, p, count);
@@ -128,11 +157,121 @@ struct in_addr *lookup_backend(const char *name, int *count)
}
+#ifdef HAVE_NS_API_H
+/* IRIX version */
+
+int init(void)
+{
+ nsd_logprintf(NSD_LOG_MIN, "entering init (wins)\n");
+ nss_wins_init();
+ return NSD_OK;
+}
+
+int lookup(nsd_file_t *rq)
+{
+ char *map;
+ char *key;
+ char *addr;
+ struct in_addr *ip_list;
+ struct node_status *status;
+ int i, count, len, size;
+ char response[1024];
+ BOOL found = False;
+
+ nsd_logprintf(NSD_LOG_MIN, "entering lookup (wins)\n");
+ if (! rq)
+ return NSD_ERROR;
+
+ map = nsd_attr_fetch_string(rq->f_attrs, "table", (char*)0);
+ if (! map) {
+ rq->f_status = NS_FATAL;
+ return NSD_ERROR;
+ }
+
+ key = nsd_attr_fetch_string(rq->f_attrs, "key", (char*)0);
+ if (! key || ! *key) {
+ rq->f_status = NS_FATAL;
+ return NSD_ERROR;
+ }
+
+ response[0] = '\0';
+ len = sizeof(response) - 2;
+
+ /*
+ * response needs to be a string of the following format
+ * ip_address[ ip_address]*\tname[ alias]*
+ */
+ if (strcasecmp(map,"hosts.byaddr") == 0) {
+ if ( status = lookup_byaddr_backend(key, &count)) {
+ size = strlen(key) + 1;
+ if (size > len) {
+ SAFE_FREE(status);
+ return NSD_ERROR;
+ }
+ len -= size;
+ strncat(response,key,size);
+ strncat(response,"\t",1);
+ for (i = 0; i < count; i++) {
+ /* ignore group names */
+ if (status[i].flags & 0x80) continue;
+ if (status[i].type == 0x20) {
+ size = sizeof(status[i].name) + 1;
+ if (size > len) {
+ SAFE_FREE(status);
+ return NSD_ERROR;
+ }
+ len -= size;
+ strncat(response, status[i].name, size);
+ strncat(response, " ", 1);
+ found = True;
+ }
+ }
+ response[strlen(response)-1] = '\n';
+ SAFE_FREE(status);
+ }
+ } else if (strcasecmp(map,"hosts.byname") == 0) {
+ if (ip_list = lookup_byname_backend(key, &count)) {
+ for (i = count; i ; i--) {
+ addr = inet_ntoa(ip_list[i-1]);
+ size = strlen(addr) + 1;
+ if (size > len) {
+ SAFE_FREE(ip_list);
+ return NSD_ERROR;
+ }
+ len -= size;
+ if (i != 0)
+ response[strlen(response)-1] = ' ';
+ strncat(response,addr,size);
+ strncat(response,"\t",1);
+ }
+ size = strlen(key) + 1;
+ if (size > len) {
+ SAFE_FREE(ip_list);
+ return NSD_ERROR;
+ }
+ strncat(response,key,size);
+ strncat(response,"\n",1);
+ found = True;
+ SAFE_FREE(ip_list);
+ }
+ }
+
+ if (found) {
+ nsd_logprintf(NSD_LOG_LOW, "lookup (wins %s) %s\n",map,response);
+ nsd_set_result(rq,NS_SUCCESS,response,strlen(response),VOLATILE);
+ return NSD_OK;
+ }
+ nsd_logprintf(NSD_LOG_LOW, "lookup (wins) not found\n");
+ rq->f_status = NS_NOTFOUND;
+ return NSD_NEXT;
+}
+
+#else
/****************************************************************************
gethostbyname() - we ignore any domain portion of the name and only
handle names that are at most 15 characters long
**************************************************************************/
-enum nss_status
+NSS_STATUS
_nss_wins_gethostbyname_r(const char *name, struct hostent *he,
char *buffer, size_t buflen, int *errnop,
int *h_errnop)
@@ -144,7 +283,7 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
memset(he, '\0', sizeof(*he));
- ip_list = lookup_backend(name, &count);
+ ip_list = lookup_byname_backend(name, &count);
if (!ip_list) {
return NSS_STATUS_NOTFOUND;
}
@@ -171,11 +310,12 @@ _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
host_addresses++;
}
- if (ip_list)
- free(ip_list);
+ SAFE_FREE(ip_list);
memcpy(buffer, name, namelen);
he->h_name = buffer;
return NSS_STATUS_SUCCESS;
}
+#endif
+
diff --git a/source/pam_smbpass/pam_smb_auth.c b/source/pam_smbpass/pam_smb_auth.c
index 739b1653eeb..a4f784701c3 100644
--- a/source/pam_smbpass/pam_smb_auth.c
+++ b/source/pam_smbpass/pam_smb_auth.c
@@ -45,7 +45,7 @@ do { \
} while (0)
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
- const char *name, SAM_ACCOUNT *sampass);
+ const char *name, SAM_ACCOUNT *sampass, BOOL exist);
/*
* pam_sm_authenticate() authenticates users against the samba password file.
@@ -64,6 +64,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
SAM_ACCOUNT *sampass = NULL;
extern BOOL in_client;
const char *name;
+ BOOL found;
/* Points to memory managed by the PAM library. Do not free. */
char *p = NULL;
@@ -101,15 +102,15 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
pdb_init_sam(&sampass);
- pdb_getsampwnam( sampass, name );
+ found = pdb_getsampwnam( sampass, name );
if (on( SMB_MIGRATE, ctrl )) {
- retval = _smb_add_user(pamh, ctrl, name, sampass);
+ retval = _smb_add_user(pamh, ctrl, name, sampass, found);
pdb_free_sam(sampass);
AUTH_RETURN;
}
- if (sampass == NULL) {
+ if (!found) {
_log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
retval = PAM_USER_UNKNOWN;
pdb_free_sam(sampass);
@@ -158,7 +159,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
pam_get_data(pamh, "smb_setcred_return", (const void **) &pretval);
if(pretval) {
retval = *pretval;
- free(pretval);
+ SAFE_FREE(pretval);
}
pam_set_data(pamh, "smb_setcred_return", NULL, NULL);
@@ -168,7 +169,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
/* Helper function for adding a user to the db. */
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
- const char *name, SAM_ACCOUNT *sampass)
+ const char *name, SAM_ACCOUNT *sampass, BOOL exist)
{
pstring err_str;
pstring msg_str;
@@ -190,7 +191,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
}
/* Add the user to the db if they aren't already there. */
- if (sampass == NULL) {
+ if (!exist) {
retval = local_password_change( name, LOCAL_ADD_USER,
pass, err_str,
sizeof(err_str),
@@ -208,8 +209,8 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
pass = NULL;
return PAM_IGNORE;
- }
-
+ }
+ else {
/* Change the user's password IFF it's null. */
if ((pdb_get_lanman_passwd(sampass) == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
{
@@ -226,6 +227,8 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
}
}
+ }
+
pass = NULL;
return PAM_IGNORE;
diff --git a/source/pam_smbpass/pam_smb_passwd.c b/source/pam_smbpass/pam_smb_passwd.c
index 2281c1dfd1d..da96f375d5a 100644
--- a/source/pam_smbpass/pam_smb_passwd.c
+++ b/source/pam_smbpass/pam_smb_passwd.c
@@ -167,7 +167,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
set( SMB__OLD_PASSWD, ctrl );
retval = _smb_read_password( pamh, ctrl, Announce, "Current SMB password: ",
NULL, _SMB_OLD_AUTHTOK, &pass_old );
- free( Announce );
+ SAFE_FREE( Announce );
if (retval != PAM_SUCCESS) {
_log_err( LOG_NOTICE
@@ -191,13 +191,15 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
} else if (flags & PAM_UPDATE_AUTHTOK) {
+#if 0
+ /* We used to return when this flag was set, but that breaks
+ password synchronization when /other/ tokens are expired. For
+ now, we change the password whenever we're asked. SRL */
if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) {
- /* NOTE: there is currently no support for password expiring
- under Samba. Support will be added here when it becomes
- available. */
pdb_free_sam(sampass);
return PAM_SUCCESS;
}
+#endif
/*
* obtain the proposed password
*/
diff --git a/source/pam_smbpass/support.c b/source/pam_smbpass/support.c
index 5042c33b268..3f5d52cdef2 100644
--- a/source/pam_smbpass/support.c
+++ b/source/pam_smbpass/support.c
@@ -216,12 +216,13 @@ void _cleanup( pam_handle_t * pamh, void *x, int error_status )
x = _pam_delete( (char *) x );
}
-/*
+/* JHT
+ *
* Safe duplication of character strings. "Paranoid"; don't leave
* evidence of old token around for later stack analysis.
+ *
*/
-
-char * xstrdup( const char *x )
+char * smbpXstrDup( const char *x )
{
register char *new = NULL;
@@ -231,7 +232,7 @@ char * xstrdup( const char *x )
for (i = 0; x[i]; ++i); /* length of string */
if ((new = malloc(++i)) == NULL) {
i = 0;
- _log_err( LOG_CRIT, "out of memory in xstrdup" );
+ _log_err( LOG_CRIT, "out of memory in smbpXstrDup" );
} else {
while (i-- > 0) {
new[i] = x[i];
@@ -292,7 +293,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err )
}
_pam_delete( failure->agent ); /* tidy up */
_pam_delete( failure->user ); /* tidy up */
- free( failure );
+ SAFE_FREE( failure );
}
}
@@ -414,9 +415,9 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
, pdb_get_uid(sampass) );
new->count = 1;
}
- new->user = xstrdup( name );
+ new->user = smbpXstrDup( name );
new->id = pdb_get_uid(sampass);
- new->agent = xstrdup( uidtoname( getuid() ) );
+ new->agent = smbpXstrDup( uidtoname( getuid() ) );
pam_set_data( pamh, data_name, new, _cleanup_failures );
} else {
@@ -556,7 +557,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
if (retval == PAM_SUCCESS) { /* a good conversation */
- token = xstrdup(resp[j++].resp);
+ token = smbpXstrDup(resp[j++].resp);
if (token != NULL) {
if (expect == 2) {
/* verify that password entered correctly */
@@ -625,10 +626,10 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
return PAM_SUCCESS;
}
-int _pam_smb_approve_pass(pam_handle_t * pamh
- ,unsigned int ctrl
- ,const char *pass_old
- ,const char *pass_new)
+int _pam_smb_approve_pass(pam_handle_t * pamh,
+ unsigned int ctrl,
+ const char *pass_old,
+ const char *pass_new )
{
/* Further checks should be handled through module stacking. -SRL */
diff --git a/source/pam_smbpass/support.h b/source/pam_smbpass/support.h
index 779e2df15ef..01178698913 100644
--- a/source/pam_smbpass/support.h
+++ b/source/pam_smbpass/support.h
@@ -12,7 +12,7 @@ extern void _cleanup(pam_handle_t *, void *, int);
* evidence of old token around for later stack analysis.
*/
-extern char *xstrdup(const char *);
+extern char *smbpXstrDup(const char *);
/* ************************************************************** *
* Useful non-trivial functions *
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index b5f4044e817..db7c5140799 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -73,6 +73,7 @@ extern pstring user_socket_options;
extern pstring global_myname;
pstring global_scope = "";
+
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
#endif
@@ -277,6 +278,7 @@ typedef struct
BOOL bHostMSDfs;
BOOL bHideLocalUsers;
BOOL bUseMmap;
+ BOOL bUnixExtensions;
}
global;
@@ -373,6 +375,7 @@ typedef struct
BOOL bLocking;
BOOL bStrictLocking;
BOOL bPosixLocking;
+ BOOL bShareModes;
BOOL bOpLocks;
BOOL bLevel2OpLocks;
BOOL bOnlyUser;
@@ -395,6 +398,7 @@ typedef struct
BOOL bInheritPerms;
BOOL bMSDfsRoot;
BOOL bUseClientDriver;
+ BOOL bDefaultDevmode;
BOOL bNTAclSupport;
char dummy[3]; /* for alignment */
@@ -488,6 +492,7 @@ static service sDefault = {
True, /* bLocking */
False, /* bStrictLocking */
True, /* bPosixLocking */
+ True, /* bShareModes */
True, /* bOpLocks */
True, /* bLevel2OpLocks */
False, /* bOnlyUser */
@@ -510,6 +515,7 @@ static service sDefault = {
False, /* bInheritPerms */
False, /* bMSDfsRoot */
False, /* bUseClientDriver */
+ False, /* bDefaultDevmode */
True, /* bNTAclSupport */
"" /* dummy */
@@ -538,7 +544,8 @@ static BOOL handle_client_code_page(char *pszParmValue, char **ptr);
static BOOL handle_vfs_object(char *pszParmValue, char **ptr);
static BOOL handle_source_env(char *pszParmValue, char **ptr);
static BOOL handle_netbios_name(char *pszParmValue, char **ptr);
-static BOOL handle_winbind_id(char *pszParmValue, char **ptr);
+static BOOL handle_winbind_uid(char *pszParmValue, char **ptr);
+static BOOL handle_winbind_gid(char *pszParmValue, char **ptr);
static BOOL handle_wins_server_list(char *pszParmValue, char **ptr);
static BOOL handle_debug_list( char *pszParmValue, char **ptr );
@@ -593,6 +600,7 @@ static struct enum_list enum_ldap_ssl[] = {
{LDAP_SSL_OFF, "off"},
{LDAP_SSL_OFF, "Off"},
{LDAP_SSL_START_TLS, "start tls"},
+ {LDAP_SSL_START_TLS, "start_tls"},
{-1, NULL}
};
#endif
@@ -826,6 +834,7 @@ static struct parm_struct parm_table[] = {
{"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},
{"Tuning Options", P_SEP, P_SEPARATOR},
@@ -879,6 +888,7 @@ static struct parm_struct parm_table[] = {
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT|FLAG_DOS_STRING},
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_DOS_STRING},
{"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},
{"printer driver file", P_STRING, P_LOCAL, &sDefault.szDriverFile, NULL, NULL, FLAG_PRINT},
{"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
@@ -964,6 +974,7 @@ static struct parm_struct parm_table[] = {
{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
#ifdef WITH_LDAP_SAM
{"Ldap Options", P_SEP, P_SEPARATOR},
@@ -1046,8 +1057,8 @@ static struct parm_struct parm_table[] = {
{"Winbind options", P_SEP, P_SEPARATOR},
- {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_id, NULL, 0},
- {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_id, NULL, 0},
+ {"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},
@@ -1315,6 +1326,7 @@ static void init_globals(void)
#else
Globals.bUseMmap = True;
#endif
+ Globals.bUnixExtensions = False;
#ifdef WITH_SSL
Globals.sslVersion = SMB_SSL_V23;
@@ -1341,8 +1353,8 @@ static void init_globals(void)
string_set(&Globals.szLdapSuffix, "");
string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
string_set(&Globals.szLdapAdminDn, "");
- Globals.ldap_port = 389;
- Globals.ldap_ssl = LDAP_SSL_OFF;
+ Globals.ldap_port = 636;
+ Globals.ldap_ssl = LDAP_SSL_ON;
#endif /* WITH_LDAP_SAM */
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -1508,8 +1520,6 @@ FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
FN_GLOBAL_STRING(lp_domain_admin_group, &Globals.szDomainAdminGroup)
FN_GLOBAL_STRING(lp_domain_guest_group, &Globals.szDomainGuestGroup)
-FN_GLOBAL_STRING(lp_winbind_uid, &Globals.szWinbindUID)
-FN_GLOBAL_STRING(lp_winbind_gid, &Globals.szWinbindGID)
FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
@@ -1589,6 +1599,7 @@ FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
+FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
@@ -1682,6 +1693,7 @@ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_locking, bLocking)
FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
+FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
@@ -1703,6 +1715,7 @@ FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
+FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
@@ -1762,11 +1775,7 @@ static void free_service(service * pservice)
pservice->szService));
string_free(&pservice->szService);
- if (pservice->copymap)
- {
- free(pservice->copymap);
- pservice->copymap = NULL;
- }
+ SAFE_FREE(pservice->copymap);
for (i = 0; parm_table[i].label; i++)
if ((parm_table[i].type == P_STRING ||
@@ -1792,6 +1801,7 @@ static int add_a_service(service * pservice, char *name)
tservice = *pservice;
/* it might already exist */
+
if (name)
{
i = getservicebyname(name, NULL);
@@ -2517,21 +2527,72 @@ static BOOL handle_copy(char *pszParmValue, char **ptr)
***************************************************************************/
-/* Do some simple checks on "winbind [ug]id" parameter value */
+/* Some lp_ routines to return winbind [ug]id information */
+
+static uid_t winbind_uid_low, winbind_uid_high;
+static gid_t winbind_gid_low, winbind_gid_high;
+
+BOOL lp_winbind_uid(uid_t *low, uid_t *high)
+{
+ if (winbind_uid_low == 0 || winbind_uid_high == 0)
+ return False;
+
+ if (low)
+ *low = winbind_uid_low;
-static BOOL handle_winbind_id(char *pszParmValue, char **ptr)
+ if (high)
+ *high = winbind_uid_high;
+
+ return True;
+}
+
+BOOL lp_winbind_gid(gid_t *low, gid_t *high)
+{
+ if (winbind_gid_low == 0 || winbind_gid_high == 0)
+ return False;
+
+ if (low)
+ *low = winbind_gid_low;
+
+ if (high)
+ *high = winbind_gid_high;
+
+ return True;
+}
+
+/* Do some simple checks on "winbind [ug]id" parameter values */
+
+static BOOL handle_winbind_uid(char *pszParmValue, char **ptr)
{
int low, high;
- if (sscanf(pszParmValue, "%d-%d", &low, &high) != 2)
- {
+ if (sscanf(pszParmValue, "%d-%d", &low, &high) != 2 || high < low)
return False;
- }
/* Parse OK */
string_set(ptr, pszParmValue);
+ winbind_uid_low = low;
+ winbind_uid_high = high;
+
+ return True;
+}
+
+static BOOL handle_winbind_gid(char *pszParmValue, char **ptr)
+{
+ gid_t low, high;
+
+ if (sscanf(pszParmValue, "%d-%d", &low, &high) != 2 || high < low)
+ return False;
+
+ /* Parse OK */
+
+ string_set(ptr, pszParmValue);
+
+ winbind_gid_low = low;
+ winbind_gid_high = high;
+
return True;
}
@@ -2566,8 +2627,7 @@ initialise a copymap
static void init_copymap(service * pservice)
{
int i;
- if (pservice->copymap)
- free(pservice->copymap);
+ SAFE_FREE(pservice->copymap);
pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
if (!pservice->copymap)
DEBUG(0,
@@ -3110,17 +3170,18 @@ static void dump_copy_map(BOOL *pcopymap)
#endif
/***************************************************************************
-Return TRUE if the passed service number is within range.
+ Return TRUE if the passed service number is within range.
***************************************************************************/
+
BOOL lp_snum_ok(int iService)
{
return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
}
-
/***************************************************************************
-auto-load some home services
+ Auto-load some home services.
***************************************************************************/
+
static void lp_add_auto_services(char *str)
{
char *s;
@@ -3136,34 +3197,30 @@ static void lp_add_auto_services(char *str)
homes = lp_servicenumber(HOMES_NAME);
- for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP))
- {
- char *home = get_user_home_dir(p);
+ for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
+ char *home = get_user_service_home_dir(p);
if (lp_servicenumber(p) >= 0)
continue;
if (home && homes >= 0)
- {
lp_add_home(p, homes, home);
- }
}
- free(s);
+ SAFE_FREE(s);
}
/***************************************************************************
-auto-load one printer
+ Auto-load one printer.
***************************************************************************/
+
void lp_add_one_printer(char *name, char *comment)
{
int printers = lp_servicenumber(PRINTERS_NAME);
int i;
- if (lp_servicenumber(name) < 0)
- {
+ if (lp_servicenumber(name) < 0) {
lp_add_printer(name, printers);
- if ((i = lp_servicenumber(name)) >= 0)
- {
+ if ((i = lp_servicenumber(name)) >= 0) {
string_set(&ServicePtrs[i]->comment, comment);
unix_to_dos(ServicePtrs[i]->comment, True);
ServicePtrs[i]->autoloaded = True;
@@ -3430,16 +3487,26 @@ does not copy the found service.
int lp_servicenumber(char *pszServiceName)
{
int iService;
+ fstring serviceName;
+
for (iService = iNumServices - 1; iService >= 0; iService--)
- if (VALID(iService) && ServicePtrs[iService]->szService &&
- strequal(ServicePtrs[iService]->szService, pszServiceName))
- break;
+ {
+ if (VALID(iService) && ServicePtrs[iService]->szService)
+ {
+ /*
+ * The substitution here is used to support %U is
+ * service names
+ */
+ fstrcpy(serviceName, ServicePtrs[iService]->szService);
+ standard_sub_basic(serviceName);
+ if (strequal(serviceName, pszServiceName))
+ break;
+ }
+ }
if (iService < 0)
- DEBUG(7,
- ("lp_servicenumber: couldn't find %s\n",
- pszServiceName));
+ DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
return (iService);
}
@@ -3687,3 +3754,24 @@ void get_private_directory(pstring priv_dir)
p = strrchr(priv_dir, '/');
if (p) *p = 0;
}
+
+/***********************************************************
+ Allow daemons such as winbindd to fix their logfile name.
+************************************************************/
+
+void lp_set_logfile(const char *name)
+{
+ extern pstring debugf;
+ string_set(&Globals.szLogFile, name);
+ pstrcpy(debugf, name);
+}
+
+/*******************************************************************
+ Return the NetBIOS called name.
+********************************************************************/
+
+const char *get_called_name(void)
+{
+ extern fstring local_machine;
+ return (*local_machine) ? local_machine : global_myname;
+}
diff --git a/source/param/params.c b/source/param/params.c
index 2bc32f1c66d..a7d50601768 100644
--- a/source/param/params.c
+++ b/source/param/params.c
@@ -98,8 +98,6 @@
* bSize - The size of the global buffer <bufr>.
*/
-extern int DEBUGLEVEL;
-
static char *bufr = NULL;
static int bSize = 0;
@@ -121,8 +119,8 @@ static int mygetc(myFILE *f)
static void myfile_close(myFILE *f)
{
if (!f) return;
- if (f->buf) free(f->buf);
- free(f);
+ SAFE_FREE(f->buf);
+ SAFE_FREE(f);
}
/* -------------------------------------------------------------------------- **
@@ -198,7 +196,7 @@ static int Continuation( char *line, int pos )
int pos2 = 0;
pos--;
- while( (pos >= 0) && isspace(line[pos]) )
+ while( (pos >= 0) && isspace((int)line[pos]) )
pos--;
/* we should recognize if `\` is part of a multibyte character or not. */
@@ -438,7 +436,7 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(char *, char *), int c )
c = 0;
else
{
- for( end = i; (end >= 0) && isspace(bufr[end]); end-- )
+ for( end = i; (end >= 0) && isspace((int)bufr[end]); end-- )
;
c = mygetc( InFile );
}
@@ -543,7 +541,7 @@ static myFILE *OpenConfFile( char *FileName )
DEBUG( lvl,
("%s Unable to open configuration file \"%s\":\n\t%s\n",
func, FileName, strerror(errno)) );
- free(ret);
+ SAFE_FREE(ret);
return NULL;
}
@@ -593,7 +591,7 @@ BOOL pm_process( char *FileName,
return( False );
}
result = Parse( InFile, sfunc, pfunc );
- free( bufr );
+ SAFE_FREE( bufr );
bufr = NULL;
bSize = 0;
}
diff --git a/source/passdb/pampass.c b/source/passdb/pampass.c
index dd9d38f66c3..018eae3a07e 100644
--- a/source/passdb/pampass.c
+++ b/source/passdb/pampass.c
@@ -30,8 +30,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#ifdef WITH_PAM
/*******************************************************************
@@ -49,9 +47,9 @@ extern int DEBUGLEVEL;
*/
struct smb_pam_userdata {
- char *PAM_username;
- char *PAM_password;
- char *PAM_newpassword;
+ const char *PAM_username;
+ const char *PAM_password;
+ const char *PAM_newpassword;
};
typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr);
@@ -83,12 +81,13 @@ static BOOL smb_pam_error_handler(pam_handle_t *pamh, int pam_error, char *msg,
*********************************************************************/
static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
- char *msg, int dbglvl, uint32 *nt_status)
+ char *msg, int dbglvl,
+ NTSTATUS *nt_status)
{
if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
return True;
- if (*nt_status == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(*nt_status)) {
/* Complain LOUDLY */
DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
@@ -158,7 +157,7 @@ static int smb_pam_conv(int num_msg,
default:
/* Must be an error of some sort... */
- free(reply);
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
}
@@ -181,7 +180,7 @@ static void special_char_sub(char *buf)
all_string_sub(buf, "\\t", "\t", 0);
}
-static void pwd_sub(char *buf, char *username, char *oldpass, char *newpass)
+static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass)
{
pstring_sub(buf, "%u", username);
all_string_sub(buf, "%o", oldpass, sizeof(fstring));
@@ -249,7 +248,7 @@ static void free_pw_chat(struct chat_struct *list)
while (list) {
struct chat_struct *old_head = list;
DLIST_REMOVE(list, list);
- free(old_head);
+ SAFE_FREE(old_head);
}
}
@@ -324,8 +323,7 @@ static int smb_pam_passchange_conv(int num_msg,
if (!found) {
DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
break;
@@ -357,8 +355,7 @@ static int smb_pam_passchange_conv(int num_msg,
if (!found) {
DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg));
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
break;
@@ -375,8 +372,7 @@ static int smb_pam_passchange_conv(int num_msg,
default:
/* Must be an error of some sort... */
free_pw_chat(pw_chat);
- free(reply);
- reply = NULL;
+ SAFE_FREE(reply);
return PAM_CONV_ERR;
}
}
@@ -394,24 +390,24 @@ static int smb_pam_passchange_conv(int num_msg,
static void smb_free_pam_conv(struct pam_conv *pconv)
{
if (pconv)
- safe_free(pconv->appdata_ptr);
+ SAFE_FREE(pconv->appdata_ptr);
- safe_free(pconv);
+ SAFE_FREE(pconv);
}
/***************************************************************************
Allocate a pam_conv struct.
****************************************************************************/
-static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, char *user,
- char *passwd, char *newpass)
+static struct pam_conv *smb_setup_pam_conv(smb_pam_conv_fn smb_pam_conv_fnptr, const char *user,
+ const char *passwd, const char *newpass)
{
struct pam_conv *pconv = (struct pam_conv *)malloc(sizeof(struct pam_conv));
struct smb_pam_userdata *udp = (struct smb_pam_userdata *)malloc(sizeof(struct smb_pam_userdata));
if (pconv == NULL || udp == NULL) {
- safe_free(pconv);
- safe_free(udp);
+ SAFE_FREE(pconv);
+ SAFE_FREE(udp);
return NULL;
}
@@ -449,9 +445,10 @@ static BOOL smb_pam_end(pam_handle_t *pamh, struct pam_conv *smb_pam_conv_ptr)
* Start PAM authentication for specified account
*/
-static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct pam_conv *pconv)
+static BOOL smb_pam_start(pam_handle_t **pamh, const char *user, const char *rhost, struct pam_conv *pconv)
{
int pam_error;
+ const char *our_rhost;
*pamh = (pam_handle_t *)NULL;
@@ -464,14 +461,16 @@ static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct p
}
if (rhost == NULL) {
- rhost = client_name();
+ our_rhost = client_name();
if (strequal(rhost,"UNKNOWN"))
- rhost = client_addr();
+ our_rhost = client_addr();
+ } else {
+ our_rhost = rhost;
}
#ifdef PAM_RHOST
- DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost));
- pam_error = pam_set_item(*pamh, PAM_RHOST, rhost);
+ DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", our_rhost));
+ pam_error = pam_set_item(*pamh, PAM_RHOST, our_rhost);
if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) {
smb_pam_end(*pamh, pconv);
*pamh = (pam_handle_t *)NULL;
@@ -494,10 +493,10 @@ static BOOL smb_pam_start(pam_handle_t **pamh, char *user, char *rhost, struct p
/*
* PAM Authentication Handler
*/
-static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
+static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
/*
* To enable debugging set in /etc/pam.d/samba:
@@ -548,10 +547,10 @@ static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
/*
* PAM Account Handler
*/
-static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
+static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
DEBUG(4,("smb_pam_account: PAM: Account Management for User: %s\n", user));
pam_error = pam_acct_mgmt(pamh, PAM_SILENT); /* Is user account enabled? */
@@ -594,10 +593,10 @@ static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
* PAM Credential Setting
*/
-static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user)
+static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user)
{
int pam_error;
- uint32 nt_status = NT_STATUS_NO_TOKEN;
+ NTSTATUS nt_status = NT_STATUS_NO_TOKEN;
/*
* This will allow samba to aquire a kerberos token. And, when
@@ -668,7 +667,7 @@ static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty,
* Internal PAM Password Changer.
*/
-static BOOL smb_pam_chauthtok(pam_handle_t *pamh, char * user)
+static BOOL smb_pam_chauthtok(pam_handle_t *pamh, const char * user)
{
int pam_error;
@@ -778,9 +777,9 @@ BOOL smb_pam_close_session(char *user, char *tty, char *rhost)
* PAM Externally accessible Account handler
*/
-uint32 smb_pam_accountcheck(char * user)
+NTSTATUS smb_pam_accountcheck(const char * user)
{
- uint32 nt_status = NT_STATUS_ACCOUNT_DISABLED;
+ NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED;
pam_handle_t *pamh = NULL;
struct pam_conv *pconv = NULL;
@@ -790,12 +789,12 @@ uint32 smb_pam_accountcheck(char * user)
return NT_STATUS_OK;
if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
- return False;
+ return NT_STATUS_NO_MEMORY;
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_ACCOUNT_DISABLED;
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK)
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user)))
DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
smb_pam_end(pamh, pconv);
@@ -806,10 +805,10 @@ uint32 smb_pam_accountcheck(char * user)
* PAM Password Validation Suite
*/
-uint32 smb_pam_passcheck(char * user, char * password)
+NTSTATUS smb_pam_passcheck(char * user, char * password)
{
pam_handle_t *pamh = NULL;
- uint32 nt_status = NT_STATUS_LOGON_FAILURE;
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
struct pam_conv *pconv = NULL;
/*
@@ -824,19 +823,19 @@ uint32 smb_pam_passcheck(char * user, char * password)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_LOGON_FAILURE;
- if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_auth(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_account(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(nt_status = smb_pam_setcred(pamh, user))) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
@@ -850,7 +849,7 @@ uint32 smb_pam_passcheck(char * user, char * password)
* PAM Password Change Suite
*/
-BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
+BOOL smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword)
{
/* Appropriate quantities of root should be obtained BEFORE calling this function */
struct pam_conv *pconv = NULL;
@@ -874,19 +873,19 @@ BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
#else
/* If PAM not used, no PAM restrictions on accounts. */
- uint32 smb_pam_accountcheck(char * user)
+NTSTATUS smb_pam_accountcheck(const char * user)
{
return NT_STATUS_OK;
}
/* If PAM not used, also no PAM restrictions on sessions. */
- BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
+BOOL smb_pam_claim_session(char *user, char *tty, char *rhost)
{
return True;
}
/* If PAM not used, also no PAM restrictions on sessions. */
- BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
+BOOL smb_pam_close_session(char *in_user, char *tty, char *rhost)
{
return True;
}
diff --git a/source/passdb/pass_check.c b/source/passdb/pass_check.c
index b3e762741fc..2437aa0d53e 100644
--- a/source/passdb/pass_check.c
+++ b/source/passdb/pass_check.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* these are kept here to keep the string_combinations function simple */
static fstring this_user;
static fstring this_salt;
@@ -233,7 +231,7 @@ static BOOL dfs_auth(char *user, char *password)
}
/*
- * NB. I'd like to change these to call something like become_user()
+ * NB. I'd like to change these to call something like change_to_user()
* instead but currently we don't have a connection
* context to become the correct user. This is already
* fairly platform specific code however, so I think
@@ -599,7 +597,7 @@ static BOOL password_check(char *password)
{
#ifdef WITH_PAM
- return (smb_pam_passcheck(this_user, password) == NT_STATUS_OK);
+ return (NT_STATUS_IS_OK(smb_pam_passcheck(this_user, password)));
#endif /* WITH_PAM */
#ifdef WITH_AFS
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 37da884a67f..fd2a678a268 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -23,8 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
* This is set on startup - it defines the SID for this
* machine, and therefore the SAM database for which it is
@@ -78,6 +76,9 @@ static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user)
}
ZERO_STRUCTP(user);
+
+ user->init_flag = FLAG_SAM_UNINIT;
+ user->uid = user->gid = -1;
user->logon_time = (time_t)0;
user->pass_last_set_time = (time_t)0;
user->pass_can_change_time = (time_t)0;
@@ -138,14 +139,15 @@ BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd)
return False;
}
+
pdb_set_username(*new_sam_acct, pwd->pw_name);
pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
pdb_set_uid(*new_sam_acct, pwd->pw_uid);
pdb_set_gid(*new_sam_acct, pwd->pw_gid);
- pdb_set_profile_path(*new_sam_acct, lp_logon_path());
- pdb_set_homedir(*new_sam_acct, lp_logon_home());
- pdb_set_dir_drive(*new_sam_acct, lp_logon_drive());
- pdb_set_logon_script(*new_sam_acct, lp_logon_script());
+ pdb_set_profile_path(*new_sam_acct, lp_logon_path(), False);
+ pdb_set_homedir(*new_sam_acct, lp_logon_home(), False);
+ pdb_set_dir_drive(*new_sam_acct, lp_logon_drive(), False);
+ pdb_set_logon_script(*new_sam_acct, lp_logon_script(), False);
return True;
}
@@ -826,8 +828,11 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
to->unknown_6 = from->unknown_6;
}
+#if 0 /* JERRY */
/*************************************************************
Copies a SAM_ACCOUNT.
+ FIXME!!!! This is broken as SAM_ACCOUNT contains two
+ pointers. --jerry
**************************************************************/
void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
@@ -836,7 +841,10 @@ void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
return;
memcpy(to, from, sizeof(SAM_ACCOUNT));
-}
+
+
+}
+#endif
/*************************************************************
Change a password entry in the local smbpasswd file.
@@ -875,6 +883,16 @@ account without a valid local system user.\n", user_name);
/* Get the smb passwd entry for this user */
pdb_init_sam(&sam_pass);
+ if(local_flags & LOCAL_DELETE_USER) {
+ if (!pdb_delete_sam_account(user_name)) {
+ slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return True;
+ }
if(!pdb_getsampwnam(sam_pass, user_name)) {
pdb_free_sam(sam_pass);
@@ -905,6 +923,9 @@ account without a valid local system user.\n", user_name);
}
}
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sam_pass, time(NULL));
+
if (pdb_add_sam_account(sam_pass)) {
slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
pdb_free_sam(sam_pass);
@@ -936,7 +957,6 @@ account without a valid local system user.\n", user_name);
pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
} else if (local_flags & LOCAL_SET_NO_PASSWORD) {
pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
-
/* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
if (!pdb_set_lanman_passwd (sam_pass, NULL)) {
pdb_free_sam(sam_pass);
@@ -965,26 +985,17 @@ account without a valid local system user.\n", user_name);
}
}
- if(local_flags & LOCAL_DELETE_USER) {
- if (!pdb_delete_sam_account(user_name)) {
- slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
- pdb_free_sam(sam_pass);
- return False;
- }
- slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
- } else {
- if(!pdb_update_sam_account(sam_pass, True)) {
- slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
- pdb_free_sam(sam_pass);
- return False;
- }
- if(local_flags & LOCAL_DISABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
- else if (local_flags & LOCAL_ENABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
- else if (local_flags & LOCAL_SET_NO_PASSWORD)
- slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
+ if(!pdb_update_sam_account(sam_pass, True)) {
+ slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
}
+ if(local_flags & LOCAL_DISABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_ENABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_SET_NO_PASSWORD)
+ slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
pdb_free_sam(sam_pass);
return True;
@@ -1314,7 +1325,7 @@ BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
return True;
}
-BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
+BOOL pdb_set_logon_divs (SAM_ACCOUNT *sampass, uint16 hours)
{
if (!sampass)
return False;
@@ -1323,12 +1334,24 @@ BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
return True;
}
+BOOL pdb_set_init_flag (SAM_ACCOUNT *sampass, uint32 flag)
+{
+ if (!sampass)
+ return False;
+
+ sampass->init_flag |= flag;
+
+ return True;
+}
+
BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
{
if (!sampass)
return False;
sampass->uid = uid;
+ sampass->init_flag |= FLAG_SAM_UID;
+
return True;
}
@@ -1337,7 +1360,9 @@ BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
if (!sampass)
return False;
- sampass->gid = gid;
+ sampass->gid = gid;
+ sampass->init_flag |= FLAG_SAM_GID;
+
return True;
}
@@ -1371,7 +1396,7 @@ BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
if (!username)
return False;
- StrnCpy (sampass->username, username, strlen(username));
+ StrnCpy (sampass->username, username, sizeof(sampass->username)-1);
return True;
}
@@ -1388,7 +1413,7 @@ BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
if (!domain)
return False;
- StrnCpy (sampass->domain, domain, strlen(domain));
+ StrnCpy (sampass->domain, domain, sizeof(sampass->domain)-1);
return True;
}
@@ -1405,7 +1430,7 @@ BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
if (!nt_username)
return False;
- StrnCpy (sampass->nt_username, nt_username, strlen(nt_username));
+ StrnCpy (sampass->nt_username, nt_username, sizeof(sampass->nt_username) -1);
return True;
}
@@ -1422,7 +1447,7 @@ BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
if (!fullname)
return False;
- StrnCpy (sampass->full_name, fullname, strlen(fullname));
+ StrnCpy (sampass->full_name, fullname, sizeof(sampass->full_name)-1);
return True;
}
@@ -1431,7 +1456,7 @@ BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
Set the user's logon script.
********************************************************************/
-BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script, BOOL store)
{
if (!sampass)
return False;
@@ -1439,7 +1464,10 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
if (!logon_script)
return False;
- StrnCpy (sampass->logon_script, logon_script, strlen(logon_script));
+ StrnCpy (sampass->logon_script, logon_script, sizeof(sampass->logon_script)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT);
return True;
}
@@ -1448,7 +1476,7 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
Set the user's profile path.
********************************************************************/
-BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path, BOOL store)
{
if (!sampass)
return False;
@@ -1456,7 +1484,10 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
if (!profile_path)
return False;
- StrnCpy (sampass->profile_path, profile_path, strlen(profile_path));
+ StrnCpy (sampass->profile_path, profile_path, sizeof(sampass->profile_path)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_PROFILE);
return True;
}
@@ -1465,7 +1496,7 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
Set the user's directory drive.
********************************************************************/
-BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive, BOOL store)
{
if (!sampass)
return False;
@@ -1473,7 +1504,10 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
if (!dir_drive)
return False;
- StrnCpy (sampass->dir_drive, dir_drive, strlen(dir_drive));
+ StrnCpy (sampass->dir_drive, dir_drive, sizeof(sampass->dir_drive)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_DRIVE);
return True;
}
@@ -1482,7 +1516,7 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
Set the user's home directory.
********************************************************************/
-BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir, BOOL store)
{
if (!sampass)
return False;
@@ -1490,7 +1524,10 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
if (!homedir)
return False;
- StrnCpy (sampass->home_dir, homedir, strlen(homedir));
+ StrnCpy (sampass->home_dir, homedir, sizeof(sampass->home_dir)-1);
+
+ if (store)
+ pdb_set_init_flag(sampass, FLAG_SAM_SMBHOME);
return True;
}
@@ -1507,7 +1544,7 @@ BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
if (!acct_desc)
return False;
- StrnCpy (sampass->acct_desc, acct_desc, strlen(acct_desc));
+ StrnCpy (sampass->acct_desc, acct_desc, sizeof(sampass->acct_desc)-1);
return True;
}
@@ -1524,7 +1561,7 @@ BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
if (!workstations)
return False;
- StrnCpy (sampass->workstations, workstations, strlen(workstations));
+ StrnCpy (sampass->workstations, workstations, sizeof(sampass->workstations)-1);
return True;
}
@@ -1541,7 +1578,7 @@ BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
if (!munged_dial)
return False;
- StrnCpy (sampass->munged_dial, munged_dial, strlen(munged_dial));
+ StrnCpy (sampass->munged_dial, munged_dial, sizeof(sampass->munged_dial)-1);
return True;
}
@@ -1555,6 +1592,9 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
if (!sampass)
return False;
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sampass, time(NULL));
+
if (!pwd) {
/* Allow setting to NULL */
SAFE_FREE(sampass->nt_pw);
@@ -1583,6 +1623,9 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
if (!sampass)
return False;
+ /* Remember to set the "last changed time". */
+ pdb_set_pass_last_set_time(sampass, time(NULL));
+
if (!pwd) {
/* Allow setting to NULL */
SAFE_FREE(sampass->lm_pw);
@@ -1666,3 +1709,34 @@ BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
return True;
}
+
+/***************************************************************************
+ Search by uid. Wrapper around pdb_getsampwnam()
+ **************************************************************************/
+
+BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
+{
+ struct passwd *pw;
+ fstring name;
+
+ if (user==NULL) {
+ DEBUG(0,("pdb_getsampwuid: SAM_ACCOUNT is NULL.\n"));
+ return False;
+ }
+
+ /*
+ * Never trust the uid in the passdb. Lookup the username first
+ * and then lokup the user by name in the sam.
+ */
+
+ if ((pw=sys_getpwuid(uid)) == NULL) {
+ DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist in Unix accounts!\n", uid));
+ return False;
+ }
+
+ fstrcpy (name, pw->pw_name);
+
+ return pdb_getsampwnam (user, name);
+
+}
+
diff --git a/source/passdb/passgrp.c b/source/passdb/passgrp.c
index 399a45d8a9a..fe5b181e33c 100644
--- a/source/passdb/passgrp.c
+++ b/source/passdb/passgrp.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
* NOTE. All these functions are abstracted into a structure
* that points to the correct function for the selected database. JRA.
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 1a1dc0915ea..3b7b8123eb6 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -2,6 +2,7 @@
Unix SMB/Netbios implementation.
Version 2.9.
LDAP protocol helper functions for SAMBA
+ Copyright (C) Gerald Carter 2001
Copyright (C) Shahms King 2001
Copyright (C) Jean François Micouleau 1998
@@ -51,10 +52,7 @@
#define SAM_ACCOUNT struct sam_passwd
#endif
-extern int DEBUGLEVEL;
-
-struct ldap_enum_info
-{
+struct ldap_enum_info {
LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
@@ -63,16 +61,24 @@ struct ldap_enum_info
static struct ldap_enum_info global_ldap_ent;
+extern pstring samlogon_user;
+extern BOOL sam_logon_in_ssb;
+
+
/*******************************************************************
open a connection to the ldap server.
******************************************************************/
-static BOOL
-ldap_open_connection (LDAP ** ldap_struct)
+static BOOL ldap_open_connection (LDAP ** ldap_struct)
{
int port;
int version, rc;
int tls = LDAP_OPT_X_TLS_HARD;
+ if (geteuid() != 0) {
+ DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
+ return False;
+ }
+
if (lp_ldap_ssl() == LDAP_SSL_ON && lp_ldap_port() == 389) {
port = 636;
}
@@ -82,7 +88,7 @@ ldap_open_connection (LDAP ** ldap_struct)
if ((*ldap_struct = ldap_init(lp_ldap_server(), port)) == NULL) {
DEBUG(0, ("The LDAP server is not responding !\n"));
- return (False);
+ return False;
}
/* Connect to older servers using SSL and V2 rather than Start TLS */
@@ -110,25 +116,31 @@ ldap_open_connection (LDAP ** ldap_struct)
}
if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
{
- DEBUG(0,
- ("Failed to issue the StartTLS instruction: %s\n",
+ DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
ldap_err2string(rc)));
return False;
}
DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
break;
+
case LDAP_SSL_ON:
if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
{
DEBUG(0, ("Failed to setup a TLS session\n"));
}
break;
+
case LDAP_SSL_OFF:
default:
+ /*
+ * No special needs to setup options prior to the LDAP
+ * bind (which should be called next via ldap_connect_system()
+ */
+ break;
}
DEBUG(2, ("ldap_open_connection: connection opened\n"));
- return (True);
+ return True;
}
/*******************************************************************
@@ -150,15 +162,19 @@ static BOOL ldap_connect_system(LDAP * ldap_struct)
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
(OpenLDAP) doesnt' seem to support it */
+
+ DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
+ lp_ldap_admin_dn()));
+
if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
ldap_secret)) != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
- return (False);
+ return False;
}
DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
- return (True);
+ return True;
}
/*******************************************************************
@@ -171,8 +187,7 @@ static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMes
DEBUG(2, ("ldap_search_one_user: searching for:[%s]\n", filter));
- rc = ldap_search_s (ldap_struct, lp_ldap_suffix (), scope,
- filter, NULL, 0, result);
+ rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, NULL, 0, result);
if (rc != LDAP_SUCCESS) {
DEBUG(0,("ldap_search_one_user: Problem during the LDAP search: %s\n",
@@ -180,7 +195,8 @@ static int ldap_search_one_user (LDAP * ldap_struct, const char *filter, LDAPMes
DEBUG(3,("ldap_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
filter));
}
- return (rc);
+
+ return rc;
}
/*******************************************************************
@@ -192,13 +208,14 @@ static int ldap_search_one_user_by_name (LDAP * ldap_struct, const char *user,
pstring filter;
/*
- in the filter expression, replace %u with the real name
- so in ldap filter, %u MUST exist :-)
+ * in the filter expression, replace %u with the real name
+ * so in ldap filter, %u MUST exist :-)
*/
pstrcpy(filter, lp_ldap_filter());
- /* have to use this here because $ is filtered out
- * in pstring_sub
+ /*
+ * have to use this here because $ is filtered out
+ * in pstring_sub
*/
all_string_sub(filter, "%u", user, sizeof(pstring));
@@ -215,8 +232,14 @@ static int ldap_search_one_user_by_uid(LDAP * ldap_struct, int uid,
pstring filter;
/* Get the username from the system and look that up in the LDAP */
- user = sys_getpwuid(uid);
+
+ if ((user = sys_getpwuid(uid)) == NULL) {
+ DEBUG(3,("ldap_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
+ return LDAP_NO_SUCH_OBJECT;
+ }
+
pstrcpy(filter, lp_ldap_filter());
+
all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
return ldap_search_one_user(ldap_struct, filter, result);
@@ -232,6 +255,7 @@ static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid,
int rc;
/* check if the user rid exsists, if not, try searching on the uid */
+
snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
rc = ldap_search_one_user(ldap_struct, filter, result);
@@ -245,20 +269,23 @@ static int ldap_search_one_user_by_rid (LDAP * ldap_struct, uint32 rid,
/*******************************************************************
search an attribute and return the first value found.
******************************************************************/
-static void get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
+static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
char *attribute, char *value)
{
- char **valeurs;
+ char **values;
- if ((valeurs = ldap_get_values (ldap_struct, entry, attribute)) != NULL) {
- pstrcpy(value, valeurs[0]);
- ldap_value_free(valeurs);
- DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
- }
- else {
+ if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
value = NULL;
- DEBUG (2, ("get_single_attribute: [%s] = [NULL]\n", attribute));
+ DEBUG (2, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
+
+ return False;
}
+
+ pstrcpy(value, values[0]);
+ ldap_value_free(values);
+ DEBUG (2, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
+
+ return True;
}
/************************************************************************
@@ -298,7 +325,7 @@ static void make_a_mod (LDAPMod *** modlist, int modop, char *attribute, char *v
if (mods[i] == NULL)
{
- mods = (LDAPMod **) realloc (mods, (i + 2) * sizeof (LDAPMod *));
+ mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
if (mods == NULL)
{
DEBUG(0, ("make_a_mod: out of memory!\n"));
@@ -322,7 +349,7 @@ static void make_a_mod (LDAPMod *** modlist, int modop, char *attribute, char *v
if (mods[i]->mod_values != NULL) {
for (; mods[i]->mod_values[j] != NULL; j++);
}
- mods[i]->mod_values = (char **)realloc(mods[i]->mod_values,
+ mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
(j + 2) * sizeof (char *));
if (mods[i]->mod_values == NULL) {
@@ -344,123 +371,152 @@ Initialize SAM_ACCOUNT from an LDAP query
static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
LDAP * ldap_struct, LDAPMessage * entry)
{
- time_t logon_time,
+ time_t logon_time,
logoff_time,
kickoff_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time;
- static pstring username;
- static pstring domain;
- static pstring nt_username;
- static pstring fullname;
- static pstring homedir;
- static pstring dir_drive;
- static pstring logon_script;
- static pstring profile_path;
- static pstring acct_desc;
- static pstring munged_dial;
- static pstring workstations;
- struct passwd *sys_user;
- uint32 user_rid, group_rid;
- static uint8 smblmpwd[16];
- static uint8 smbntpwd[16];
- uint16 acct_ctrl, logon_divs;
- uint32 hours_len;
- uint8 *hours;
- pstring temp;
+ pstring username,
+ domain,
+ nt_username,
+ fullname,
+ homedir,
+ dir_drive,
+ logon_script,
+ profile_path,
+ acct_desc,
+ munged_dial,
+ workstations;
+ struct passwd *sys_user;
+ uint32 user_rid,
+ group_rid;
+ uint8 smblmpwd[16],
+ smbntpwd[16];
+ uint16 acct_ctrl,
+ logon_divs;
+ uint32 hours_len;
+ uint8 hours[MAX_HOURS_LEN];
+ pstring temp;
+ gid_t gid = getegid();
+
+
+ /*
+ * do a little initialization
+ */
+ username[0] = '\0';
+ domain[0] = '\0';
+ nt_username[0] = '\0';
+ fullname[0] = '\0';
+ homedir[0] = '\0';
+ dir_drive[0] = '\0';
+ logon_script[0] = '\0';
+ profile_path[0] = '\0';
+ acct_desc[0] = '\0';
+ munged_dial[0] = '\0';
+ workstations[0] = '\0';
+
get_single_attribute(ldap_struct, entry, "uid", username);
DEBUG(2, ("Entry found for user: %s\n", username));
-
+
+ pstrcpy(samlogon_user, username);
+
pstrcpy(nt_username, username);
- get_single_attribute(ldap_struct, entry, "sambaDomain", domain);
- if (!domain)
- pstrcpy(domain, lp_workgroup());
+ pstrcpy(domain, lp_workgroup());
get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
- pass_last_set_time = (time_t) strtol(temp, NULL, 16);
+ pass_last_set_time = (time_t) atol(temp);
get_single_attribute(ldap_struct, entry, "logonTime", temp);
- logon_time = (time_t) strtol(temp, NULL, 16);
+ logon_time = (time_t) atol(temp);
get_single_attribute(ldap_struct, entry, "logoffTime", temp);
- logoff_time = (time_t) strtol(temp, NULL, 16);
+ logoff_time = (time_t) atol(temp);
get_single_attribute(ldap_struct, entry, "kickoffTime", temp);
- kickoff_time = (time_t) strtol(temp, NULL, 16);
+ kickoff_time = (time_t) atol(temp);
get_single_attribute(ldap_struct, entry, "pwdCanChange", temp);
- pass_can_change_time = (time_t) strtol(temp, NULL, 16);
+ pass_can_change_time = (time_t) atol(temp);
get_single_attribute(ldap_struct, entry, "pwdMustChange", temp);
- pass_must_change_time = (time_t) strtol(temp, NULL, 16);
+ pass_must_change_time = (time_t) atol(temp);
/* recommend that 'gecos' and 'displayName' should refer to the same
- * attribute OID. userFullName depreciated, only used by Samba
- * primary rules of LDAP: don't make a new attribute when one is already defined
- * that fits your needs; using gecos then displayName then cn rather than 'userFullName'
+ * attribute OID. userFullName depreciated, only used by Samba
+ * primary rules of LDAP: don't make a new attribute when one is already defined
+ * that fits your needs; using cn then displayName rather than 'userFullName'
*/
+
+ sam_logon_in_ssb = True;
- get_single_attribute(ldap_struct, entry, "gecos", fullname);
-
- if (!fullname) {
+ if (!get_single_attribute(ldap_struct, entry, "cn", fullname)) {
get_single_attribute(ldap_struct, entry, "displayName", fullname);
- get_single_attribute(ldap_struct, entry, "cn", fullname);
}
- get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive);
- DEBUG(5,("homeDrive is set to %s\n",dir_drive));
- if (!*dir_drive) {
+
+ if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
pstrcpy(dir_drive, lp_logon_drive());
+ standard_sub_advanced(-1, username, "", gid, dir_drive);
DEBUG(5,("homeDrive fell back to %s\n",dir_drive));
+ pdb_set_dir_drive(sampass, dir_drive, False);
}
+ else
+ pdb_set_dir_drive(sampass, dir_drive, True);
- get_single_attribute(ldap_struct, entry, "smbHome", homedir);
- DEBUG(5,("smbHome is set to %s\n",homedir));
- if (!*homedir) {
+ if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
pstrcpy(homedir, lp_logon_home());
+ standard_sub_advanced(-1, username, "", gid, homedir);
DEBUG(5,("smbHome fell back to %s\n",homedir));
+ pdb_set_homedir(sampass, homedir, False);
}
+ else
+ pdb_set_homedir(sampass, homedir, True);
- get_single_attribute(ldap_struct, entry, "scriptPath", logon_script);
- DEBUG(5,("scriptPath is set to %s\n",logon_script));
- if (!*logon_script) {
+ if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
pstrcpy(logon_script, lp_logon_script());
+ standard_sub_advanced(-1, username, "", gid, logon_script);
DEBUG(5,("scriptPath fell back to %s\n",logon_script));
+ pdb_set_logon_script(sampass, logon_script, False);
}
+ else
+ pdb_set_logon_script(sampass, logon_script, True);
- get_single_attribute(ldap_struct, entry, "profilePath", profile_path);
- DEBUG(5,("profilePath is set to %s\n",profile_path));
- if (!*profile_path) {
+ if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
pstrcpy(profile_path, lp_logon_path());
+ standard_sub_advanced(-1, username, "", gid, profile_path);
DEBUG(5,("profilePath fell back to %s\n",profile_path));
+ pdb_set_profile_path(sampass, profile_path, False);
}
+ else
+ pdb_set_profile_path(sampass, profile_path, True);
+
+ sam_logon_in_ssb = False;
get_single_attribute(ldap_struct, entry, "description", acct_desc);
get_single_attribute(ldap_struct, entry, "userWorkstations", workstations);
get_single_attribute(ldap_struct, entry, "rid", temp);
- user_rid = (uint32)strtol(temp, NULL, 16);
+ user_rid = (uint32)atol(temp);
get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
- group_rid = (uint32)strtol(temp, NULL, 16);
+ group_rid = (uint32)atol(temp);
/* These values MAY be in LDAP, but they can also be retrieved through
- * sys_getpw*() which is how we're doing it (if you use nss_ldap, then
- * these values will be stored in LDAP as well, but if not, we want the
- * local values to override the LDAP for this anyway
- * homeDirectory attribute
+ * sys_getpw*() which is how we're doing it
*/
sys_user = sys_getpwnam(username);
- if (sys_user == NULL)
+ if (sys_user == NULL) {
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
return False;
+ }
/* FIXME: hours stuff should be cleaner */
+
logon_divs = 168;
hours_len = 21;
- hours = malloc(sizeof(hours) * hours_len);
memset(hours, 0xff, hours_len);
get_single_attribute (ldap_struct, entry, "lmPassword", temp);
@@ -485,7 +541,7 @@ static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
pdb_set_pass_last_set_time(sampass, pass_last_set_time);
pdb_set_hours_len(sampass, hours_len);
- pdb_set_logons_divs(sampass, logon_divs);
+ pdb_set_logon_divs(sampass, logon_divs);
pdb_set_uid(sampass, sys_user->pw_uid);
pdb_set_gid(sampass, sys_user->pw_gid);
@@ -499,13 +555,10 @@ static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass,
pdb_set_fullname(sampass, fullname);
- pdb_set_logon_script(sampass, logon_script);
- pdb_set_profile_path(sampass, profile_path);
- pdb_set_dir_drive(sampass, dir_drive);
- pdb_set_homedir(sampass, homedir);
pdb_set_acct_desc(sampass, acct_desc);
pdb_set_workstations(sampass, workstations);
pdb_set_munged_dial(sampass, munged_dial);
+
if (!pdb_set_nt_passwd(sampass, smbntpwd))
return False;
if (!pdb_set_lanman_passwd(sampass, smblmpwd))
@@ -527,6 +580,7 @@ Initialize SAM_ACCOUNT from an LDAP query
static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT * sampass)
{
pstring temp;
+ uint32 i;
*mods = NULL;
@@ -539,12 +593,6 @@ static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT *
make_a_mod(mods, ldap_state, "uid", pdb_get_username(sampass));
DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
- /* not sure about using this for the nt_username */
- make_a_mod(mods, ldap_state, "sambaDomain", pdb_get_domain(sampass));
-
- slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_uid(sampass));
- make_a_mod(mods, ldap_state, "uidNumber", temp);
-
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
make_a_mod(mods, ldap_state, "pwdLastSet", temp);
@@ -564,32 +612,52 @@ static BOOL init_ldap_from_sam (LDAPMod *** mods, int ldap_state, SAM_ACCOUNT *
make_a_mod(mods, ldap_state, "pwdMustChange", 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
- * add-user script
+ * most easily accomplished by giving them the same OID
+ * gecos isn't set here b/c it should be handled by the
+ * add-user script
*/
make_a_mod(mods, ldap_state, "displayName", pdb_get_fullname(sampass));
make_a_mod(mods, ldap_state, "cn", pdb_get_fullname(sampass));
-
- make_a_mod(mods, ldap_state, "smbHome", pdb_get_homedir(sampass));
- make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass));
- make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass));
- make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass));
make_a_mod(mods, ldap_state, "description", pdb_get_acct_desc(sampass));
make_a_mod(mods, ldap_state, "userWorkstations", pdb_get_workstations(sampass));
- slprintf(temp, sizeof(temp) - 1, "%i", sampass->user_rid);
+ /*
+ * Only updates fields which have been set (not defaults from smb.conf)
+ */
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME))
+ make_a_mod(mods, ldap_state, "smbHome", pdb_get_homedir(sampass));
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
+ make_a_mod(mods, ldap_state, "homeDrive", pdb_get_dirdrive(sampass));
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
+ make_a_mod(mods, ldap_state, "scriptPath", pdb_get_logon_script(sampass));
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE))
+ make_a_mod(mods, ldap_state, "profilePath", pdb_get_profile_path(sampass));
+
+
+ if ( !pdb_get_user_rid(sampass))
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_uid_to_user_rid(pdb_get_uid(sampass)));
+ else
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_user_rid(sampass));
make_a_mod(mods, ldap_state, "rid", temp);
- slprintf(temp, sizeof(temp) - 1, "%i", sampass->group_rid);
+ if ( !pdb_get_group_rid(sampass))
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_gid_to_group_rid(pdb_get_gid(sampass)));
+ else
+ slprintf(temp, sizeof(temp) - 1, "%i", pdb_get_group_rid(sampass));
make_a_mod(mods, ldap_state, "primaryGroupID", 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_state, "lmPassword", temp);
+
pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
make_a_mod (mods, ldap_state, "ntPassword", temp);
+
make_a_mod (mods, ldap_state, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
NEW_PW_FORMAT_SPACE_PADDED_LEN));
@@ -691,16 +759,18 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname)
ldap_unbind(ldap_struct);
return False;
}
- if (ldap_search_one_user_by_name(ldap_struct, sname, &result) !=
- LDAP_SUCCESS)
+ if (ldap_search_one_user_by_name(ldap_struct, sname, &result) != LDAP_SUCCESS)
{
ldap_unbind(ldap_struct);
return False;
}
if (ldap_count_entries(ldap_struct, result) < 1)
{
- DEBUG(0,
- ("We don't find this user [%s] count=%d\n", sname,
+ pstring filter;
+
+ pstrcpy(filter, lp_ldap_filter());
+ standard_sub_advanced(-1, sname, "", -1, filter);
+ DEBUG(0,("LDAP search \"%s\" returned %d entries.\n", filter,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
return False;
@@ -771,57 +841,9 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
}
/**********************************************************************
- Get SAM_ACCOUNT entry from LDAP by uid
-*********************************************************************/
-BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid)
-{
- LDAP *ldap_struct;
- LDAPMessage *result;
- LDAPMessage *entry;
-
- if (!ldap_open_connection(&ldap_struct))
- return False;
-
- if (!ldap_connect_system(ldap_struct))
- {
- ldap_unbind(ldap_struct);
- return False;
- }
- if (ldap_search_one_user_by_uid(ldap_struct, uid, &result) !=
- LDAP_SUCCESS)
- {
- ldap_unbind(ldap_struct);
- return False;
- }
-
- if (ldap_count_entries(ldap_struct, result) < 1)
- {
- DEBUG(0,
- ("We don't find this uid [%i] count=%d\n", uid,
- ldap_count_entries(ldap_struct, result)));
- ldap_unbind(ldap_struct);
- return False;
- }
- entry = ldap_first_entry(ldap_struct, result);
- if (entry)
- {
- init_sam_from_ldap(user, ldap_struct, entry);
- ldap_msgfree(result);
- ldap_unbind(ldap_struct);
- return True;
- }
- else
- {
- ldap_msgfree(result);
- ldap_unbind(ldap_struct);
- return False;
- }
-}
-
-
-/**********************************************************************
Delete entry from LDAP for username
*********************************************************************/
+
BOOL pdb_delete_sam_account(char *sname)
{
int rc;
@@ -830,6 +852,7 @@ BOOL pdb_delete_sam_account(char *sname)
LDAPMessage *entry;
LDAPMessage *result;
+ /* Ensure we have euid as root - else deny this. */
if (!ldap_open_connection (&ldap_struct))
return False;
@@ -873,6 +896,7 @@ BOOL pdb_delete_sam_account(char *sname)
/**********************************************************************
Update SAM_ACCOUNT
*********************************************************************/
+
BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
{
int rc;
@@ -885,8 +909,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
return False;
- if (!ldap_connect_system(ldap_struct)) /* connect as system account */
- {
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */ {
ldap_unbind(ldap_struct);
return False;
}
@@ -894,8 +917,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
rc = ldap_search_one_user_by_name(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);
@@ -909,8 +931,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
rc = ldap_modify_s(ldap_struct, dn, mods);
- if (rc != LDAP_SUCCESS)
- {
+ if (rc != LDAP_SUCCESS) {
char *ld_error;
ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
@@ -923,8 +944,7 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
return False;
}
- DEBUG(2,
- ("successfully modified uid = %s in the LDAP database\n",
+ DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
pdb_get_username(newpwd)));
ldap_mods_free(mods, 1);
ldap_unbind(ldap_struct);
@@ -934,41 +954,29 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override)
/**********************************************************************
Add SAM_ACCOUNT to LDAP
*********************************************************************/
+
BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
{
- int rc;
- pstring filter;
- LDAP *ldap_struct;
- LDAPMessage *result;
- pstring dn;
- LDAPMod **mods;
- int ldap_op = LDAP_MOD_ADD;
+ int rc;
+ pstring filter;
+ LDAP *ldap_struct;
+ LDAPMessage *result;
+ pstring dn;
+ LDAPMod **mods;
+ int ldap_op;
+ uint32 num_result;
if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
- {
return False;
- }
- if (!ldap_connect_system(ldap_struct)) /* connect as system account */
- {
+ if (!ldap_connect_system(ldap_struct)) /* connect as system account */ {
ldap_unbind(ldap_struct);
return False;
}
- if (pdb_get_username(newpwd) != NULL) {
- slprintf (dn, sizeof (dn) - 1, "uid=%s,%s",
- pdb_get_username(newpwd), lp_ldap_suffix ());
- }
- else
- {
- return False;
- }
-
-
rc = ldap_search_one_user_by_name (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,("User already in the base, with samba properties\n"));
ldap_msgfree(result);
ldap_unbind(ldap_struct);
@@ -978,21 +986,29 @@ BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
slprintf (filter, sizeof (filter) - 1, "uid=%s", pdb_get_username(newpwd));
rc = ldap_search_one_user(ldap_struct, filter, &result);
- if (ldap_count_entries(ldap_struct, result) == 1)
- {
+ num_result = ldap_count_entries(ldap_struct, result);
+
+ if (num_result > 1) {
+ DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
+ return False;
+ }
+
+ /* Check if we need to update an existing entry */
+ if (num_result == 1) {
char *tmp;
LDAPMessage *entry;
+
DEBUG(3,("User exists without samba properties: adding them\n"));
ldap_op = LDAP_MOD_REPLACE;
entry = ldap_first_entry (ldap_struct, result);
tmp = ldap_get_dn (ldap_struct, entry);
slprintf (dn, sizeof (dn) - 1, "%s", tmp);
ldap_memfree (tmp);
- }
- else
- {
- DEBUG (3, ("More than one user with that uid exists: bailing out!\n"));
- return False;
+ } else {
+ /* Check if we need to add an entry */
+ DEBUG(3,("Adding new user\n"));
+ ldap_op = LDAP_MOD_ADD;
+ slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", pdb_get_username(newpwd), lp_ldap_suffix ());
}
ldap_msgfree(result);
@@ -1002,13 +1018,11 @@ BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
if (ldap_op == LDAP_MOD_REPLACE) {
rc = ldap_modify_s(ldap_struct, dn, mods);
- }
- else {
+ } else {
rc = ldap_add_s(ldap_struct, dn, mods);
}
- if (rc != LDAP_SUCCESS)
- {
+ if (rc != LDAP_SUCCESS) {
char *ld_error;
ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
diff --git a/source/passdb/pdb_nisplus.c b/source/passdb/pdb_nisplus.c
index 990dcfbe9e0..3648fb0341a 100644
--- a/source/passdb/pdb_nisplus.c
+++ b/source/passdb/pdb_nisplus.c
@@ -325,27 +325,40 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
pstrcpy(samlogon_user, pdb_get_username(pw_buf));
get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
- if( !(home_dir && *home_dir) )
+ if( !(home_dir && *home_dir) ) {
pstrcpy(home_dir, lp_logon_home());
- pdb_set_homedir(pw_buf, home_dir);
+ 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) )
+ if( !(home_drive && *home_drive) ) {
pstrcpy(home_drive, lp_logon_drive());
- pdb_set_dir_drive(pw_buf, home_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());
- pdb_set_logon_script(pw_buf, logon_script);
+ if( !(logon_script && *logon_script) ) {
+ pstrcpy(logon_script, lp_logon_script(), False);
+ }
+ 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) )
+ 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);
- } else {
+ 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_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
}
@@ -375,7 +388,7 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
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:
+ DEBUG(0, ("malformed NT pwd entry:\
uid = %d.\n",
pdb_get_uid(pw_buf)));
return False;
@@ -385,7 +398,7 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, nis_object *obj)
}
pdb_set_unknown_3(pw_buf, 0xffffff); /* don't know */
- pdb_set_logons_divs(pw_buf, 168); /* hours per week */
+ 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);
@@ -1015,46 +1028,6 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
}
/*************************************************************************
- Routine to search the nisplus passwd file for an entry matching the username
- *************************************************************************/
-BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid)
-{
- nis_result *result;
- char *nisname;
- BOOL ret;
- char *sp, *p = lp_smb_passwd_file();
- pstring pfiletmp;
-
- if (!*p)
- {
- DEBUG(0, ("no SMB password file set\n"));
- return False;
- }
-
- 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_uid(uid, pfiletmp);
-
- DEBUG(10, ("search by uid: %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;
-}
-
-/*************************************************************************
Routine to remove entry from the nisplus smbpasswd table
*************************************************************************/
BOOL pdb_delete_sam_account(char *sname)
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index d29a4bfcaf0..6f75f879667 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -44,7 +44,6 @@ struct smb_passwd
};
-extern int DEBUGLEVEL;
extern pstring samlogon_user;
extern BOOL sam_logon_in_ssb;
extern struct passdb_ops pdb_ops;
@@ -168,7 +167,7 @@ static void *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int
DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
if((fp = sys_fopen(pfile, open_mode)) == NULL) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
+ DEBUG(2, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
return NULL;
}
@@ -1089,7 +1088,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
size_t new_entry_length;
if (strequal(name, pwd->smb_name)) {
- DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
+ DEBUG(10, ("del_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
continue;
}
@@ -1221,7 +1220,7 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, struct smb_passwd *pw_buf)
pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time);
pdb_set_domain (sam_pass, lp_workgroup());
- pdb_set_dir_drive (sam_pass, lp_logon_drive());
+ pdb_set_dir_drive (sam_pass, lp_logon_drive(), False);
/* FIXME!! What should this be set to? New smb.conf parameter maybe?
max password age? For now, we'll use the current time + 21 days.
@@ -1238,15 +1237,15 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, struct smb_passwd *pw_buf)
pstrcpy(str, lp_logon_script());
standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str);
- pdb_set_logon_script(sam_pass, str);
+ pdb_set_logon_script(sam_pass, str, False);
pstrcpy(str, lp_logon_path());
standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str);
- pdb_set_profile_path(sam_pass, str);
+ pdb_set_profile_path(sam_pass, str, False);
pstrcpy(str, lp_logon_home());
standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str);
- pdb_set_homedir(sam_pass, str);
+ pdb_set_homedir(sam_pass, str, False);
sam_logon_in_ssb = False;
} else {
@@ -1403,48 +1402,6 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, char *username)
}
-BOOL pdb_getsampwuid (SAM_ACCOUNT *sam_acct, uid_t uid)
-{
- struct smb_passwd *smb_pw;
- void *fp = NULL;
-
- DEBUG(10, ("pdb_getsampwuid: search by uid: %d\n", uid));
-
- /* Open the sam password file - not for update. */
- fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
-
- if (fp == NULL) {
- DEBUG(0, ("unable to open passdb database.\n"));
- return False;
- }
-
- while ( ((smb_pw=getsmbfilepwent(fp)) != NULL) && (smb_pw->smb_userid != uid) )
- /* do nothing */ ;
-
- endsmbfilepwent(fp, &pw_file_lock_depth);
-
- /* did we locate the username in smbpasswd */
- if (smb_pw == NULL)
- return False;
-
- DEBUG(10, ("pdb_getsampwuid: found by name: %s\n", smb_pw->smb_name));
-
- if (!sam_acct) {
- DEBUG(10,("pdb_getsampwuid:SAM_ACCOUNT is NULL\n"));
-#if 0
- smb_panic("NULL pointer passed to pdb_getsampwuid\n");
-#endif
- return False;
- }
-
- /* now build the SAM_ACCOUNT */
- if (!build_sam_account(sam_acct, smb_pw))
- return False;
-
- /* success */
- return True;
-}
-
BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
{
struct smb_passwd *smb_pw;
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 6ae7f33b0f1..219b0ee7bd6 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -82,7 +82,16 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
uint32 len = 0;
uint32 lmpwlen, ntpwlen, hourslen;
BOOL ret = True;
-
+ BOOL setflag;
+ struct passwd *pw;
+ uid_t uid;
+ gid_t gid;
+
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
+ return False;
+ }
+
/* unpack the buffer into variables */
len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
&logon_time,
@@ -120,6 +129,22 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
goto done;
}
+ /* validate the account and fill in UNIX uid and gid. Standard
+ * getpwnam() is used instead of Get_Pwnam() as we do not need
+ * to try case permutations
+ */
+ if (!username || !(pw=getpwnam(username))) {
+ DEBUG(0,("tdb_sam: getpwnam(%s) return NULL. User does not exist!\n",
+ username?username:"NULL"));
+ ret = False;
+ goto done;
+ }
+
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ pdb_set_uid(sampass, uid);
+ pdb_set_gid(sampass, gid);
+
pdb_set_logon_time(sampass, logon_time);
pdb_set_logoff_time(sampass, logoff_time);
pdb_set_kickoff_time(sampass, kickoff_time);
@@ -131,18 +156,55 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
pdb_set_domain (sampass, domain_len?domain:NULL);
pdb_set_nt_username (sampass, nt_username_len?nt_username:NULL);
pdb_set_fullname (sampass, fullname_len?fullname:NULL);
- pdb_set_homedir (sampass, homedir_len?homedir:NULL);
- pdb_set_dir_drive (sampass, dir_drive_len?dir_drive:NULL);
- pdb_set_logon_script (sampass, logon_script_len?logon_script:NULL);
- pdb_set_profile_path (sampass, profile_path_len?profile_path:NULL);
- pdb_set_acct_desc (sampass, acct_desc_len?acct_desc:NULL);
- pdb_set_workstations (sampass, workstations_len?workstations:NULL);
- pdb_set_munged_dial (sampass, munged_dial_len?munged_dial:NULL);
- if (!pdb_set_lanman_passwd(sampass, lmpwlen?lm_pw_ptr:NULL)) {
+
+ if (homedir) setflag = True;
+ else {
+ setflag = False;
+ homedir = strdup(lp_logon_home());
+ if(!homedir) { ret = False; goto done; }
+ standard_sub_advanced(-1, username, "", gid, homedir);
+ DEBUG(5,("Home directory set back to %s\n", homedir));
+ }
+ pdb_set_homedir(sampass, homedir, setflag);
+
+ if (dir_drive) setflag = True;
+ else {
+ setflag = False;
+ dir_drive = strdup(lp_logon_drive());
+ if(!dir_drive) { ret = False; goto done; }
+ standard_sub_advanced(-1, username, "", gid, dir_drive);
+ DEBUG(5,("Home directory set back to %s\n", dir_drive));
+ }
+ pdb_set_dir_drive(sampass, dir_drive, setflag);
+
+ if (logon_script) setflag = True;
+ else {
+ setflag = False;
+ logon_script = strdup(lp_logon_script());
+ if(!logon_script) { ret = False; goto done; }
+ standard_sub_advanced(-1, username, "", gid, logon_script);
+ DEBUG(5,("Home directory set back to %s\n", logon_script));
+ }
+ pdb_set_logon_script(sampass, logon_script, setflag);
+
+ if (profile_path) setflag = True;
+ else {
+ setflag = False;
+ profile_path = strdup(lp_logon_path());
+ if(!profile_path) { ret = False; goto done; }
+ standard_sub_advanced(-1, username, "", gid, profile_path);
+ DEBUG(5,("Home directory set back to %s\n", profile_path));
+ }
+ pdb_set_profile_path(sampass, profile_path, setflag);
+
+ pdb_set_acct_desc (sampass, acct_desc);
+ pdb_set_workstations (sampass, workstations);
+ pdb_set_munged_dial (sampass, munged_dial);
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
ret = False;
goto done;
}
- if (!pdb_set_nt_passwd(sampass, ntpwlen?nt_pw_ptr:NULL)) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
ret = False;
goto done;
}
@@ -156,7 +218,7 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
pdb_set_unknown_5(sampass, unknown_5);
pdb_set_unknown_6(sampass, unknown_6);
pdb_set_acct_ctrl(sampass, acct_ctrl);
- pdb_set_logons_divs(sampass, logon_divs);
+ pdb_set_logon_divs(sampass, logon_divs);
pdb_set_hours(sampass, hours);
done:
@@ -209,14 +271,16 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
- uint8 *lm_pw;
- uint8 *nt_pw;
+ const uint8 *lm_pw;
+ const uint8 *nt_pw;
uint32 lm_pw_len = 16;
uint32 nt_pw_len = 16;
/* do we have a valid SAM_ACCOUNT pointer? */
- if (sampass == NULL)
+ if (sampass == NULL) {
+ DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
return -1;
+ }
*buf = NULL;
buflen = 0;
@@ -230,71 +294,65 @@ static uint32 init_buffer_from_sam (uint8 **buf, SAM_ACCOUNT *sampass)
username = pdb_get_username(sampass);
- if (username)
- username_len = strlen(username) +1;
- else
- username_len = 0;
+ if (username) username_len = strlen(username) +1;
+ else username_len = 0;
+
domain = pdb_get_domain(sampass);
- if (domain)
- domain_len = strlen(domain) +1;
- else
- domain_len = 0;
+ if (domain) domain_len = strlen(domain) +1;
+ else domain_len = 0;
+
nt_username = pdb_get_nt_username(sampass);
- if (nt_username)
- nt_username_len = strlen(nt_username) +1;
- else
- nt_username_len = 0;
- dir_drive = pdb_get_dirdrive(sampass);
- if (dir_drive)
- dir_drive_len = strlen(dir_drive) +1;
- else
- dir_drive_len = 0;
- unknown_str = NULL;
- unknown_str_len = 0;
- munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial)
- munged_dial_len = strlen(munged_dial) +1;
- else
- munged_dial_len = 0;
-
+ if (nt_username) nt_username_len = strlen(nt_username) +1;
+ else nt_username_len = 0;
+
fullname = pdb_get_fullname(sampass);
- if (fullname)
- fullname_len = strlen(fullname) +1;
- else
- fullname_len = 0;
- homedir = pdb_get_homedir(sampass);
- if (homedir)
- homedir_len = strlen(homedir) +1;
- else
- homedir_len = 0;
- logon_script = pdb_get_logon_script(sampass);
- if (logon_script)
- logon_script_len = strlen(logon_script) +1;
- else
- logon_script_len = 0;
- profile_path = pdb_get_profile_path(sampass);
- if (profile_path)
- profile_path_len = strlen(profile_path) +1;
- else
- profile_path_len = 0;
- acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc)
- acct_desc_len = strlen(acct_desc) +1;
- else
- acct_desc_len = 0;
- workstations = pdb_get_workstations(sampass);
- if (workstations)
- workstations_len = strlen(workstations) +1;
- else
- workstations_len = 0;
+ if (fullname) fullname_len = strlen(fullname) +1;
+ else fullname_len = 0;
+
+ /*
+ * Only updates fields which have been set (not defaults from smb.conf)
+ */
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) dir_drive = pdb_get_dirdrive(sampass);
+ else dir_drive = NULL;
+ if (dir_drive) dir_drive_len = strlen(dir_drive) +1;
+ else dir_drive_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME)) homedir = pdb_get_homedir(sampass);
+ else homedir = NULL;
+ if (homedir) homedir_len = strlen(homedir) +1;
+ else homedir_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT)) logon_script = pdb_get_logon_script(sampass);
+ else logon_script = NULL;
+ if (logon_script) logon_script_len = strlen(logon_script) +1;
+ else logon_script_len = 0;
+
+ if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE)) profile_path = pdb_get_profile_path(sampass);
+ else profile_path = NULL;
+ if (profile_path) profile_path_len = strlen(profile_path) +1;
+ else profile_path_len = 0;
lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw)
- lm_pw_len = 0;
+ if (!lm_pw) lm_pw_len = 0;
nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw)
- nt_pw_len = 0;
+ if (!nt_pw) nt_pw_len = 0;
+
+ acct_desc = pdb_get_acct_desc(sampass);
+ if (acct_desc) acct_desc_len = strlen(acct_desc) +1;
+ else acct_desc_len = 0;
+
+ workstations = pdb_get_workstations(sampass);
+ if (workstations) workstations_len = strlen(workstations) +1;
+ else workstations_len = 0;
+
+ unknown_str = NULL;
+ unknown_str_len = 0;
+
+ munged_dial = pdb_get_munged_dial(sampass);
+ if (munged_dial) munged_dial_len = strlen(munged_dial) +1;
+ else munged_dial_len = 0;
/* one time to get the size needed */
len = tdb_pack(NULL, 0, TDB_FORMAT_STRING,
@@ -412,7 +470,7 @@ void pdb_endsampwent(void)
global_tdb_ent.passwd_tdb = NULL;
}
- DEBUG(7, ("endtdbpwent: closed password file.\n"));
+ DEBUG(7, ("endtdbpwent: closed sam database.\n"));
}
/*****************************************************************
@@ -433,10 +491,10 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
return False;
}
- /* skip all RID entries */
- while ((global_tdb_ent.key.dsize != 0) && (strncmp (global_tdb_ent.key.dptr, prefix, prefixlen)))
+ /* skip all non-USER entries (eg. RIDS) */
+ while ((global_tdb_ent.key.dsize != 0) && (strncmp(global_tdb_ent.key.dptr, prefix, prefixlen)))
/* increment to next in line */
- global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
/* do we have an valid interation pointer? */
if(global_tdb_ent.passwd_tdb == NULL) {
@@ -444,43 +502,22 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
return False;
}
- data = tdb_fetch (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ data = tdb_fetch(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer (user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return False;
}
SAFE_FREE(data.dptr);
- /* validate the account and fill in UNIX uid and gid. sys_getpwnam()
- is used instaed of Get_Pwnam() as we do not need to try case
- permutations */
- if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL) {
- DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
- pdb_get_username(user)));
- return False;
- }
-
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- pdb_set_uid (user, uid);
- pdb_set_gid (user, gid);
-
- /* 21 days from present */
- pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_logon_script(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_profile_path(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_homedir(user));
-
/* increment to next in line */
- global_tdb_ent.key = tdb_nextkey (global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+ global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
return True;
}
@@ -511,12 +548,12 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
strlower(name);
get_private_directory(tdbfile);
- pstrcat (tdbfile, PASSDB_FILE_NAME);
+ pstrcat(tdbfile, PASSDB_FILE_NAME);
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
key.dptr = keystr;
- key.dsize = strlen (keystr) + 1;
+ key.dsize = strlen(keystr) + 1;
/* open the accounts TDB */
if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
@@ -525,75 +562,30 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname)
}
/* get the record */
- data = tdb_fetch (pwd_tdb, key);
+ data = tdb_fetch(pwd_tdb, key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close (pwd_tdb);
+ tdb_close(pwd_tdb);
return False;
}
/* unpack the buffer */
- if (!init_sam_from_buffer (user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
+ tdb_close(pwd_tdb);
return False;
}
SAFE_FREE(data.dptr);
-
- /* validate the account and fill in UNIX uid and gid. sys_getpwnam()
- is used instaed of Get_Pwnam() as we do not need to try case
- permutations */
- if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL) {
- DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n",
- pdb_get_username(user)));
- return False;
- }
-
- uid = pw->pw_uid;
- gid = pw->pw_gid;
- pdb_set_uid (user, uid);
- pdb_set_gid (user, gid);
-
- /* 21 days from present */
- pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_logon_script(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_profile_path(user));
- standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_homedir(user));
-
- /* cleanup */
- tdb_close (pwd_tdb);
+ /* no further use for database, close it now */
+ tdb_close(pwd_tdb);
+
return True;
}
/***************************************************************************
- Search by uid
- **************************************************************************/
-
-BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid)
-{
- struct passwd *pw;
- fstring name;
-
- if (user==NULL) {
- DEBUG(0,("pdb_getsampwuid: SAM_ACCOUNT is NULL.\n"));
- return False;
- }
-
- pw = sys_getpwuid(uid);
- if (pw == NULL) {
- DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist!\n", uid));
- return False;
- }
- fstrcpy (name, pw->pw_name);
-
- return pdb_getsampwnam (user, name);
-
-}
-
-/***************************************************************************
Search by rid
**************************************************************************/
@@ -740,7 +732,6 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
pstring tdbfile;
fstring name;
BOOL ret = True;
- int newtdb = FALSE;
get_private_directory(tdbfile);
pstrcat (tdbfile, PASSDB_FILE_NAME);
@@ -789,7 +780,6 @@ static BOOL tdb_update_sam(SAM_ACCOUNT* newpwd, BOOL override, int flag)
if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
DEBUG(0, ("Unable to modify passwd TDB!"));
DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
- tdb_close (pwd_tdb);
ret = False;
goto done;
}
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 856adec244b..ad29bb23b0f 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -110,13 +110,14 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
if (dyn_sid == NULL)
return False;
- if (size != sizeof(DOM_SID)) {
- free(dyn_sid);
+ if (size != sizeof(DOM_SID))
+ {
+ SAFE_FREE(dyn_sid);
return False;
}
*sid = *dyn_sid;
- free(dyn_sid);
+ SAFE_FREE(dyn_sid);
return True;
}
@@ -153,10 +154,8 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
return False;
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
-
memcpy(ret_pwd, pass->hash, 16);
- free(pass);
-
+ SAFE_FREE(pass);
return True;
}
@@ -199,8 +198,8 @@ void reset_globals_after_fork(void)
*/
if (tdb) {
- uint32 initial_val = sys_getpid();
- tdb_change_int_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1);
+ int32 initial_val = sys_getpid();
+ tdb_change_int32_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1);
set_rand_reseed_data((unsigned char *)&initial_val, sizeof(initial_val));
}
diff --git a/source/passdb/smbpassfile.c b/source/passdb/smbpassfile.c
index e4b11dbf76a..d931478839d 100644
--- a/source/passdb/smbpassfile.c
+++ b/source/passdb/smbpassfile.c
@@ -27,7 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
diff --git a/source/printing/load.c b/source/printing/load.c
index c4fc3377c3f..ae76229d773 100644
--- a/source/printing/load.c
+++ b/source/printing/load.c
@@ -48,7 +48,7 @@ static void add_auto_printers(void)
printers = lp_servicenumber(PRINTERS_NAME);
if (printers < 0) {
- free(str);
+ SAFE_FREE(str);
return;
}
@@ -60,7 +60,7 @@ static void add_auto_printers(void)
}
}
- free(str);
+ SAFE_FREE(str);
}
/***************************************************************************
diff --git a/source/printing/lpq_parse.c b/source/printing/lpq_parse.c
index a143709570b..edb56f49be4 100644
--- a/source/printing/lpq_parse.c
+++ b/source/printing/lpq_parse.c
@@ -20,7 +20,6 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index c410c9d1e04..dc04a2fb6eb 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-extern pstring global_myname;
extern DOM_SID global_sid_World;
static TDB_CONTEXT *tdb_forms; /* used for forms files */
@@ -35,11 +33,13 @@ static TDB_CONTEXT *tdb_printers; /* used for printers files */
#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
#define PRINTERS_PREFIX "PRINTERS/"
#define SECDESC_PREFIX "SECDESC/"
+#define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
#define NTDRIVERS_DATABASE_VERSION_1 1
#define NTDRIVERS_DATABASE_VERSION_2 2
+#define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
-#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
+#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
/* Map generic permissions to printer object specific permissions */
@@ -175,11 +175,11 @@ static nt_forms_struct default_forms[] = {
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
-static BOOL upgrade_to_version_2(void)
+static BOOL upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
- DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
+ DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
@@ -187,50 +187,51 @@ static BOOL upgrade_to_version_2(void)
dbuf = tdb_fetch(tdb_drivers, kbuf);
if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving form\n"));
+ DEBUG(0,("upgrade_to_version_3:moving form\n"));
if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
+ DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving printer\n"));
+ DEBUG(0,("upgrade_to_version_3:moving printer\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
+ DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
- DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
}
return True;
}
/****************************************************************************
-open the NT printing tdb
+ Open the NT printing tdb.
****************************************************************************/
+
BOOL nt_printing_init(void)
{
static pid_t local_pid;
@@ -264,24 +265,106 @@ BOOL nt_printing_init(void)
/* handle a Samba upgrade */
tdb_lock_bystring(tdb_drivers, vstring);
- if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
-
- if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
- if (!upgrade_to_version_2())
- return False;
- } else
- tdb_traverse(tdb_drivers, (tdb_traverse_func)tdb_delete, NULL);
-
- tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ {
+ int32 vers_id;
+
+ /* Cope with byte-reversed older versions of the db. */
+ vers_id = tdb_fetch_int32(tdb_drivers, vstring);
+ if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
+ /* Written on a bigendian machine with old fetch_int code. Save as le. */
+ /* The only upgrade between V2 and V3 is to save the version in little-endian. */
+ tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ vers_id = NTDRIVERS_DATABASE_VERSION;
+ }
+
+ if (vers_id != NTDRIVERS_DATABASE_VERSION) {
+
+ if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
+ if (!upgrade_to_version_3())
+ return False;
+ } else
+ tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
+
+ tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ }
}
tdb_unlock_bystring(tdb_drivers, vstring);
+ update_c_setprinter(True);
+
return True;
}
+/*******************************************************************
+ tdb traversal function for counting printers.
+********************************************************************/
+
+static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
+ TDB_DATA data, void *context)
+{
+ int *printer_count = (int*)context;
+
+ if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
+ (*printer_count)++;
+ DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+ Update the spooler global c_setprinter. This variable is initialized
+ when the parent smbd starts with the number of existing printers. It
+ is monotonically increased by the current number of printers *after*
+ each add or delete printer RPC. Only Microsoft knows why... JRR020119
+********************************************************************/
+
+uint32 update_c_setprinter(BOOL initialize)
+{
+ int32 c_setprinter;
+ int32 printer_count = 0;
+
+ tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
+ /* Traverse the tdb, counting the printers */
+ tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
+
+ /* If initializing, set c_setprinter to current printers count
+ * otherwise, bump it by the current printer count
+ */
+ if (!initialize)
+ c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
+ else
+ c_setprinter = printer_count;
+
+ DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
+ tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
+
+ tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
+ return (uint32)c_setprinter;
+}
+
+/*******************************************************************
+ Get the spooler global c_setprinter, accounting for initialization.
+********************************************************************/
+
+uint32 get_c_setprinter(void)
+{
+ int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
+
+ if (c_setprinter == (int32)-1)
+ c_setprinter = update_c_setprinter(True);
+
+ DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
+
+ return (uint32)c_setprinter;
+}
+
/****************************************************************************
- get builtin form struct list
+ Get builtin form struct list.
****************************************************************************/
+
int get_builtin_ntforms(nt_forms_struct **list)
{
*list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
@@ -334,7 +417,7 @@ int get_ntforms(nt_forms_struct **list)
ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
&i, &form.flag, &form.width, &form.length, &form.left,
&form.top, &form.right, &form.bottom);
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
if (ret != dbuf.dsize) continue;
tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
@@ -431,14 +514,14 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
/****************************************************************************
delete a named form struct
****************************************************************************/
-BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret)
+BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
{
pstring key;
TDB_DATA kbuf;
int n=0;
fstring form_name;
- *ret = 0;
+ *ret = WERR_OK;
unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
@@ -451,7 +534,7 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32
if (n == *count) {
DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
- *ret = ERRinvalidparam;
+ *ret = WERR_INVALID_PARAM;
return False;
}
@@ -460,7 +543,7 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32
kbuf.dsize = strlen(key)+1;
kbuf.dptr = key;
if (tdb_delete(tdb_forms, kbuf) != 0) {
- *ret = ERRnomem;
+ *ret = WERR_NOMEM;
return False;
}
@@ -519,8 +602,8 @@ int get_ntdrivers(fstring **list, char *architecture, uint32 version)
if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
return -1;
- } else
- *list = fl;
+ }
+ else *list = fl;
fstrcpy((*list)[total], kbuf.dptr+strlen(key));
total++;
@@ -573,13 +656,14 @@ BOOL get_short_archi(char *short_archi, char *long_archi)
}
/****************************************************************************
-Version information in Microsoft files is held in a VS_VERSION_INFO structure.
-There are two case to be covered here: PE (Portable Executable) and NE (New
-Executable) files. Both files support the same INFO structure, but PE files
-store the signature in unicode, and NE files store it as !unicode.
+ Version information in Microsoft files is held in a VS_VERSION_INFO structure.
+ There are two case to be covered here: PE (Portable Executable) and NE (New
+ Executable) files. Both files support the same INFO structure, but PE files
+ store the signature in unicode, and NE files store it as !unicode.
+ returns -1 on error, 1 on version info found, and 0 on no version info found.
****************************************************************************/
-static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
- uint32 *minor)
+
+static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
{
int i;
char *buf;
@@ -637,7 +721,7 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
/* get the section table */
num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
- free(buf);
+ SAFE_FREE(buf);
if ((buf=malloc(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
fname, section_table_bytes));
@@ -658,7 +742,7 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
- free(buf);
+ SAFE_FREE(buf);
if ((buf=malloc(section_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
fname, section_bytes));
@@ -692,8 +776,8 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
fname, *major, *minor,
(*major>>16)&0xffff, *major&0xffff,
(*minor>>16)&0xffff, *minor&0xffff));
- free(buf);
- return True;
+ SAFE_FREE(buf);
+ return 1;
}
}
}
@@ -702,8 +786,8 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
/* Version info not found, fall back to origin date/time */
DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
- free(buf);
- return False;
+ SAFE_FREE(buf);
+ return 0;
} else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
@@ -715,7 +799,7 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
}
/* Allocate a bit more space to speed up things */
- free(buf);
+ SAFE_FREE(buf);
if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
fname, PE_HEADER_SIZE));
@@ -769,16 +853,16 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
fname, *major, *minor,
(*major>>16)&0xffff, *major&0xffff,
(*minor>>16)&0xffff, *minor&0xffff));
- free(buf);
- return True;
+ SAFE_FREE(buf);
+ return 1;
}
}
}
/* Version info not found, fall back to origin date/time */
DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
- free(buf);
- return False;
+ SAFE_FREE(buf);
+ return 0;
} else
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
@@ -786,11 +870,11 @@ static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
no_version_info:
- free(buf);
- return False;
+ SAFE_FREE(buf);
+ return 0;
error_exit:
- free(buf);
+ SAFE_FREE(buf);
return -1;
}
@@ -923,26 +1007,29 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file,
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
- struct current_user *user, uint32 *perr)
+ struct current_user *user, WERROR *perr)
{
int cversion;
int access_mode;
int action;
- int ecode;
pstring driverpath;
fstring user_name;
fstring null_pw;
files_struct *fsp = NULL;
BOOL bad_path;
+ int ecode;
SMB_STRUCT_STAT st;
struct passwd *pass;
connection_struct *conn;
ZERO_STRUCT(st);
+ *perr = WERR_INVALID_PARAM;
+
/* If architecture is Windows 95/98/ME, the version is always 0. */
if (strcmp(architecture, "WIN40") == 0) {
DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
+ *perr = WERR_OK;
return 0;
}
@@ -952,33 +1039,33 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
(unsigned int)user->uid ));
unbecome_root();
- *perr = ERRnoaccess;
+ *perr = WERR_ACCESS_DENIED;
return -1;
}
- unbecome_root();
- /* connect to the print$ share under the same account as the user connected
- * to the rpc pipe */
+ /*
+ * Connect to the print$ share under the same account as the user connected
+ * to the rpc pipe. Note we must still be root to do this.
+ */
+
fstrcpy(user_name, pass->pw_name );
DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user->uid, user_name));
/* Null password is ok - we are already an authenticated user... */
*null_pw = '\0';
conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
+ unbecome_root();
if (conn == NULL) {
DEBUG(0,("get_correct_cversion: Unable to connect\n"));
- *perr = (uint32)ecode;
+ *perr = W_ERROR(ecode);
return -1;
}
- /* Save who we are - we are temporarily becoming the connection user. */
- push_sec_ctx();
-
+ /* We are temporarily becoming the connection user. */
if (!become_user(conn, conn->vuid)) {
- DEBUG(0,("get_correct_cversion: Can't become user %s\n", user_name ));
- *perr = ERRnoaccess;
- pop_sec_ctx();
+ DEBUG(0,("get_correct_cversion: Can't become user!\n"));
+ *perr = WERR_ACCESS_DENIED;
return -1;
}
@@ -995,7 +1082,7 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
if (!fsp) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
driverpath, errno));
- *perr = ERRnoaccess;
+ *perr = WERR_ACCESS_DENIED;
goto error_exit;
}
else {
@@ -1037,29 +1124,31 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
close_file(fsp, True);
close_cnum(conn, user->vuid);
- pop_sec_ctx();
+ unbecome_user();
+ *perr = WERR_OK;
return cversion;
- error_exit:
- if(fsp)
- close_file(fsp, True);
+ error_exit:
- close_cnum(conn, user->vuid);
- pop_sec_ctx();
- return -1;
+ if(fsp)
+ close_file(fsp, True);
+
+ close_cnum(conn, user->vuid);
+ unbecome_user();
+ return -1;
}
/****************************************************************************
****************************************************************************/
-static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
+static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
struct current_user *user)
{
fstring architecture;
fstring new_name;
char *p;
int i;
- uint32 err;
+ WERROR err;
/* clean up the driver name.
* we can get .\driver.dll
@@ -1112,19 +1201,19 @@ static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
driver->driverpath, user, &err)) == -1)
return err;
- return NT_STATUS_OK;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
+static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
struct current_user *user)
{
fstring architecture;
fstring new_name;
char *p;
int i;
- uint32 err;
+ WERROR err;
/* clean up the driver name.
* we can get .\driver.dll
@@ -1177,12 +1266,12 @@ static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
driver->driverpath, user, &err)) == -1)
return err;
- return NT_STATUS_OK;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
uint32 level, struct current_user *user)
{
switch (level) {
@@ -1199,7 +1288,7 @@ uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
return clean_up_driver_struct_level_6(driver, user);
}
default:
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
}
@@ -1242,7 +1331,8 @@ static char* ffmt(unsigned char *c){
/****************************************************************************
****************************************************************************/
-BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
+BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
+ struct current_user *user, WERROR *perr)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
@@ -1260,9 +1350,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
int ver = 0;
int i;
- *perr = 0;
memset(inbuf, '\0', sizeof(inbuf));
memset(outbuf, '\0', sizeof(outbuf));
+ *perr = WERR_OK;
if (level==3)
driver=driver_abstract.info_3;
@@ -1284,19 +1374,23 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
unbecome_root();
return False;
}
- unbecome_root();
- /* connect to the print$ share under the same account as the user connected to the rpc pipe */
+ /*
+ * Connect to the print$ share under the same account as the user connected to the rpc pipe.
+ * Note we must be root to do this.
+ */
+
fstrcpy(user_name, pass->pw_name );
DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
/* Null password is ok - we are already an authenticated user... */
*null_pw = '\0';
conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
+ unbecome_root();
if (conn == NULL) {
DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
- *perr = (uint32)ecode;
+ *perr = W_ERROR(ecode);
return False;
}
@@ -1304,11 +1398,8 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
* Save who we are - we are temporarily becoming the connection user.
*/
- push_sec_ctx();
-
if (!become_user(conn, conn->vuid)) {
DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
- pop_sec_ctx();
return False;
}
@@ -1318,7 +1409,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
*/
DEBUG(5,("Creating first directory\n"));
slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
- mkdir_internal(conn, inbuf, outbuf, new_dir);
+ mkdir_internal(conn, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
@@ -1343,16 +1434,18 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
+ NTSTATUS status;
+ status = rename_internals(conn, new_name, old_name, True);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
- *perr = (uint32)SVAL(outbuf,smb_err);
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ *perr = ntstatus_to_werror(status);
+ unlink_internals(conn, 0, new_name);
ver = -1;
}
}
else
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ unlink_internals(conn, 0, new_name);
}
if (driver->datafile && strlen(driver->datafile)) {
@@ -1360,16 +1453,18 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
+ NTSTATUS status;
+ status = rename_internals(conn, new_name, old_name, True);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
- *perr = (uint32)SVAL(outbuf,smb_err);
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ *perr = ntstatus_to_werror(status);
+ unlink_internals(conn, 0, new_name);
ver = -1;
}
}
else
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1379,16 +1474,18 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
+ NTSTATUS status;
+ status = rename_internals(conn, new_name, old_name, True);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
- *perr = (uint32)SVAL(outbuf,smb_err);
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ *perr = ntstatus_to_werror(status);
+ unlink_internals(conn, 0, new_name);
ver = -1;
}
}
else
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1399,16 +1496,18 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
+ NTSTATUS status;
+ status = rename_internals(conn, new_name, old_name, True);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
- *perr = (uint32)SVAL(outbuf,smb_err);
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ *perr = ntstatus_to_werror(status);
+ unlink_internals(conn, 0, new_name);
ver = -1;
}
}
else
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ unlink_internals(conn, 0, new_name);
}
}
@@ -1428,23 +1527,25 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
+ NTSTATUS status;
+ status = rename_internals(conn, new_name, old_name, True);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
- *perr = (uint32)SVAL(outbuf,smb_err);
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ *perr = ntstatus_to_werror(status);
+ unlink_internals(conn, 0, new_name);
ver = -1;
}
}
else
- unlink_internals(conn, inbuf, outbuf, 0, new_name);
+ unlink_internals(conn, 0, new_name);
}
NextDriver: ;
}
}
close_cnum(conn, user->vuid);
- pop_sec_ctx();
+ unbecome_user();
return ver == -1 ? False : True;
}
@@ -1471,36 +1572,36 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
- /* .inf files do not always list a file for each of the four standard files.
- * Don't prepend a path to a null filename, or client claims:
- * "The server on which the printer resides does not have a suitable
- * <printer driver name> printer driver installed. Click OK if you
- * wish to install the driver on your local machine."
- */
+ /* .inf files do not always list a file for each of the four standard files.
+ * Don't prepend a path to a null filename, or client claims:
+ * "The server on which the printer resides does not have a suitable
+ * <printer driver name> printer driver installed. Click OK if you
+ * wish to install the driver on your local machine."
+ */
if (strlen(driver->driverpath)) {
- fstrcpy(temp_name, driver->driverpath);
- slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
- }
+ fstrcpy(temp_name, driver->driverpath);
+ slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
+ }
if (strlen(driver->datafile)) {
- fstrcpy(temp_name, driver->datafile);
- slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
- }
+ fstrcpy(temp_name, driver->datafile);
+ slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
+ }
if (strlen(driver->configfile)) {
- fstrcpy(temp_name, driver->configfile);
- slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
- }
+ fstrcpy(temp_name, driver->configfile);
+ slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
+ }
if (strlen(driver->helpfile)) {
- fstrcpy(temp_name, driver->helpfile);
- slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
- }
+ fstrcpy(temp_name, driver->helpfile);
+ slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
+ }
if (driver->dependentfiles) {
for (i=0; *driver->dependentfiles[i]; i++) {
- fstrcpy(temp_name, driver->dependentfiles[i]);
- slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
+ fstrcpy(temp_name, driver->dependentfiles[i]);
+ slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
}
}
@@ -1541,8 +1642,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
ret = -1;
goto done;
}
- else
- buf = tb;
+ else buf = tb;
buflen = len;
goto again;
}
@@ -1559,7 +1659,7 @@ done:
if (ret)
DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
- safe_free(buf);
+ SAFE_FREE(buf);
return ret;
}
@@ -1587,7 +1687,7 @@ static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
/****************************************************************************
****************************************************************************/
-static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
+static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
@@ -1602,19 +1702,19 @@ static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
fstrcpy(info.helpfile, "");
if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
memset(info.dependentfiles, '\0', 2*sizeof(fstring));
fstrcpy(info.dependentfiles[0], "");
*info_ptr = memdup(&info, sizeof(info));
- return 0;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
+static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA kbuf, dbuf;
@@ -1638,7 +1738,7 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
#if 0
if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
#else
- if (!dbuf.dptr) return 5;
+ if (!dbuf.dptr) return WERR_ACCESS_DENIED;
#endif
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
&driver.cversion,
@@ -1655,13 +1755,13 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
while (len < dbuf.dsize) {
fstring *tddfs;
- tddfs = (fstring *)Realloc(driver.dependentfiles, sizeof(fstring)*(i+2));
+ tddfs = (fstring *)Realloc(driver.dependentfiles,
+ sizeof(fstring)*(i+2));
if (tddfs == NULL) {
DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
break;
}
- else
- driver.dependentfiles = tddfs;
+ else driver.dependentfiles = tddfs;
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
&driver.dependentfiles[i]);
@@ -1670,18 +1770,17 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
if (driver.dependentfiles != NULL)
fstrcpy(driver.dependentfiles[i], "");
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
if (len != dbuf.dsize) {
- if (driver.dependentfiles != NULL)
- safe_free(driver.dependentfiles);
+ SAFE_FREE(driver.dependentfiles);
return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
}
*info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
- return 0;
+ return WERR_OK;
}
/****************************************************************************
@@ -1699,54 +1798,56 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- if (!tdb_exists(tdb_drivers, kbuf)) return False;
+ if (!tdb_exists(tdb_drivers, kbuf))
+ return False;
ZERO_STRUCT(info3);
get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
- DEBUGADD(10,("info3->name [%s]\n", info3->name));
- DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
- DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
- DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
- DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
+ DEBUGADD(10,("info3->name [%s]\n", info3->name));
+ DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
+ DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
+ DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
+ DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
- DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
- }
- DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
- DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
- DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
+ DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
+ }
+ DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
+ DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
+ DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
/*pstrcat(line, info3->name); pstrcat(line, ":");*/
trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->configfile);
- pstrcat(line, ":");
+ pstrcat(line, ":");
trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->datafile);
- pstrcat(line, ":");
+ pstrcat(line, ":");
trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->helpfile);
- pstrcat(line, ":");
+ pstrcat(line, ":");
trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->monitorname);
- pstrcat(line, ":");
+ pstrcat(line, ":");
pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
- pstrcat(line, ":");
+ pstrcat(line, ":");
- for (i=0; info3->dependentfiles &&
- *info3->dependentfiles[i]; i++) {
- if (i) pstrcat(line, ","); /* don't end in a "," */
+ for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
+ if (i)
+ pstrcat(line, ","); /* don't end in a "," */
trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
pstrcat(line, info3->dependentfiles[i]);
}
- free(info3);
+ SAFE_FREE(info3);
return True;
}
/****************************************************************************
-debugging function, dump at level 6 the struct in the logs
+ Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
+
static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
{
uint32 result;
@@ -1784,7 +1885,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
break;
}
default:
- DEBUGADD(1,("Level not implemented\n"));
+ DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
result=1;
break;
}
@@ -1876,9 +1977,10 @@ static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
/****************************************************************************
-delete a printer - this just deletes the printer info file, any open
-handles are not affected
+ Delete a printer - this just deletes the printer info file, any open
+ handles are not affected.
****************************************************************************/
+
uint32 del_a_printer(char *sharename)
{
pstring key;
@@ -1895,15 +1997,16 @@ uint32 del_a_printer(char *sharename)
}
/* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
-static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
/****************************************************************************
****************************************************************************/
-static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
+static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
pstring key;
char *buf;
- int buflen, len, ret;
+ int buflen, len;
+ WERROR ret;
TDB_DATA kbuf, dbuf;
/*
@@ -1970,10 +2073,10 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
tb = (char *)Realloc(buf, len);
if (!tb) {
DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
- ret = -1;
+ ret = WERR_NOMEM;
goto done;
- } else
- buf = tb;
+ }
+ else buf = tb;
buflen = len;
goto again;
}
@@ -1987,13 +2090,13 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
dbuf.dptr = buf;
dbuf.dsize = len;
- ret = tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
+ ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
done:
- if (ret == -1)
+ if (!W_ERROR_IS_OK(ret))
DEBUG(8, ("error updating printer to tdb on disk\n"));
- safe_free(buf);
+ SAFE_FREE(buf);
DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
info->sharename, info->drivername, info->portname, len));
@@ -2044,8 +2147,8 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
(strlen(current->value)==strlen(param->value)) ) {
DEBUG(109,("deleting first value\n"));
info_2->specific=current->next;
- safe_free(current->data);
- safe_free(current);
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
DEBUG(109,("deleted first value\n"));
return (True);
}
@@ -2057,8 +2160,8 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
strlen(current->value)==strlen(param->value) ) {
DEBUG(109,("deleting current value\n"));
previous->next=current->next;
- safe_free(current->data);
- safe_free(current);
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
DEBUG(109,("deleted current value\n"));
return(True);
}
@@ -2081,11 +2184,8 @@ void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
- if(param->data)
- safe_free(param->data);
-
- safe_free(param);
- *param_ptr = NULL;
+ SAFE_FREE(param->data);
+ SAFE_FREE(*param_ptr);
}
/****************************************************************************
@@ -2126,7 +2226,7 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
nt_devmode->paperlength = 0;
nt_devmode->paperwidth = 0;
nt_devmode->scale = 0x64;
- nt_devmode->copies = 01;
+ nt_devmode->copies = 1;
nt_devmode->defaultsource = BIN_FORMSOURCE;
nt_devmode->printquality = RES_HIGH; /* 0x0258 */
nt_devmode->color = COLOR_MONOCHROME;
@@ -2171,7 +2271,7 @@ NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
new_nt_devicemode->private = NULL;
if (nt_devicemode->private != NULL) {
if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
- safe_free(new_nt_devicemode);
+ SAFE_FREE(new_nt_devicemode);
DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
return NULL;
}
@@ -2193,11 +2293,8 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
- if(nt_devmode->private)
- safe_free(nt_devmode->private);
-
- safe_free(nt_devmode);
- *devmode_ptr = NULL;
+ SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(*devmode_ptr);
}
/****************************************************************************
@@ -2222,8 +2319,7 @@ static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
free_nt_printer_param(&tofree);
}
- safe_free(*info_ptr);
- *info_ptr = NULL;
+ SAFE_FREE(*info_ptr);
}
@@ -2413,9 +2509,8 @@ static void map_to_os2_driver(fstring drivername)
/****************************************************************************
get a default printer info 2 struct
****************************************************************************/
-static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
{
- extern pstring global_myname;
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
@@ -2423,23 +2518,20 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
snum = lp_servicenumber(sharename);
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
- global_myname, sharename);
+ get_called_name(), sharename);
fstrcpy(info.sharename, sharename);
fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
fstrcpy(info.drivername, lp_printerdriver(snum));
-#if 0 /* JERRY */
- if (!*info.drivername)
- fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
-#else
/* by setting the driver name to an empty string, a local NT admin
can now run the **local** APW to install a local printer driver
for a Samba shared printer in 2.2. Without this, drivers **must** be
installed on the Samba server for NT clients --jerry */
+#if 0 /* JERRY --do not uncomment-- */
if (!*info.drivername)
- fstrcpy(info.drivername, "");
+ fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
#endif
@@ -2449,10 +2541,7 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
fstrcpy(info.printprocessor, "winprint");
fstrcpy(info.datatype, "RAW");
- info.attributes = PRINTER_ATTRIBUTE_SHARED \
- | PRINTER_ATTRIBUTE_LOCAL \
- | PRINTER_ATTRIBUTE_RAW_ONLY \
- | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
+ info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; /* attributes */
info.starttime = 0; /* Minutes since 12:00am GMT */
info.untiltime = 0; /* Minutes since 12:00am GMT */
@@ -2460,18 +2549,23 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
info.default_priority = 1;
info.setuptime = (uint32)time(NULL);
-#if 1 /* JRA - NO NOT CHANGE ! */
- info.devmode = NULL;
-#else
/*
- * We should not return a default devicemode, as this causes
- * Win2K to not send the correct one on PCL drivers. It needs to
- * see a null devicemode so it can then overwrite the devicemode
- * on OpenPrinterEx. Yes this *is* insane :-). JRA.
+ * I changed this as I think it is better to have a generic
+ * DEVMODE than to crash Win2k explorer.exe --jerry
+ * See the HP Deskjet 990c Win2k drivers for an example.
+ *
+ * However the default devmode appears to cause problems
+ * with the HP CLJ 8500 PCL driver. Hence the addition of
+ * the "default devmode" parameter --jerry 22/01/2002
*/
- if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
- goto fail;
-#endif
+
+ if (lp_default_devmode(snum)) {
+ if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
+ goto fail;
+ }
+ else {
+ info.devmode = NULL;
+ }
/* This will get the current RPC talloc context, but we should be
passing this as a parameter... fixme... JRA ! */
@@ -2485,22 +2579,21 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
goto fail;
}
- return (0);
+ return WERR_OK;
fail:
-
if (info.devmode)
free_nt_devicemode(&info.devmode);
- return 2;
+ return WERR_ACCESS_DENIED;
}
/****************************************************************************
****************************************************************************/
-static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
{
pstring key;
NT_PRINTER_INFO_LEVEL_2 info;
- int len = 0;
+ int len = 0;
TDB_DATA kbuf, dbuf;
fstring printername;
@@ -2541,15 +2634,31 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
info.parameters);
/* Samba has to have shared raw drivers. */
- info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
+ info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK);
/* Restore the stripped strings. */
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", global_myname,
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
info.printername);
fstrcpy(info.printername, printername);
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
+
+ /*
+ * Some client drivers freak out if there is a NULL devmode
+ * (probably the driver is not checking before accessing
+ * the devmode pointer) --jerry
+ *
+ * See comments in get_a_printer_2_default()
+ */
+
+ if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
+ {
+ DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
+ printername));
+ info.devmode = construct_nt_devicemode(printername);
+ }
+
len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
/* This will get the current RPC talloc context, but we should be
@@ -2562,14 +2671,13 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
if (get_remote_arch() == RA_OS2)
map_to_os2_driver(info.drivername);
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
*info_ptr=memdup(&info, sizeof(info));
DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
sharename, info.printername, info.drivername));
-
- return 0;
+ return WERR_OK;
}
/****************************************************************************
@@ -2620,7 +2728,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
break;
}
default:
- DEBUGADD(1,("Level not implemented\n"));
+ DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
result=1;
break;
}
@@ -2638,7 +2746,7 @@ void get_printer_subst_params(int snum, fstring *printername, fstring *sharename
**printername = **sharename = **portname = '\0';
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return;
fstrcpy(*printername, printer->info_2->printername);
@@ -2648,6 +2756,24 @@ void get_printer_subst_params(int snum, fstring *printername, fstring *sharename
free_a_printer(&printer, 2);
}
+/****************************************************************************
+ Update the changeid time.
+ This is SO NASTY as some drivers need this to change, others need it
+ static. This value will change every second, and I must hope that this
+ is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
+ UTAH ! JRA.
+****************************************************************************/
+
+static uint32 rev_changeid(void)
+{
+ struct timeval tv;
+
+ get_process_uptime(&tv);
+
+ /* Return changeid as msec since spooler restart */
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
/*
* The function below are the high level ones.
* only those ones must be called from the spoolss code.
@@ -2658,9 +2784,9 @@ void get_printer_subst_params(int snum, fstring *printername, fstring *sharename
Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
****************************************************************************/
-uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
- uint32 result;
+ WERROR result;
dump_a_printer(printer, level);
@@ -2668,52 +2794,42 @@ uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
case 2:
{
- printer.info_2->c_setprinter++;
- result=update_a_printer_2(printer.info_2);
- break;
- }
- default:
- result=1;
- break;
- }
-
- return result;
-}
+ /*
+ * Update the changestamp. Emperical tests show that the
+ * ChangeID is always updated,but c_setprinter is
+ * global spooler variable (not per printer).
+ */
-/****************************************************************************
- Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
- We split this out from mod_a_printer as it updates the id's and timestamps.
-****************************************************************************/
+ /* ChangeID **must** be increasing over the lifetime
+ of client's spoolss service in order for the
+ client's cache to show updates */
+
+ printer.info_2->changeid = rev_changeid();
-uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
-{
- uint32 result;
-
- dump_a_printer(printer, level);
-
- switch (level)
- {
- case 2:
- {
/*
- * Update the changestamp.
- * Note we must *not* do this in mod_a_printer().
+ * Because one day someone will ask:
+ * NT->NT An admin connection to a remote
+ * printer show changes imeediately in
+ * the properities dialog
+ *
+ * A non-admin connection will only show the
+ * changes after viewing the properites page
+ * 2 times. Seems to be related to a
+ * race condition in the client between the spooler
+ * updating the local cache and the Explorer.exe GUI
+ * actually displaying the properties.
+ *
+ * This is fixed in Win2k. admin/non-admin
+ * connections both display changes immediately.
+ *
+ * 14/12/01 --jerry
*/
- NTTIME time_nt;
- time_t time_unix = time(NULL);
- unix_to_nt_time(&time_nt, time_unix);
- if (printer.info_2->changeid==time_nt.low)
- printer.info_2->changeid++;
- else
- printer.info_2->changeid=time_nt.low;
-
- printer.info_2->c_setprinter++;
result=update_a_printer_2(printer.info_2);
break;
}
default:
- result=1;
+ result=WERR_UNKNOWN_LEVEL;
break;
}
@@ -2723,6 +2839,7 @@ uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
/****************************************************************************
Initialize printer devmode & data with previously saved driver init values.
****************************************************************************/
+
static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
{
int len = 0;
@@ -2731,6 +2848,17 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
NT_PRINTER_PARAM *current;
NT_PRINTER_INFO_LEVEL_2 info;
+ /*
+ * Delete any printer data 'specifics' already set. When called for driver
+ * replace, there will generally be some, but during an add printer, there
+ * should not be any (if there are delete them).
+ */
+ while ( (current=info_ptr->specific) != NULL ) {
+ info_ptr->specific=current->next;
+ SAFE_FREE(current->data);
+ SAFE_FREE(current);
+ }
+
ZERO_STRUCT(info);
slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
@@ -2740,8 +2868,14 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
kbuf.dsize = strlen(key)+1;
dbuf = tdb_fetch(tdb_drivers, kbuf);
- if (!dbuf.dptr)
+ if (!dbuf.dptr) {
+ /*
+ * When changing to a driver that has no init info in the tdb, remove
+ * the previous drivers init info and leave the new on blank.
+ */
+ free_nt_devicemode(&info_ptr->devmode);
return False;
+ }
/*
* Get the saved DEVMODE..
@@ -2765,21 +2899,11 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
info_ptr->printername, info_ptr->drivername));
/*
- * There should not be any printer data 'specifics' already set during the
- * add printer operation, if there are delete them.
- */
- while ( (current=info_ptr->specific) != NULL ) {
- info_ptr->specific=current->next;
- safe_free(current->data);
- safe_free(current);
- }
-
- /*
* Add the printer data 'specifics' to the new printer
*/
len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
return True;
}
@@ -2817,6 +2941,7 @@ uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
of whether it was installed from NT or 2K. Technically, they should be
different, but they work out to the same struct.
****************************************************************************/
+
static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
pstring key;
@@ -2842,8 +2967,7 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
ret = -1;
goto done;
}
- else
- buf = tb;
+ else buf = tb;
buflen = len;
goto again;
}
@@ -2862,7 +2986,7 @@ done:
if (ret == -1)
DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
- safe_free(buf);
+ SAFE_FREE(buf);
DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
info->sharename, info->drivername));
@@ -2874,7 +2998,7 @@ done:
Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
****************************************************************************/
-static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
uint32 result;
@@ -2943,35 +3067,44 @@ static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEV
about it and you will realize why. JRR 010720
****************************************************************************/
-static uint32 save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
+static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
{
- uint32 status = ERRsuccess;
+ WERROR status = WERR_OK;
TALLOC_CTX *ctx = NULL;
NT_DEVICEMODE *nt_devmode = NULL;
NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
/*
- * Set devmode on printer info, so entire printer initialization can be
- * saved to tdb.
+ * When the DEVMODE is already set on the printer, don't try to unpack it.
*/
- if ((ctx = talloc_init()) == NULL)
- return ERRnomem;
- if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
- status = ERRnomem;
- goto done;
- }
+ if (!printer->info_2->devmode) {
+ /*
+ * 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);
+ 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(param, ctx, nt_devmode)) {
- DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
- status = ERRinvalidparam;
- goto done;
+ /*
+ * 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(param, ctx, nt_devmode)) {
+ DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
+ status = WERR_INVALID_PARAM;
+ goto done;
+ }
+
+ printer->info_2->devmode = nt_devmode;
}
/*
@@ -2979,10 +3112,10 @@ static uint32 save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARA
* a 'driver init' element in the tdb
*
*/
- printer->info_2->devmode = nt_devmode;
+
if (update_driver_init(*printer, 2)!=0) {
DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
- status = ERRnomem;
+ status = WERR_NOMEM;
goto done;
}
@@ -2991,17 +3124,21 @@ static uint32 save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARA
* printer to match it. This allows initialization of the current printer
* as well as the driver.
*/
- if (mod_a_printer(*printer, 2)!=0) {
+ 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));
- status = ERRinvalidparam;
}
+
+#if 0 /* JERRY */
+ srv_spoolss_sendnotify(p, handle);
+#endif
done:
talloc_destroy(ctx);
if (nt_devmode)
- safe_free(nt_devmode->private);
- safe_free(nt_devmode);
+ SAFE_FREE(nt_devmode->private);
+ SAFE_FREE(nt_devmode);
printer->info_2->devmode = tmp_devmode;
return status;
@@ -3011,9 +3148,9 @@ static uint32 save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARA
Update the driver init info (DEVMODE and specifics) for a printer
****************************************************************************/
-uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
+WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
{
- uint32 status = ERRsuccess;
+ WERROR status = WERR_OK;
switch (level)
{
@@ -3023,7 +3160,7 @@ uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER
break;
}
default:
- status=ERRunknownlevel;
+ status=WERR_UNKNOWN_LEVEL;
break;
}
@@ -3034,9 +3171,9 @@ uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
****************************************************************************/
-uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
+WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
{
- uint32 result;
+ WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
*pp_printer = NULL;
@@ -3049,24 +3186,24 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring s
{
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
DEBUG(0,("get_a_printer: malloc fail.\n"));
- return 1;
+ return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
result=get_a_printer_2(&printer->info_2, sharename);
- if (result == 0) {
+ if (W_ERROR_IS_OK(result)) {
dump_a_printer(*printer, level);
*pp_printer = printer;
} else {
- safe_free(printer);
+ SAFE_FREE(printer);
}
break;
}
default:
- result=1;
+ result=WERR_UNKNOWN_LEVEL;
break;
}
- DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)result));
+ DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
return result;
}
@@ -3105,8 +3242,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
break;
}
- safe_free(printer);
- *pp_printer = NULL;
+ SAFE_FREE(*pp_printer);
return result;
}
@@ -3140,10 +3276,10 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
}
/****************************************************************************
****************************************************************************/
-uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
fstring printername, fstring architecture, uint32 version)
{
- uint32 result;
+ WERROR result;
switch (level)
{
@@ -3153,11 +3289,11 @@ uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
break;
}
default:
- result=1;
+ result=W_ERROR(1);
break;
}
- if (result == 0)
+ if (W_ERROR_IS_OK(result))
dump_a_printer_driver(*driver, level);
return result;
}
@@ -3176,9 +3312,9 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
if (driver.info_3 != NULL)
{
info3=driver.info_3;
- safe_free(info3->dependentfiles);
+ SAFE_FREE(info3->dependentfiles);
ZERO_STRUCTP(info3);
- safe_free(info3);
+ SAFE_FREE(info3);
result=0;
}
else
@@ -3193,10 +3329,10 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
if (driver.info_6 != NULL)
{
info6=driver.info_6;
- safe_free(info6->dependentfiles);
- safe_free(info6->previousnames);
+ SAFE_FREE(info6->dependentfiles);
+ SAFE_FREE(info6->previousnames);
ZERO_STRUCTP(info6);
- safe_free(info6);
+ SAFE_FREE(info6);
result=0;
}
else
@@ -3265,7 +3401,7 @@ BOOL printer_driver_in_use (char *arch, char *driver)
info.datatype,
info.parameters);
- safe_free(dbuf.dptr);
+ SAFE_FREE(dbuf.dptr);
if (ret == -1) {
DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
@@ -3295,7 +3431,7 @@ BOOL printer_driver_in_use (char *arch, char *driver)
Remove a printer driver from the TDB. This assumes that the the driver was
previously looked up.
***************************************************************************/
-uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
+WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
{
pstring key;
fstring arch;
@@ -3312,13 +3448,13 @@ uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
if (tdb_delete(tdb_drivers, kbuf) == -1) {
DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
- return NT_STATUS_ACCESS_VIOLATION;
+ return WERR_ACCESS_DENIED;
}
DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
i->name));
- return NT_STATUS_OK;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
@@ -3399,18 +3535,18 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
Store a security desc for a printer.
****************************************************************************/
-uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
+WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL;
SEC_DESC_BUF *old_secdesc_ctr = NULL;
prs_struct ps;
TALLOC_CTX *mem_ctx = NULL;
fstring key;
- uint32 status;
+ WERROR status;
mem_ctx = talloc_init();
if (mem_ctx == NULL)
- return False;
+ return WERR_NOMEM;
/* The old owner and group sids of the security descriptor are not
present when new ACEs are added or removed by changing printer
@@ -3465,17 +3601,17 @@ uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
&ps, 1)) {
- status = ERRbadfunc;
+ status = WERR_BADFUNC;
goto out;
}
slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
if (tdb_prs_store(tdb_printers, key, &ps)==0) {
- status = 0;
+ status = WERR_OK;
} else {
DEBUG(1,("Failed to store secdesc for %s\n", printername));
- status = ERRbadfunc;
+ status = WERR_BADFUNC;
}
/* Free malloc'ed memory */
@@ -3494,6 +3630,7 @@ uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
{
+ extern DOM_SID global_sam_sid;
SEC_ACE ace[3];
SEC_ACCESS sa;
SEC_ACL *psa = NULL;
@@ -3515,19 +3652,14 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
} else {
- uint32 owner_rid;
/* Backup plan - make printer owned by admins or root.
This should emulate a lanman printer as security
settings can't be changed. */
- sid_peek_rid(&owner_sid, &owner_rid);
-
- if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
- owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
- owner_rid != DOMAIN_USER_RID_ADMIN &&
- !lookup_name("root", &owner_sid, &name_type)) {
- sid_copy(&owner_sid, &global_sid_World);
+ if (!lookup_name("root", &owner_sid, &name_type)) {
+ sid_copy(&owner_sid, &global_sam_sid);
+ sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
}
}
@@ -3591,6 +3723,16 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secde
return False;
}
+ /* Save default security descriptor for later */
+
+ prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
+ sizeof(SEC_DESC_BUF), ctx, MARSHALL);
+
+ if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
+ tdb_prs_store(tdb_printers, key, &ps);
+
+ prs_mem_free(&ps);
+
return True;
}
@@ -3643,7 +3785,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secde
for (i = 0; i < the_acl->num_aces; i++) {
fstring sid_str;
- sid_to_string(sid_str, &the_acl->ace[i].sid);
+ sid_to_string(sid_str, &the_acl->ace[i].trustee);
DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
the_acl->ace[i].type, the_acl->ace[i].flags,
@@ -3726,7 +3868,8 @@ void map_printer_permissions(SEC_DESC *sd)
BOOL print_access_check(struct current_user *user, int snum, int access_type)
{
SEC_DESC_BUF *secdesc = NULL;
- uint32 access_granted, status;
+ uint32 access_granted;
+ NTSTATUS status;
BOOL result;
char *pname;
TALLOC_CTX *mem_ctx = NULL;
@@ -3809,7 +3952,7 @@ BOOL print_time_access_check(int snum)
struct tm *t;
uint32 mins;
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
@@ -3833,21 +3976,20 @@ BOOL print_time_access_check(int snum)
Attempt to write a default device.
*****************************************************************************/
-uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
+WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- uint32 result = 0;
+ WERROR result;
/*
* Don't bother if no default devicemode was sent.
*/
if (printer_default->devmode_cont.devmode == NULL)
- return 0;
+ return WERR_OK;
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
- return ERRnoaccess;
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) return result;
/*
* Just ignore it if we already have a devmode.
@@ -3865,15 +4007,15 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
PRINTER_ACCESS_ADMINISTER) {
DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
- result = ERRnoaccess;
+ result = WERR_ACCESS_DENIED;
goto done;
}
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
lp_servicename(snum) ));
- result = ERRnoaccess;
- /*result = NT_STATUS_OK;*/
+ result = WERR_ACCESS_DENIED;
+ /*result = NT_STATUS_NO_PROBLEMO;*/
goto done;
}
@@ -3886,7 +4028,7 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
if (!convert_devicemode(printer->info_2->printername,
printer_default->devmode_cont.devmode,
&printer->info_2->devmode)) {
- result = ERRnomem;
+ result = WERR_NOMEM;
goto done;
}
@@ -3894,10 +4036,7 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
* Finally write back to the tdb.
*/
- if (add_a_printer(*printer, 2)!=0) {
- result = ERRnoaccess;
- goto done;
- }
+ result = mod_a_printer(*printer, 2);
done:
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index cead9f919e9..a2ca0b7dcb4 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -65,8 +65,6 @@
#include "smb.h"
-extern int DEBUGLEVEL;
-
#ifdef AIX
/* ******************************************
Extend for AIX system and qconfig file
@@ -114,7 +112,7 @@ static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
iEtat = 0;
/* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
{
if (*line == '*' || *line == 0)
continue;
@@ -184,7 +182,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
if ((pfile = sys_fopen(psz, "r")) == NULL)
{
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- free(pName);
+ SAFE_FREE(pName);
return(False);
}
slprintf(pName, iLg + 9, "%s:",pszPrintername);
@@ -192,7 +190,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
/*DEBUG(3,( " Looking for entry %s\n",pName));*/
iEtat = 0;
/* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
{
if (*line == '*' || *line == 0)
continue;
@@ -211,8 +209,8 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
{
/* name is found without stanza device */
/* probably a good printer ??? */
- free (line);
- free(pName);
+ SAFE_FREE (line);
+ SAFE_FREE(pName);
fclose(pfile);
return(True);
}
@@ -225,15 +223,15 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
else if (strlocate(line,"device"))
{
/* it's a good virtual printer */
- free (line);
- free(pName);
+ SAFE_FREE (line);
+ SAFE_FREE(pName);
fclose(pfile);
return(True);
}
break;
}
}
- free (pName);
+ SAFE_FREE (pName);
fclose(pfile);
return(False);
}
@@ -291,7 +289,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
return(False);
}
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
{
if (*line == '#' || *line == 0)
continue;
@@ -312,7 +310,7 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
{
/* normalise the case */
pstrcpy(pszPrintername,p);
- free(line);
+ SAFE_FREE(line);
fclose(pfile);
return(True);
}
@@ -374,7 +372,7 @@ void pcap_printer_fn(void (*fn)(char *, char *))
return;
}
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
+ for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
{
if (*line == '#' || *line == 0)
continue;
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index 565caff30ac..327811dd9fe 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -1,7 +1,7 @@
/*
* Support code for the Common UNIX Printing System ("CUPS")
*
- * Copyright 1999-2001 by Easy Software Products
+ * Copyright 1999-2001 by Michael R Sweet.
*
* 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
@@ -51,9 +51,6 @@ struct printif cups_printif =
cups_job_submit,
};
-extern int DEBUGLEVEL;
-
-
/*
* 'cups_passwd_cb()' - The CUPS password callback...
*/
@@ -826,7 +823,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
ippDelete(response);
httpClose(http);
- free (queue);
+ SAFE_FREE(queue);
return (0);
}
diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c
index ef38d26493c..741a4db2391 100644
--- a/source/printing/print_generic.c
+++ b/source/printing/print_generic.c
@@ -47,8 +47,6 @@ struct printif generic_printif =
generic_job_submit,
};
-extern int DEBUGLEVEL;
-
/****************************************************************************
run a given print command
a null terminated list of value/substitute pairs is provided
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 5d81843b87b..c4c8945ea86 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -37,8 +37,6 @@
#ifdef SYSV
-extern int DEBUGLEVEL;
-
typedef struct printer {
char *name;
struct printer *next;
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index 6545dc59c22..ea50f43d2e2 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -21,25 +21,33 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
-
/***************************************************************************
open a print file and setup a fsp for it. This is a wrapper around
print_job_start().
***************************************************************************/
-files_struct *print_fsp_open(connection_struct *conn)
+files_struct *print_fsp_open(connection_struct *conn, char *fname)
{
int jobid;
SMB_STRUCT_STAT sbuf;
extern struct current_user current_user;
files_struct *fsp = file_new(conn);
+ fstring name;
if(!fsp)
return NULL;
- jobid = print_job_start(&current_user, SNUM(conn), "smb.prn");
+ fstrcpy( name, "Remote Downlevel Document");
+ if (fname) {
+ char *p = strrchr(fname, '/');
+ fstrcat(name, " ");
+ if (!p)
+ p = fname;
+ fstrcat(name, p);
+ }
+
+ jobid = print_job_start(&current_user, SNUM(conn), name);
if (jobid == -1) {
file_free(fsp);
return NULL;
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 19d6aa2f70c..a1aa2ce76ed 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -21,8 +21,6 @@
#include "printing.h"
-extern int DEBUGLEVEL;
-
/* Current printer interface */
struct printif *current_printif = &generic_printif;
@@ -47,9 +45,10 @@ static pid_t local_pid;
static int get_queue_status(int, print_status_struct *);
/****************************************************************************
-initialise the printing backend. Called once at startup.
-Does not survive a fork
+ Initialise the printing backend. Called once at startup.
+ Does not survive a fork
****************************************************************************/
+
BOOL print_backend_init(void)
{
char *sversion = "INFO/version";
@@ -65,9 +64,9 @@ BOOL print_backend_init(void)
/* handle a Samba upgrade */
tdb_lock_bystring(tdb, sversion);
- if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
- tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION);
+ if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) {
+ tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
+ tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION);
}
tdb_unlock_bystring(tdb, sversion);
@@ -82,8 +81,9 @@ BOOL print_backend_init(void)
}
/****************************************************************************
-useful function to generate a tdb key
+ Useful function to generate a tdb key.
****************************************************************************/
+
static TDB_DATA print_key(int jobid)
{
static int j;
@@ -96,8 +96,9 @@ static TDB_DATA print_key(int jobid)
}
/****************************************************************************
-useful function to find a print job in the database
+ Useful function to find a print job in the database.
****************************************************************************/
+
static struct printjob *print_job_find(int jobid)
{
static struct printjob pjob;
@@ -107,13 +108,14 @@ static struct printjob *print_job_find(int jobid)
if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
memcpy(&pjob, ret.dptr, sizeof(pjob));
- free(ret.dptr);
+ SAFE_FREE(ret.dptr);
return &pjob;
}
/****************************************************************************
-store a job structure back to the database
+ Store a job structure back to the database.
****************************************************************************/
+
static BOOL print_job_store(int jobid, struct printjob *pjob)
{
TDB_DATA d;
@@ -124,8 +126,9 @@ static BOOL print_job_store(int jobid, struct printjob *pjob)
}
/****************************************************************************
-parse a file name from the system spooler to generate a jobid
+ Parse a file name from the system spooler to generate a jobid.
****************************************************************************/
+
static int print_parse_jobid(char *fname)
{
int jobid;
@@ -139,10 +142,10 @@ static int print_parse_jobid(char *fname)
return jobid;
}
-
/****************************************************************************
-list a unix job in the print database
+ List a unix job in the print database.
****************************************************************************/
+
static void print_unix_job(int snum, print_queue_struct *q)
{
int jobid = q->job + UNIX_JOB_START;
@@ -249,14 +252,15 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
}
/****************************************************************************
-check if the print queue has been updated recently enough
+ Check if the print queue has been updated recently enough.
****************************************************************************/
+
static void print_cache_flush(int snum)
{
fstring key;
slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
dos_to_unix(key, True); /* Convert key to unix-codepage */
- tdb_store_int(tdb, key, -1);
+ tdb_store_int32(tdb, key, -1);
}
/****************************************************************************
@@ -278,7 +282,7 @@ static pid_t get_updating_pid(fstring printer_name)
return (pid_t)-1;
memcpy(&updating_pid, data.dptr, sizeof(pid_t));
- free(data.dptr);
+ SAFE_FREE(data.dptr);
if (process_exists(updating_pid))
return updating_pid;
@@ -381,7 +385,7 @@ static void print_queue_update(int snum)
*/
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
- tdb_store_int(tdb, cachestr, (int)time(NULL));
+ tdb_store_int32(tdb, cachestr, (int)time(NULL));
/* get the current queue using the appropriate interface */
ZERO_STRUCT(status);
@@ -437,7 +441,7 @@ static void print_queue_update(int snum)
safe_free(tstruct.queue);
- tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs);
+ tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs);
/*
* Get the old print status. We will use this to compare the
@@ -467,26 +471,27 @@ static void print_queue_update(int snum)
*/
slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
- tdb_store_int(tdb, keystr, (int)time(NULL));
+ tdb_store_int32(tdb, keystr, (int32)time(NULL));
/* Delete our pid from the db. */
set_updating_pid(printer_name, True);
}
/****************************************************************************
-check if a jobid is valid. It is valid if it exists in the database
+ Check if a jobid is valid. It is valid if it exists in the database.
****************************************************************************/
+
BOOL print_job_exists(int jobid)
{
return tdb_exists(tdb, print_key(jobid));
}
-
/****************************************************************************
-work out which service a jobid is for
-note that we have to look up by queue name to ensure that it works for
-other than the process that started the job
+ Work out which service a jobid is for.
+ Note that we have to look up by queue name to ensure that it works for
+ other than the process that started the job.
****************************************************************************/
+
int print_job_snum(int jobid)
{
struct printjob *pjob = print_job_find(jobid);
@@ -496,8 +501,9 @@ int print_job_snum(int jobid)
}
/****************************************************************************
-give the fd used for a jobid
+ Give the fd used for a jobid.
****************************************************************************/
+
int print_job_fd(int jobid)
{
struct printjob *pjob = print_job_find(jobid);
@@ -508,10 +514,11 @@ int print_job_fd(int jobid)
}
/****************************************************************************
-give the filename used for a jobid
-only valid for the process doing the spooling and when the job
-has not been spooled
+ Give the filename used for a jobid.
+ Only valid for the process doing the spooling and when the job
+ has not been spooled.
****************************************************************************/
+
char *print_job_fname(int jobid)
{
struct printjob *pjob = print_job_find(jobid);
@@ -519,10 +526,10 @@ char *print_job_fname(int jobid)
return pjob->filename;
}
-
/****************************************************************************
-set the place in the queue for a job
+ Set the place in the queue for a job.
****************************************************************************/
+
BOOL print_job_set_place(int jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
@@ -530,8 +537,9 @@ BOOL print_job_set_place(int jobid, int place)
}
/****************************************************************************
-set the name of a job. Only possible for owner
+ Set the name of a job. Only possible for owner.
****************************************************************************/
+
BOOL print_job_set_name(int jobid, char *name)
{
struct printjob *pjob = print_job_find(jobid);
@@ -541,10 +549,10 @@ BOOL print_job_set_name(int jobid, char *name)
return print_job_store(jobid, pjob);
}
-
/****************************************************************************
-delete a print job - don't update queue
+ Delete a print job - don't update queue.
****************************************************************************/
+
static BOOL print_job_delete1(int jobid)
{
struct printjob *pjob = print_job_find(jobid);
@@ -588,8 +596,9 @@ static BOOL print_job_delete1(int jobid)
}
/****************************************************************************
-return true if the current user owns the print job
+ Return true if the current user owns the print job.
****************************************************************************/
+
static BOOL is_owner(struct current_user *user, int jobid)
{
struct printjob *pjob = print_job_find(jobid);
@@ -607,9 +616,10 @@ static BOOL is_owner(struct current_user *user, int jobid)
}
/****************************************************************************
-delete a print job
+ Delete a print job.
****************************************************************************/
-BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
+
+BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
{
int snum = print_job_snum(jobid);
char *printer_name;
@@ -623,7 +633,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
if (!owner &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("delete denied by security descriptor\n"));
- *errcode = ERRnoaccess;
+ *errcode = WERR_ACCESS_DENIED;
return False;
}
@@ -643,11 +653,11 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
return !print_job_exists(jobid);
}
-
/****************************************************************************
-pause a job
+ Pause a job.
****************************************************************************/
-BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
+
+BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
{
struct printjob *pjob = print_job_find(jobid);
int snum, ret = -1;
@@ -662,7 +672,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
- *errcode = ERRnoaccess;
+ *errcode = WERR_ACCESS_DENIED;
return False;
}
@@ -670,7 +680,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
ret = (*(current_printif->job_pause))(snum, pjob);
if (ret != 0) {
- *errcode = ERRinvalidparam;
+ *errcode = WERR_INVALID_PARAM;
return False;
}
@@ -689,9 +699,10 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
}
/****************************************************************************
-resume a job
+ Resume a job.
****************************************************************************/
-BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
+
+BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
{
struct printjob *pjob = print_job_find(jobid);
char *printer_name;
@@ -706,14 +717,14 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
- *errcode = ERRnoaccess;
+ *errcode = WERR_ACCESS_DENIED;
return False;
}
ret = (*(current_printif->job_resume))(snum, pjob);
if (ret != 0) {
- *errcode = ERRinvalidparam;
+ *errcode = WERR_INVALID_PARAM;
return False;
}
@@ -730,8 +741,9 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
}
/****************************************************************************
-write to a print file
+ Write to a print file.
****************************************************************************/
+
int print_job_write(int jobid, const char *buf, int size)
{
int fd;
@@ -753,9 +765,11 @@ static BOOL print_cache_expired(int snum)
slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
dos_to_unix(key, True); /* Convert key to unix-codepage */
- t2 = tdb_fetch_int(tdb, key);
+ t2 = (time_t)tdb_fetch_int32(tdb, key);
if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
- DEBUG(3, ("print cache expired\n"));
+ DEBUG(3, ("print cache expired for queue %s \
+(last_cache = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum),
+ (int)t2, (int)t, (int)lp_lpqcachetime() ));
return True;
}
return False;
@@ -764,6 +778,7 @@ static BOOL print_cache_expired(int snum)
/****************************************************************************
Get the queue status - do not update if db is out of date.
****************************************************************************/
+
static int get_queue_status(int snum, print_status_struct *status)
{
fstring keystr;
@@ -779,7 +794,7 @@ static int get_queue_status(int snum, print_status_struct *status)
if (data.dsize == sizeof(print_status_struct)) {
memcpy(status, data.dptr, sizeof(print_status_struct));
}
- free(data.dptr);
+ SAFE_FREE(data.dptr);
}
return status->qcount;
}
@@ -787,20 +802,28 @@ static int get_queue_status(int snum, print_status_struct *status)
/****************************************************************************
Determine the number of jobs in a queue.
****************************************************************************/
-static int print_queue_length(int snum)
+
+int print_queue_length(int snum, print_status_struct *pstatus)
{
print_status_struct status;
-
+ int len;
+
/* make sure the database is up to date */
- if (print_cache_expired(snum)) print_queue_update(snum);
-
+ if (print_cache_expired(snum))
+ print_queue_update(snum);
+
/* also fetch the queue status */
- return get_queue_status(snum, &status);
+ memset(&status, 0, sizeof(status));
+ len = get_queue_status(snum, &status);
+ if (pstatus)
+ *pstatus = status;
+ return len;
}
/****************************************************************************
Determine the number of jobs in all queues.
****************************************************************************/
+
static int get_total_jobs(int snum)
{
int total_jobs;
@@ -808,7 +831,7 @@ static int get_total_jobs(int snum)
/* make sure the database is up to date */
if (print_cache_expired(snum)) print_queue_update(snum);
- total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs");
+ total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs");
if (total_jobs >0)
return total_jobs;
else
@@ -816,8 +839,9 @@ static int get_total_jobs(int snum)
}
/***************************************************************************
-start spooling a job - return the jobid
+ Start spooling a job - return the jobid.
***************************************************************************/
+
int print_job_start(struct current_user *user, int snum, char *jobname)
{
int jobid;
@@ -825,6 +849,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
struct printjob pjob;
int next_jobid;
user_struct *vuser;
+ int njobs = 0;
errno = 0;
@@ -859,9 +884,9 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
}
/* Insure the maximum queue size is not violated */
- if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) {
+ 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",
- print_queue_length(snum), lp_maxprintjobs(snum) ));
+ njobs, lp_maxprintjobs(snum) ));
errno = ENOSPC;
return -1;
}
@@ -869,7 +894,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
/* Insure the maximum print jobs in the system is not violated */
if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
- print_queue_length(snum), lp_totalprintjobs() ));
+ njobs, lp_totalprintjobs() ));
errno = ENOSPC;
return -1;
}
@@ -898,7 +923,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
/* lock the database */
tdb_lock_bystring(tdb, "INFO/nextjob");
- next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
+ next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob");
if (next_jobid == -1)
next_jobid = 1;
@@ -913,7 +938,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
goto fail;
}
- tdb_store_int(tdb, "INFO/nextjob", jobid);
+ tdb_store_int32(tdb, "INFO/nextjob", jobid);
/* we have a job entry - now create the spool file */
slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
@@ -1106,8 +1131,9 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
}
/****************************************************************************
-get a printer queue listing
+ Get a printer queue listing.
****************************************************************************/
+
int print_queue_status(int snum,
print_queue_struct **queue,
print_status_struct *status)
@@ -1136,7 +1162,7 @@ int print_queue_status(int snum,
if (data.dsize == sizeof(*status)) {
memcpy(status, data.dptr, sizeof(*status));
}
- free(data.dptr);
+ SAFE_FREE(data.dptr);
}
/*
@@ -1178,10 +1204,10 @@ int print_queue_status(int snum,
return tstruct.qcount;
}
-
/****************************************************************************
-turn a queue name into a snum
+ Turn a queue name into a snum.
****************************************************************************/
+
int print_queue_snum(char *qname)
{
int snum = lp_servicenumber(qname);
@@ -1189,24 +1215,24 @@ int print_queue_snum(char *qname)
return snum;
}
-
/****************************************************************************
- pause a queue
+ Pause a queue.
****************************************************************************/
-BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
+
+BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
{
char *printer_name;
int ret;
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = ERRnoaccess;
+ *errcode = WERR_ACCESS_DENIED;
return False;
}
ret = (*(current_printif->queue_pause))(snum);
if (ret != 0) {
- *errcode = ERRinvalidparam;
+ *errcode = WERR_INVALID_PARAM;
return False;
}
@@ -1223,22 +1249,23 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
}
/****************************************************************************
- resume a queue
+ Resume a queue.
****************************************************************************/
-BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
+
+BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
{
char *printer_name;
int ret;
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = ERRnoaccess;
+ *errcode = WERR_ACCESS_DENIED;
return False;
}
ret = (*(current_printif->queue_resume))(snum);
if (ret != 0) {
- *errcode = ERRinvalidparam;
+ *errcode = WERR_INVALID_PARAM;
return False;
}
@@ -1255,9 +1282,10 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
}
/****************************************************************************
- purge a queue - implemented by deleting all jobs that we can delete
+ Purge a queue - implemented by deleting all jobs that we can delete.
****************************************************************************/
-BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
+
+BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
{
print_queue_struct *queue;
print_status_struct status;
diff --git a/source/profile/profile.c b/source/profile/profile.c
index 430732c6f86..8f76b5a0465 100644
--- a/source/profile/profile.c
+++ b/source/profile/profile.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
static int shm_id;
diff --git a/source/rpc_client/cli_login.c b/source/rpc_client/cli_login.c
index 40d6464c56d..2e90702e66d 100644
--- a/source/rpc_client/cli_login.c
+++ b/source/rpc_client/cli_login.c
@@ -23,7 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern fstring global_myworkgroup;
extern pstring global_myname;
@@ -31,8 +30,9 @@ extern pstring global_myname;
Initialize domain session credentials.
****************************************************************************/
-BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
+NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
{
+ NTSTATUS result;
DOM_CHAL clnt_chal;
DOM_CHAL srv_chal;
@@ -46,7 +46,7 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal))
{
DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
/**************** Long-term Session key **************/
@@ -66,14 +66,16 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
* Receive an auth-2 challenge response and check it.
*/
- if (!cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
- SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, &srv_chal))
+ result = cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, &srv_chal);
+
+ if (!NT_STATUS_IS_OK(result))
{
DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
- return False;
+ return result;
}
- return True;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -103,13 +105,13 @@ NT login - interactive.
password equivalents, protected by the session key) is inherently insecure
given the current design of the NT Domain system. JRA.
****************************************************************************/
-BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
+NTSTATUS cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
uint32 smb_userid_low, char *password,
NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
{
uchar lm_owf_user_pwd[16];
uchar nt_owf_user_pwd[16];
- BOOL ret;
+ NTSTATUS ret;
DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
@@ -156,33 +158,33 @@ NT login - network.
password equivalents over the network. JRA.
****************************************************************************/
-BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char lm_chal[8],
- char *lm_chal_resp, char *nt_chal_resp,
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+NTSTATUS cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
+ uint32 smb_userid_low, const char lm_chal[8],
+ const char *lm_chal_resp, const char *nt_chal_resp,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
{
fstring dos_wksta_name, dos_username, dos_domain;
- DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
- /* indicate a "network" login */
- ctr->switch_value = NET_LOGON_TYPE;
+ DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
+ /* indicate a "network" login */
+ ctr->switch_value = NET_LOGON_TYPE;
- fstrcpy(dos_wksta_name, cli->clnt_name_slash);
- unix_to_dos(dos_wksta_name, True);
+ fstrcpy(dos_wksta_name, cli->clnt_name_slash);
+ unix_to_dos(dos_wksta_name, True);
- fstrcpy(dos_username, username);
- unix_to_dos(dos_username, True);
+ fstrcpy(dos_username, username);
+ unix_to_dos(dos_username, True);
- fstrcpy(dos_domain, domain);
- unix_to_dos(dos_domain, True);
+ fstrcpy(dos_domain, domain);
+ unix_to_dos(dos_domain, True);
- /* Create the structure needed for SAM logon. */
- init_id_info2(&ctr->auth.id2, dos_domain, 0, smb_userid_low, 0,
- dos_username, dos_wksta_name,
- (uchar *)lm_chal, (uchar *)lm_chal_resp,
- (uchar *)nt_chal_resp);
+ /* Create the structure needed for SAM logon. */
+ init_id_info2(&ctr->auth.id2, dos_domain, 0, smb_userid_low, 0,
+ dos_username, dos_wksta_name,
+ (const uchar *)lm_chal, (const uchar *)lm_chal_resp, lm_chal_resp ? 24 : 0,
+ (const uchar *)nt_chal_resp, nt_chal_resp ? 24 : 0 );
- /* Send client sam-logon request - update credentials on success. */
- return cli_net_sam_logon(cli, ctr, user_info3);
+ /* Send client sam-logon request - update credentials on success. */
+ return cli_net_sam_logon(cli, ctr, user_info3);
}
/****************************************************************************
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 5f58f16d498..168828e5388 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -23,13 +23,8 @@
*/
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -57,7 +52,7 @@ static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
/****************************************************************************
do a LSA Logon Control2
****************************************************************************/
-BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
+BOOL cli_net_logon_ctrl2(struct cli_state *cli, NTSTATUS status_level)
{
prs_struct rbuf;
prs_struct buf;
@@ -118,13 +113,14 @@ Ensure that the server credential returned matches the session key
encrypt of the server challenge originally received. JRA.
****************************************************************************/
-BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
+NTSTATUS cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
uint32 neg_flags, DOM_CHAL *srv_chal)
{
prs_struct rbuf;
prs_struct buf;
NET_Q_AUTH_2 q_a;
BOOL ok = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
@@ -144,7 +140,7 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n"));
prs_mem_free(&buf);
prs_mem_free(&rbuf);
- return False;
+ return result;
}
/* send the data on \PIPE\ */
@@ -153,12 +149,12 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
NET_R_AUTH_2 r_a;
ok = net_io_r_auth_2("", &r_a, &rbuf, 0);
+ result = r_a.status;
- if (ok && r_a.status != 0)
+ if (ok && !NT_STATUS_IS_OK(result))
{
/* report error code */
- DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(r_a.status)));
- cli->nt_error = r_a.status;
+ DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(result)));
ok = False;
}
@@ -201,7 +197,7 @@ password ?).\n", cli->desthost ));
prs_mem_free(&buf);
prs_mem_free(&rbuf);
- return ok;
+ return result;
}
/****************************************************************************
@@ -244,11 +240,10 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
ok = net_io_r_req_chal("", &r_c, &rbuf, 0);
- if (ok && r_c.status != 0)
+ if (ok && !NT_STATUS_IS_OK(r_c.status))
{
/* report error code */
DEBUG(0,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
- cli->nt_error = r_c.status;
ok = False;
}
@@ -310,11 +305,10 @@ BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
- if (ok && r_s.status != 0)
+ if (ok && !NT_STATUS_IS_OK(r_s.status))
{
/* report error code */
DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
ok = False;
}
@@ -341,8 +335,9 @@ password ?).\n", cli->desthost ));
returns level 3.
****************************************************************************/
-static uint32 cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
- NET_USER_INFO_3 *user_info3, uint16 validation_level)
+static NTSTATUS cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3,
+ uint16 validation_level)
{
DOM_CRED new_clnt_cred;
DOM_CRED dummy_rtn_creds;
@@ -350,7 +345,7 @@ static uint32 cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR
prs_struct buf;
NET_Q_SAM_LOGON q_s;
NET_R_SAM_LOGON r_s;
- uint32 retval;
+ NTSTATUS retval = NT_STATUS_OK;
gen_next_creds( cli, &new_clnt_cred);
@@ -382,8 +377,8 @@ static uint32 cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR
/* send the data on \PIPE\ */
if (!rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf)) {
- DEBUG(0,("cli_net_sam_logon_internal: Erro rpc_api_pipe_req failed.\n"));
- retval = cli->nt_error;
+ DEBUG(0,("cli_net_sam_logon_internal: Error rpc_api_pipe_req failed.\n"));
+ retval = NT_STATUS_UNSUCCESSFUL;
goto out;
}
@@ -402,14 +397,13 @@ static uint32 cli_net_sam_logon_internal(struct cli_state *cli, NET_ID_INFO_CTR
* the call.
*/
- if (retval == NT_STATUS_INVALID_INFO_CLASS) {
+ if (NT_STATUS_V(retval) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
goto out;
}
- if (retval != 0) {
+ if (!NT_STATUS_IS_OK(retval)) {
/* report error code */
DEBUG(0,("cli_net_sam_logon_internal: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
goto out;
}
@@ -442,18 +436,18 @@ password ?).\n", cli->desthost ));
LSA SAM Logon - interactive or network.
****************************************************************************/
-BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+NTSTATUS cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
{
- BOOL ok = True;
uint16 validation_level=3;
- uint32 ret_err_code;
+ NTSTATUS result;
- ret_err_code = cli_net_sam_logon_internal(cli, ctr, user_info3, validation_level);
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
- if(ret_err_code == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result)) {
DEBUG(10,("cli_net_sam_logon: Success \n"));
- ok = True;
- } else if (ret_err_code == NT_STATUS_INVALID_INFO_CLASS) {
+ } else if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
DEBUG(10,("cli_net_sam_logon: STATUS INVALID INFO CLASS \n"));
validation_level=2;
@@ -463,15 +457,11 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INF
* for the error. If its error, return False.
*/
- if(cli_net_sam_logon_internal(cli, ctr, user_info3, validation_level) != 0)
- ok = False;
-
- } else {
- DEBUG(10,("cli_net_sam_logon: Error\n"));
- ok = False;
+ result = cli_net_sam_logon_internal(cli, ctr, user_info3,
+ validation_level);
}
- return ok;
+ return result;
}
/***************************************************************************
@@ -525,11 +515,10 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0);
- if (ok && r_s.status != 0)
+ if (ok && !NT_STATUS_IS_OK(r_s.status))
{
/* report error code */
DEBUG(0,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
ok = False;
}
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index 4bbbac17ed3..d6332c83bc4 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -24,7 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern struct pipe_id_info pipe_names[];
extern fstring global_myworkgroup;
extern pstring global_myname;
@@ -81,11 +80,13 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re
DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
num_read, stream_offset, data_to_read));
- if (cli_error(cli, &eclass, &ecode, NULL) &&
- (eclass != ERRDOS && ecode != ERRmoredata)) {
- DEBUG(0,("rpc_read: Error %d/%u in cli_read\n",
- eclass, (unsigned int)ecode));
- return False;
+ if (cli_is_dos_error(cli)) {
+ cli_dos_error(cli, &eclass, &ecode);
+ if (eclass != ERRDOS && ecode != ERRmoredata) {
+ DEBUG(0,("rpc_read: Error %d/%u in cli_read\n",
+ eclass, (unsigned int)ecode));
+ return False;
+ }
}
data_to_read -= num_read;
@@ -361,10 +362,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr
/* Throw away returned params - we know we won't use them. */
- if(rparam) {
- free(rparam);
- rparam = NULL;
- }
+ SAFE_FREE(rparam);
if (prdata == NULL) {
DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n",
@@ -468,11 +466,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr
prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
- if (cli_error(cli, &eclass, &ecode, NULL) &&
- (eclass != ERRDOS && ecode != ERRmoredata)) {
- DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n",
- eclass, ecode));
- return False;
+
+ if (cli_is_dos_error(cli)) {
+ cli_dos_error(cli, &eclass, &ecode);
+ if (eclass != ERRDOS && ecode != ERRmoredata) {
+ DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
+ return False;
+ }
}
DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
@@ -897,7 +897,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
Set the handle state.
****************************************************************************/
-static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
+static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, uint16 device_state)
{
BOOL state_set = False;
char param[2];
@@ -931,10 +931,8 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1
state_set = True;
}
- if (rparam)
- free(rparam);
- if (rdata)
- free(rdata );
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
return state_set;
}
@@ -943,7 +941,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1
check the rpc bind acknowledge response
****************************************************************************/
-static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
+static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
{
int pipe_idx = 0;
@@ -973,7 +971,7 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra
check the rpc bind acknowledge response
****************************************************************************/
-static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
+static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, RPC_IFACE *transfer)
{
int i = 0;
@@ -1107,7 +1105,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
Do an rpc bind.
****************************************************************************/
-BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
+BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name)
{
RPC_IFACE abstract;
RPC_IFACE transfer;
@@ -1192,16 +1190,16 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
Open a session.
****************************************************************************/
-BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name)
{
int fnum;
SMB_ASSERT(cli->nt_pipe_fnum == 0);
if (cli->capabilities & CAP_NT_SMBS) {
- if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -1) {
+ if ((fnum = cli_nt_create(cli, &pipe_name[5], DESIRED_ACCESS_PIPE)) == -1) {
DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
- &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
+ &pipe_name[5], cli->desthost, cli_errstr(cli)));
return False;
}
diff --git a/source/rpc_client/cli_spoolss_notify.c b/source/rpc_client/cli_spoolss_notify.c
index 2f712f6adbc..a96fd8e0dde 100644
--- a/source/rpc_client/cli_spoolss_notify.c
+++ b/source/rpc_client/cli_spoolss_notify.c
@@ -22,10 +22,8 @@
#include "includes.h"
#include "rpc_parse.h"
-#include "rpc_client.h"
#include "nterr.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
/*********************************************************
@@ -48,7 +46,7 @@ BOOL spoolss_disconnect_from_client( struct cli_state *cli)
BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine)
{
ZERO_STRUCTP(cli);
- if(!cli_initialise(cli)) {
+ if(cli_initialise(cli) == NULL) {
DEBUG(0,("connect_to_client: unable to initialize client connection.\n"));
return False;
}
@@ -133,7 +131,7 @@ BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine)
do a reply open printer
****************************************************************************/
-BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, uint32 *status, POLICY_HND *handle)
+BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, WERROR *status, POLICY_HND *handle)
{
prs_struct rbuf;
prs_struct buf;
@@ -189,7 +187,7 @@ BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32
****************************************************************************/
BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle,
- uint32 change_low, uint32 change_high, uint32 *status)
+ uint32 change_low, uint32 change_high, WERROR *status)
{
prs_struct rbuf;
prs_struct buf;
@@ -243,7 +241,8 @@ BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle,
do a reply open printer
****************************************************************************/
-BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle, uint32 *status)
+BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle,
+ WERROR *status)
{
prs_struct rbuf;
prs_struct buf;
diff --git a/source/rpc_client/cli_trust.c b/source/rpc_client/cli_trust.c
index 440cc5143a2..c910e2f334a 100644
--- a/source/rpc_client/cli_trust.c
+++ b/source/rpc_client/cli_trust.c
@@ -35,6 +35,17 @@ static BOOL modify_trust_password( char *domain, char *remote_machine,
unsigned char new_trust_passwd_hash[16])
{
struct cli_state cli;
+ NTSTATUS result;
+ DOM_SID domain_sid;
+
+ /*
+ * Ensure we have the domain SID for this domain.
+ */
+
+ if (!secrets_fetch_domain_sid(domain, &domain_sid)) {
+ DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n"));
+ return False;
+ }
ZERO_STRUCT(cli);
if(cli_initialise(&cli) == NULL) {
@@ -115,13 +126,6 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
* Now start the NT Domain stuff :-).
*/
- if(cli_lsa_get_domain_sid(&cli, remote_machine) == False) {
- DEBUG(0,("modify_trust_password: unable to obtain domain sid from %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
DEBUG(0,("modify_trust_password: unable to open the domain client session to \
machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
@@ -131,9 +135,11 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
return False;
}
- if(cli_nt_setup_creds(&cli, orig_trust_passwd_hash) == False) {
+ result = cli_nt_setup_creds(&cli, orig_trust_passwd_hash);
+
+ if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
+%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result)));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
@@ -207,15 +213,14 @@ account password for domain %s.\n", domain));
for(i = 0; i < count; i++) {
fstring dc_name;
- if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name))
+ if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name))
continue;
if((res = modify_trust_password( domain, dc_name,
old_trust_passwd_hash, new_trust_passwd_hash)))
break;
}
- if(ip_list != NULL)
- free((char *)ip_list);
+ SAFE_FREE(ip_list);
} else {
res = modify_trust_password( domain, remote_machine,
diff --git a/source/rpc_parse/.cvsignore b/source/rpc_parse/.cvsignore
index e69de29bb2d..5f2a5c4cf75 100644
--- a/source/rpc_parse/.cvsignore
+++ b/source/rpc_parse/.cvsignore
@@ -0,0 +1,2 @@
+*.po
+*.po32
diff --git a/source/rpc_parse/parse_dfs.c b/source/rpc_parse/parse_dfs.c
index 7e0959d2f35..a152e3528e3 100644
--- a/source/rpc_parse/parse_dfs.c
+++ b/source/rpc_parse/parse_dfs.c
@@ -26,7 +26,14 @@
#include "nterr.h"
#include "rpc_parse.h"
-extern int DEBUGLEVEL;
+/*******************************************************************
+Make a DFS_Q_DFS_QUERY structure
+*******************************************************************/
+
+void init_dfs_q_dfs_exist(DFS_Q_DFS_EXIST *q_d)
+{
+ q_d->dummy = 0;
+}
/*************************************************************
Read/write a DFS_Q_DFS_EXIST structure - dummy...
@@ -67,10 +74,10 @@ BOOL dfs_io_r_dfs_exist(char *desc, DFS_R_DFS_EXIST *q_d, prs_struct *ps, int de
Make a DFS_Q_DFS_REMOVE structure
*******************************************************************/
-BOOL make_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, char *entrypath,
+BOOL init_dfs_q_dfs_remove(DFS_Q_DFS_REMOVE *q_d, char *entrypath,
char *servername, char *sharename)
{
- DEBUG(5,("make_dfs_q_dfs_remove\n"));
+ DEBUG(5,("init_dfs_q_dfs_remove\n"));
init_unistr2(&q_d->DfsEntryPath, entrypath, strlen(entrypath)+1);
init_unistr2(&q_d->ServerName, servername, strlen(servername)+1);
init_unistr2(&q_d->ShareName, sharename, strlen(sharename)+1);
@@ -112,6 +119,8 @@ BOOL dfs_io_q_dfs_remove(char *desc, DFS_Q_DFS_REMOVE *q_d, prs_struct *ps, int
if(q_d->ptr_ShareName)
if (!smb_io_unistr2("ShareName",&q_d->ShareName, q_d->ptr_ShareName, ps, depth))
return False;
+ if(!prs_align(ps))
+ return False;
return True;
}
@@ -128,7 +137,7 @@ BOOL dfs_io_r_dfs_remove(char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps, int
prs_debug(ps, depth, desc, "dfs_io_r_dfs_remove");
depth++;
- if(!prs_uint32("status", ps, depth, &r_d->status))
+ if(!prs_werror("status", ps, depth, &r_d->status))
return False;
return True;
@@ -138,10 +147,10 @@ BOOL dfs_io_r_dfs_remove(char *desc, DFS_R_DFS_REMOVE *r_d, prs_struct *ps, int
Make a DFS_Q_DFS_ADD structure
*******************************************************************/
-BOOL make_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, char *entrypath, char *servername,
+BOOL init_dfs_q_dfs_add(DFS_Q_DFS_ADD *q_d, char *entrypath, char *servername,
char *sharename, char *comment, uint32 flags)
{
- DEBUG(5,("make_dfs_q_dfs_add\n"));
+ DEBUG(5,("init_dfs_q_dfs_add\n"));
q_d->ptr_DfsEntryPath = q_d->ptr_ServerName = q_d->ptr_ShareName = 1;
init_unistr2(&q_d->DfsEntryPath, entrypath, strlen(entrypath)+1);
init_unistr2(&q_d->ServerName, servername, strlen(servername)+1);
@@ -214,12 +223,25 @@ BOOL dfs_io_r_dfs_add(char *desc, DFS_R_DFS_ADD *r_d, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "dfs_io_r_dfs_add");
depth++;
- if(!prs_uint32("status", ps, depth, &r_d->status))
+ if(!prs_werror("status", ps, depth, &r_d->status))
return False;
return True;
}
+BOOL init_dfs_q_dfs_get_info(DFS_Q_DFS_GET_INFO *q_d, char *entrypath,
+ char *servername, char *sharename,
+ uint32 info_level)
+{
+ DEBUG(5,("init_dfs_q2_get_info\n"));
+ init_unistr2(&q_d->uni_path, entrypath, strlen(entrypath)+1);
+ init_unistr2(&q_d->uni_server, servername, strlen(servername)+1);
+ init_unistr2(&q_d->uni_share, sharename, strlen(sharename)+1);
+ q_d->level = info_level;
+ q_d->ptr_server = q_d->ptr_share = 1;
+ return True;
+}
+
/************************************************************
Read/write a DFS_Q_GET_INFO structure
************************************************************/
@@ -276,7 +298,7 @@ BOOL dfs_io_r_dfs_get_info(char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps,
if(!dfs_io_dfs_info_ctr("", &r_i->ctr, 1, r_i->level, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_i->status))
+ if(!prs_werror("status", ps, depth, &r_i->status))
return False;
return True;
}
@@ -284,7 +306,7 @@ BOOL dfs_io_r_dfs_get_info(char* desc, DFS_R_DFS_GET_INFO* r_i, prs_struct* ps,
/************************************************************
Make a DFS_Q_DFS_ENUM structure
************************************************************/
-BOOL make_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr)
+BOOL init_dfs_q_dfs_enum(DFS_Q_DFS_ENUM *q_d, uint32 level, DFS_INFO_CTR *ctr)
{
q_d->level = level;
q_d->maxpreflen = -1;
@@ -477,7 +499,7 @@ BOOL dfs_io_r_dfs_enum(char *desc, DFS_R_DFS_ENUM *q_d, prs_struct *ps, int dept
if(!smb_io_enum_hnd("resume_hnd", &q_d->reshnd, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &q_d->status))
+ if(!prs_werror("status", ps, depth, &q_d->status))
return False;
return True;
}
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index 5128bb1dbbc..10a9efbe49d 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -23,8 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth);
/*******************************************************************
@@ -248,11 +246,14 @@ static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps,
if(!prs_uint32("ptr_sec_qos ", ps, depth, &attr->ptr_sec_qos )) /* security quality of service (pointer) */
return False;
+ /* code commented out as it's not necessary true (tested with hyena). JFM, 11/22/2001 */
+#if 0
if (attr->len != prs_offset(ps) - start) {
DEBUG(3,("lsa_io_obj_attr: length %x does not match size %x\n",
attr->len, prs_offset(ps) - start));
return False;
}
+#endif
if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL) {
if(!lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth))
@@ -324,7 +325,7 @@ BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps,
if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_p->status))
+ if(!prs_ntstatus("status", ps, depth, &r_p->status))
return False;
return True;
@@ -391,7 +392,7 @@ BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps,
if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_p->status))
+ if(!prs_ntstatus("status", ps, depth, &r_p->status))
return False;
return True;
@@ -452,7 +453,7 @@ BOOL lsa_io_r_query_sec_obj(char *desc, LSA_R_QUERY_SEC_OBJ *r_u,
return False;
}
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -532,13 +533,13 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
char *domain_name, DOM_SID *domain_sid,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_r_enum_trust_dom\n"));
r_e->enum_context = enum_context;
- if (status == 0) {
+ if (NT_STATUS_IS_OK(status)) {
int len_domain_name = strlen(domain_name) + 1;
r_e->num_domains = 1;
@@ -619,7 +620,7 @@ BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
}
}
- if(!prs_uint32("status", ps, depth, &r_e->status))
+ if(!prs_ntstatus("status", ps, depth, &r_e->status))
return False;
return True;
@@ -789,7 +790,7 @@ BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -853,6 +854,15 @@ static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen, prs_struct *ps,
return False;
if(!prs_uint32("ptr_sid_enum", ps, depth, &sen->ptr_sid_enum))
return False;
+
+ /*
+ if the ptr is NULL, leave here. checked from a real w2k trace.
+ JFM, 11/23/2001
+ */
+
+ if (sen->ptr_sid_enum==0)
+ return True;
+
if(!prs_uint32("num_entries2", ps, depth, &sen->num_entries2))
return False;
@@ -1031,7 +1041,7 @@ BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s,
if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count))
return False;
- if(!prs_uint32("status ", ps, depth, &r_s->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_s->status))
return False;
return True;
@@ -1192,7 +1202,7 @@ BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r,
if(!prs_uint32("mapped_count", ps, depth, &r_r->mapped_count))
return False;
- if(!prs_uint32("status ", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_r->status))
return False;
return True;
@@ -1237,7 +1247,7 @@ BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth)
if(!smb_io_pol_hnd("", &r_c->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_c->status))
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
return False;
return True;
@@ -1276,12 +1286,310 @@ BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, in
return False;
if(!prs_uint32("dummy4", ps, depth, &r_c->dummy4))
return False;
- if(!prs_uint32("status", ps, depth, &r_c->status))
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits an LSA_Q_ENUM_PRIVS structure.
+********************************************************************/
+
+void init_q_enum_privs(LSA_Q_ENUM_PRIVS *q_q, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length)
+{
+ DEBUG(5, ("init_q_enum_privs\n"));
+
+ memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
+
+ q_q->enum_context = enum_context;
+ q_q->pref_max_length = pref_max_length;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_q_enum_privs(char *desc, LSA_Q_ENUM_PRIVS *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_enum_privs");
+ depth++;
+
+ if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ return False;
+
+ if(!prs_uint32("enum_context ", ps, depth, &q_q->enum_context))
+ return False;
+ if(!prs_uint32("pref_max_length", ps, depth, &q_q->pref_max_length))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL lsa_io_priv_entries(char *desc, LSA_PRIV_ENTRY *entries, uint32 count, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ if (entries == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_priv_entries");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ for (i = 0; i < count; i++) {
+ if (!smb_io_unihdr("", &entries[i].hdr_name, ps, depth))
+ return False;
+ if(!prs_uint32("luid_low ", ps, depth, &entries[i].luid_low))
+ return False;
+ if(!prs_uint32("luid_high", ps, depth, &entries[i].luid_high))
+ return False;
+ }
+
+ for (i = 0; i < count; i++)
+ if (!smb_io_unistr2("", &entries[i].name, entries[i].hdr_name.buffer, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits an LSA_R_ENUM_PRIVS structure.
+********************************************************************/
+
+void init_lsa_r_enum_privs(LSA_R_ENUM_PRIVS *r_u, uint32 enum_context,
+ uint32 count, LSA_PRIV_ENTRY *entries)
+{
+ DEBUG(5, ("init_lsa_r_enum_privs\n"));
+
+ r_u->enum_context=enum_context;
+ r_u->count=count;
+
+ if (entries!=NULL) {
+ r_u->ptr=1;
+ r_u->count1=count;
+ r_u->privs=entries;
+ } else {
+ r_u->ptr=0;
+ r_u->count1=0;
+ r_u->privs=NULL;
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_r_enum_privs(char *desc, LSA_R_ENUM_PRIVS *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_enum_privs");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("enum_context", ps, depth, &r_q->enum_context))
+ return False;
+ if(!prs_uint32("count", ps, depth, &r_q->count))
+ return False;
+ if(!prs_uint32("ptr", ps, depth, &r_q->ptr))
+ return False;
+
+ if (r_q->ptr) {
+ if(!prs_uint32("count1", ps, depth, &r_q->count1))
+ return False;
+
+ if (UNMARSHALLING(ps))
+ if (!(r_q->privs = (LSA_PRIV_ENTRY *)prs_alloc_mem(ps, sizeof(LSA_PRIV_ENTRY) * r_q->count1)))
+ return False;
+
+ if (!lsa_io_priv_entries("", r_q->privs, r_q->count1, ps, depth))
+ return False;
+ }
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
}
+void init_lsa_priv_get_dispname(LSA_Q_PRIV_GET_DISPNAME *trn, POLICY_HND *hnd, char *name, uint16 lang_id, uint16 lang_id_sys)
+{
+ int len_name = strlen(name);
+
+ if(len_name == 0)
+ len_name = 1;
+
+ memcpy(&trn->pol, hnd, sizeof(trn->pol));
+
+ init_uni_hdr(&trn->hdr_name, len_name);
+ init_unistr2(&trn->name, name, len_name);
+ trn->lang_id = lang_id;
+ trn->lang_id_sys = lang_id_sys;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_q_priv_get_dispname(char *desc, LSA_Q_PRIV_GET_DISPNAME *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_priv_get_dispname");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ return False;
+
+ if (!smb_io_unihdr("hdr_name", &q_q->hdr_name, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("name", &q_q->name, q_q->hdr_name.buffer, ps, depth))
+ return False;
+
+ if(!prs_uint16("lang_id ", ps, depth, &q_q->lang_id))
+ return False;
+ if(!prs_uint16("lang_id_sys", ps, depth, &q_q->lang_id_sys))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_r_priv_get_dispname(char *desc, LSA_R_PRIV_GET_DISPNAME *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_priv_get_dispname");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_info", ps, depth, &r_q->ptr_info))
+ return False;
+
+ if (r_q->ptr_info){
+ if (!smb_io_unihdr("hdr_name", &r_q->hdr_desc, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("desc", &r_q->desc, r_q->hdr_desc.buffer, ps, depth))
+ return False;
+ }
+/*
+ if(!prs_align(ps))
+ return False;
+*/
+ if(!prs_uint16("lang_id", ps, depth, &r_q->lang_id))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ return False;
+
+ return True;
+}
+
+void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length)
+{
+ memcpy(&trn->pol, hnd, sizeof(trn->pol));
+
+ trn->enum_context = enum_context;
+ trn->pref_max_length = pref_max_length;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_q_enum_accounts(char *desc, LSA_Q_ENUM_ACCOUNTS *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_enum_accounts");
+ depth++;
+
+ if (!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ return False;
+
+ if(!prs_uint32("enum_context ", ps, depth, &q_q->enum_context))
+ return False;
+ if(!prs_uint32("pref_max_length", ps, depth, &q_q->pref_max_length))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits an LSA_R_ENUM_PRIVS structure.
+********************************************************************/
+
+void init_lsa_r_enum_accounts(LSA_R_ENUM_ACCOUNTS *r_u, uint32 enum_context)
+{
+ DEBUG(5, ("init_lsa_r_enum_accounts\n"));
+
+ r_u->enum_context=enum_context;
+ if (r_u->enum_context!=0) {
+ r_u->sids.num_entries=enum_context;
+ r_u->sids.ptr_sid_enum=1;
+ r_u->sids.num_entries2=enum_context;
+ } else {
+ r_u->sids.num_entries=0;
+ r_u->sids.ptr_sid_enum=0;
+ r_u->sids.num_entries2=0;
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL lsa_io_r_enum_accounts(char *desc, LSA_R_ENUM_ACCOUNTS *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_enum_accounts");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("enum_context", ps, depth, &r_q->enum_context))
+ return False;
+
+ if (!lsa_io_sid_enum("sids", &r_q->sids, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ return False;
+
+ return True;
+}
+
+
/*******************************************************************
Reads or writes an LSA_Q_UNK_GET_CONNUSER structure.
********************************************************************/
@@ -1346,7 +1654,221 @@ BOOL lsa_io_r_unk_get_connuser(char *desc, LSA_R_UNK_GET_CONNUSER *r_c, prs_stru
if (!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_c->status))
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_Q_OPENACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_q_open_account(char *desc, LSA_Q_OPENACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_q_open_account");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ if(!smb_io_dom_sid2("", &r_c->sid, ps, depth)) /* domain SID */
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &r_c->access))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_R_OPENACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_r_open_account(char *desc, LSA_R_OPENACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_r_open_account");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+ Reads or writes an LSA_Q_ENUMPRIVSACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_q_enum_privsaccount(char *desc, LSA_Q_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_q_enum_privsaccount");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LUID structure.
+********************************************************************/
+
+BOOL lsa_io_luid(char *desc, LUID *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_luid");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("low", ps, depth, &r_c->low))
+ return False;
+
+ if(!prs_uint32("high", ps, depth, &r_c->high))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LUID_ATTR structure.
+********************************************************************/
+
+BOOL lsa_io_luid_attr(char *desc, LUID_ATTR *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_luid_attr");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!lsa_io_luid(desc, &r_c->luid, ps, depth))
+ return False;
+
+ if(!prs_uint32("attr", ps, depth, &r_c->attr))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an PRIVILEGE_SET structure.
+********************************************************************/
+
+BOOL lsa_io_privilege_set(char *desc, PRIVILEGE_SET *r_c, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ prs_debug(ps, depth, desc, "lsa_io_privilege_set");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("count", ps, depth, &r_c->count))
+ return False;
+ if(!prs_uint32("control", ps, depth, &r_c->control))
+ return False;
+
+ for (i=0; i<r_c->count; i++) {
+ if (!lsa_io_luid_attr(desc, &r_c->set[i], ps, depth))
+ return False;
+ }
+
+ return True;
+}
+
+void init_lsa_r_enum_privsaccount(LSA_R_ENUMPRIVSACCOUNT *r_u, LUID_ATTR *set, uint32 count, uint32 control)
+{
+ r_u->ptr=1;
+ r_u->count=count;
+ r_u->set.set=set;
+ r_u->set.count=count;
+ r_u->set.control=control;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_R_ENUMPRIVSACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_r_enum_privsaccount(char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_r_enum_privsaccount");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
+ return False;
+
+ if (r_c->ptr!=0) {
+ if(!prs_uint32("count", ps, depth, &r_c->count))
+ return False;
+
+ /* malloc memory if unmarshalling here */
+
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
+ return False;
+ }
+
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
+ return False;
+
+ return True;
+}
+
+
+
+/*******************************************************************
+ Reads or writes an LSA_Q_GETSYSTEMACCOUNTstructure.
+********************************************************************/
+
+BOOL lsa_io_q_getsystemaccount(char *desc, LSA_Q_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_q_getsystemaccount");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_R_GETSYSTEMACCOUNTstructure.
+********************************************************************/
+
+BOOL lsa_io_r_getsystemaccount(char *desc, LSA_R_GETSYSTEMACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_r_getsystemaccount");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &r_c->access))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index 541738413a0..afb829637c3 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
A temporary TALLOC context for things like unistrs, that is valid for
the life of a complete RPC call.
@@ -296,7 +294,7 @@ void init_dom_sid(DOM_SID *sid, char *str_sid)
Inits a DOM_SID2 structure.
********************************************************************/
-void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid)
+void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
{
sid2->sid = *sid;
sid2->num_auths = sid2->sid.num_auths;
@@ -787,7 +785,7 @@ void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
Copies a UNISTR2 structure.
********************************************************************/
-void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
+void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
{
/* set up string lengths. add one if string is not null-terminated */
@@ -824,23 +822,23 @@ void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
Creates a STRING2 structure.
********************************************************************/
-void init_string2(STRING2 *str, char *buf, int len)
+void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
{
int alloc_len = 0;
/* set up string lengths. */
- str->str_max_len = len;
+ str->str_max_len = max_len;
str->undoc = 0;
- str->str_str_len = len;
+ str->str_str_len = str_len;
/* store the string */
- if(len != 0) {
- if (len < MAX_STRINGLEN)
+ if(str_len != 0) {
+ if (str_len < MAX_STRINGLEN)
alloc_len = MAX_STRINGLEN;
str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
if (str->buffer == NULL)
smb_panic("init_string2: malloc fail\n");
- memcpy(str->buffer, buf, len);
+ memcpy(str->buffer, buf, str_len);
}
}
@@ -911,6 +909,13 @@ void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
return;
}
+ /*
+ * don't move this test above ! The UNISTR2 must be initialized !!!
+ * jfm, 7/7/2001.
+ */
+ if (buf==NULL)
+ return;
+
/* store the string (null-terminated 8 bit chars into 16 bit chars) */
dos_struni2((char *)str->buffer, buf, len);
}
@@ -1525,4 +1530,68 @@ BOOL prs_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64)
prs_uint32(name, ps, depth+1, &data64->high);
}
+/*******************************************************************
+reads or writes a BUFHDR2 structure.
+********************************************************************/
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_bufhdr2");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &(hdr->info_level));
+ prs_uint32("length ", ps, depth, &(hdr->length ));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a BUFFER4 structure.
+********************************************************************/
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_buffer4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
+
+ if (buf4->buf_len > MAX_BUFFERLEN)
+ {
+ buf4->buf_len = MAX_BUFFERLEN;
+ }
+
+ prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
+
+ return True;
+}
+
+/*******************************************************************
+creates a UNIHDR structure.
+********************************************************************/
+
+BOOL make_uni_hdr(UNIHDR *hdr, int len)
+{
+ if (hdr == NULL)
+ {
+ return False;
+ }
+ hdr->uni_str_len = 2 * len;
+ hdr->uni_max_len = 2 * len;
+ hdr->buffer = len != 0 ? 1 : 0;
+
+ return True;
+}
+
+/*******************************************************************
+creates a BUFHDR2 structure.
+********************************************************************/
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
+{
+ hdr->info_level = info_level;
+ hdr->length = length;
+ hdr->buffer = buffer;
+ return True;
+}
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index a4964e4b422..e3f7ea5d9ae 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -23,8 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
Reads or writes a structure.
********************************************************************/
@@ -142,9 +140,9 @@ static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_statu
info->tc_status = tc_status;
if (trusted_dc_name != NULL)
- init_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
+ init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, len_dc_name+1);
else
- init_unistr2(&(info->uni_trusted_dc_name), "", 1);
+ init_unistr2(&info->uni_trusted_dc_name, "", 1);
}
/*******************************************************************
@@ -249,18 +247,18 @@ void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
case 1:
r_l->ptr = 1; /* undocumented pointer */
init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
- r_l->status = 0;
+ r_l->status = NT_STATUS_OK;
break;
case 2:
r_l->ptr = 1; /* undocumented pointer */
init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
tc_status, trusted_domain_name);
- r_l->status = 0;
+ r_l->status = NT_STATUS_OK;
break;
case 3:
r_l->ptr = 1; /* undocumented pointer */
- init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);
- r_l->status = 0;
+ init_netinfo_3(&r_l->logon.info3, flags, logon_attempts);
+ r_l->status = NT_STATUS_OK;
break;
default:
DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
@@ -311,7 +309,7 @@ BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, in
}
}
- if(!prs_uint32("status ", ps, depth, &r_l->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_l->status))
return False;
return True;
@@ -377,7 +375,7 @@ void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
case 1:
r_l->ptr = 1; /* undocumented pointer */
init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
- r_l->status = 0;
+ r_l->status = NT_STATUS_OK;
break;
default:
DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
@@ -418,7 +416,7 @@ BOOL net_io_r_logon_ctrl(char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps,
}
}
- if(!prs_uint32("status ", ps, depth, &r_l->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_l->status))
return False;
return True;
@@ -451,7 +449,7 @@ void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
r_t->uni_trust_dom_name[i].undoc = 0x1;
}
- r_t->status = 0;
+ r_t->status = NT_STATUS_OK;
}
/*******************************************************************
@@ -499,7 +497,7 @@ BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, i
return False;
}
- if(!prs_uint32("status", ps, depth, &r_t->status))
+ if(!prs_ntstatus("status", ps, depth, &r_t->status))
return False;
#endif
return True;
@@ -602,7 +600,7 @@ BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int dept
if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
return False;
- if(!prs_uint32("status", ps, depth, &r_c->status))
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
return False;
return True;
@@ -658,7 +656,7 @@ BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
return False;
- if(!prs_uint32("status", ps, depth, &r_a->status))
+ if(!prs_ntstatus("status", ps, depth, &r_a->status))
return False;
return True;
@@ -734,7 +732,7 @@ BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_a->status))
+ if(!prs_ntstatus("status", ps, depth, &r_a->status))
return False;
return True;
@@ -796,7 +794,7 @@ BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int de
if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
return False;
- if(!prs_uint32("status", ps, depth, &r_s->status))
+ if(!prs_ntstatus("status", ps, depth, &r_s->status))
return False;
return True;
@@ -976,20 +974,19 @@ checking for a logon as it doesn't export the password
hashes to anyone who has compromised the secure channel. JRA.
********************************************************************/
-void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- unsigned char lm_challenge[8],
- unsigned char *lm_chal_resp,
- unsigned char *nt_chal_resp)
+void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar * lm_chal_resp, int lm_chal_resp_len,
+ const uchar * nt_chal_resp, int nt_chal_resp_len)
{
int len_domain_name = strlen(domain_name);
int len_user_name = strlen(user_name );
int len_wksta_name = strlen(wksta_name );
- int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
- int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
unsigned char lm_owf[24];
- unsigned char nt_owf[24];
+ unsigned char nt_owf[128];
DEBUG(5,("init_id_info2: %d\n", __LINE__));
@@ -1005,25 +1002,26 @@ void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
if (nt_chal_resp) {
/* oops. can only send what-ever-it-is direct */
- memcpy(nt_owf, nt_chal_resp, 24);
+ memcpy(nt_owf, nt_chal_resp, MIN(sizeof(nt_owf), nt_chal_resp_len));
nt_chal_resp = nt_owf;
}
if (lm_chal_resp) {
/* oops. can only send what-ever-it-is direct */
- memcpy(lm_owf, lm_chal_resp, 24);
+ memcpy(lm_owf, lm_chal_resp, MIN(sizeof(lm_owf), lm_chal_resp_len));
lm_chal_resp = lm_owf;
}
memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
- init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
- init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
+ init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
+ init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
init_unistr2(&id->uni_user_name, user_name, len_user_name);
init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
- init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
- init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
+ init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
+ init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
+
}
/*******************************************************************
@@ -1098,7 +1096,7 @@ void init_sam_info(DOM_SAM_INFO *sam,
{
DEBUG(5,("init_sam_info: %d\n", __LINE__));
- init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
+ init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred);
if (rtn_cred != NULL) {
sam->ptr_rtn_cred = 1;
@@ -1195,7 +1193,7 @@ static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int d
void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
uint16 logon_count, uint16 bad_pw_count,
uint32 num_groups, DOM_GID *gids,
- uint32 user_flgs, char *sess_key,
+ uint32 user_flgs, uchar *sess_key,
char *logon_srv, char *logon_dom,
DOM_SID *dom_sid, char *other_sids)
{
@@ -1211,12 +1209,12 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sam
int len_user_name, len_full_name, len_home_dir,
len_dir_drive, len_logon_script, len_profile_path;
- char* user_name = pdb_get_username(sampw);
- char* full_name = pdb_get_fullname(sampw);
- char* home_dir = pdb_get_homedir(sampw);
- char* dir_drive = pdb_get_dirdrive(sampw);
- char* logon_script = pdb_get_logon_script(sampw);
- char* profile_path = pdb_get_profile_path(sampw);
+ const char* user_name = pdb_get_username(sampw);
+ const char* full_name = pdb_get_fullname(sampw);
+ const char* home_dir = pdb_get_homedir(sampw);
+ const char* dir_drive = pdb_get_dirdrive(sampw);
+ const char* logon_script = pdb_get_logon_script(sampw);
+ const char* profile_path = pdb_get_profile_path(sampw);
int len_logon_srv = strlen(logon_srv);
int len_logon_dom = strlen(logon_dom);
@@ -1259,8 +1257,8 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sam
usr->logon_count = logon_count;
usr->bad_pw_count = bad_pw_count;
- usr->user_id = pdb_get_user_rid(sampw);
- usr->group_id = pdb_get_group_rid(sampw);
+ usr->user_rid = pdb_get_user_rid(sampw);
+ usr->group_rid = pdb_get_group_rid(sampw);
usr->num_groups = num_groups+1;
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
@@ -1300,11 +1298,11 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sam
/* primary group **MUST** go first. NT4's winmsd.exe will give
"The Network statistics are currently not available. 9-5"
What the heck is this? -- jerry */
- usr->gids[0].g_rid = usr->group_id;
+ usr->gids[0].g_rid = usr->group_rid;
usr->gids[0].attr = 0x07;
for (i = 0; i < num_groups; i++)
usr->gids[i+1] = gids[i];
-
+
init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
@@ -1373,9 +1371,9 @@ static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!prs_uint16("bad_pw_count ", ps, depth, &usr->bad_pw_count)) /* bad password count */
return False;
- if(!prs_uint32("user_id ", ps, depth, &usr->user_id)) /* User ID */
+ if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User RID */
return False;
- if(!prs_uint32("group_id ", ps, depth, &usr->group_id)) /* Group ID */
+ if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group RID */
return False;
if(!prs_uint32("num_groups ", ps, depth, &usr->num_groups)) /* num groups */
return False;
@@ -1491,7 +1489,7 @@ BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int de
if(!prs_align(ps))
return False;
- if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */
+ if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
return False;
if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
@@ -1535,7 +1533,7 @@ BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int de
if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
return False;
- if(!prs_uint32("status ", ps, depth, &r_l->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_l->status))
return False;
if(!prs_align(ps))
@@ -1585,8 +1583,1004 @@ BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int
if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
return False;
- if(!prs_uint32("status ", ps, depth, &r_l->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_l->status))
return False;
return True;
}
+
+/*******************************************************************
+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,
+ uint32 database_id)
+{
+ DEBUG(5, ("init_q_sam_sync\n"));
+
+ init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
+ init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
+
+ if (cli_creds) {
+ memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
+ memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
+ }
+
+ q_s->database_id = database_id;
+ q_s->restart_state = 0;
+ q_s->sync_context = 0;
+ q_s->max_size = 0xffff;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
+ int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_q_sam_sync");
+ depth++;
+
+ if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
+ return False;
+ if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
+ return False;
+
+ if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
+ return False;
+ if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
+ return False;
+
+ if (!prs_uint32("database_id ", ps, depth, &q_s->database_id))
+ return False;
+ if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
+ return False;
+ if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
+ return False;
+
+ if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
+ depth++;
+
+ if (!prs_uint16("type", ps, depth, &delta->type))
+ return False;
+ if (!prs_uint16("type2", ps, depth, &delta->type2))
+ return False;
+ if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
+ return False;
+
+ if (!prs_uint32("type3", ps, depth, &delta->type3))
+ return False;
+
+ /* Not sure why we need this but it seems to be necessary to get
+ sam deltas working. */
+
+ if (delta->type != 0x16) {
+ if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_delta_stamp(char *desc, SAM_DELTA_STAMP *info,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
+ depth++;
+
+ if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
+ return False;
+ if (!prs_uint32("dom_mod_count_ptr", ps, depth,
+ &info->dom_mod_count_ptr))
+ return False;
+
+ if (info->dom_mod_count_ptr) {
+ if (!prs_uint64("dom_mod_count", ps, depth,
+ &info->dom_mod_count))
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_domain_info");
+ depth++;
+
+ if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
+ return False;
+
+ if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
+ return False;
+ if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
+ return False;
+ if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
+ return False;
+ if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
+ return False;
+ if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
+ return False;
+ if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
+ return False;
+ if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
+ return False;
+
+ if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
+ return False;
+
+ if (ps->data_offset + 40 > ps->buffer_size)
+ return False;
+ ps->data_offset += 40;
+
+ if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
+ info->hdr_dom_name.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
+ info->hdr_oem_info.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
+ info->hdr_sec_desc.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
+ info->hdr_unknown.buffer, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_group_info");
+ depth++;
+
+ if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
+ return False;
+ if (!smb_io_gid("gid", &info->gid, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
+ return False;
+ if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+
+ if (ps->data_offset + 48 > ps->buffer_size)
+ return False;
+ ps->data_offset += 48;
+
+ if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
+ info->hdr_grp_name.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
+ info->hdr_grp_desc.buffer, 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_passwd_info(char *desc, SAM_PWD * pwd,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
+ depth++;
+
+ if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
+ return False;
+
+ if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
+ return False;
+ if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
+ return False;
+
+ if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
+ return False;
+ if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
+ return False;
+
+ if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
+ return False;
+ if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAM_ACCOUNT_INFO structure.
+********************************************************************/
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
+{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
+ DEBUG(5, ("make_sam_account_info\n"));
+
+ make_uni_hdr(&info->hdr_acct_name, len_user_name);
+ make_uni_hdr(&info->hdr_full_name, len_full_name);
+ make_uni_hdr(&info->hdr_home_dir, len_home_dir);
+ make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
+ make_uni_hdr(&info->hdr_logon_script, len_logon_script);
+ make_uni_hdr(&info->hdr_profile, len_profile_path);
+ make_uni_hdr(&info->hdr_acct_desc, len_description);
+ make_uni_hdr(&info->hdr_workstations, len_workstations);
+ make_uni_hdr(&info->hdr_comment, len_unknown_str);
+ make_uni_hdr(&info->hdr_parameters, len_munged_dial);
+
+ /* not present */
+ make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
+
+ info->user_rid = user_rid;
+ info->group_rid = group_rid;
+
+ init_nt_time(&info->logon_time);
+ init_nt_time(&info->logoff_time);
+ init_nt_time(&info->pwd_last_set_time);
+ init_nt_time(&info->acct_expiry_time);
+
+ info->logon_divs = 0xA8;
+ info->ptr_logon_hrs = 0; /* Don't care right now */
+
+ info->bad_pwd_count = 0;
+ info->logon_count = 0;
+ info->acb_info = acb_info;
+ info->nt_pwd_present = 0;
+ info->lm_pwd_present = 0;
+ info->pwd_expired = 0;
+ info->country = 0;
+ info->codepage = 0;
+
+ info->unknown1 = 0x4EC;
+ info->unknown2 = 0;
+
+ copy_unistr2(&info->uni_acct_name, user_name);
+ copy_unistr2(&info->uni_full_name, full_name);
+ copy_unistr2(&info->uni_home_dir, home_dir);
+ copy_unistr2(&info->uni_dir_drive, dir_drive);
+ copy_unistr2(&info->uni_logon_script, log_scr);
+ copy_unistr2(&info->uni_profile, prof_path);
+ copy_unistr2(&info->uni_acct_desc, desc);
+ copy_unistr2(&info->uni_workstations, wkstas);
+ copy_unistr2(&info->uni_comment, unk_str);
+ copy_unistr2(&info->uni_parameters, mung_dial);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
+ SAM_ACCOUNT_INFO * info, prs_struct *ps,
+ int depth)
+{
+ BUFHDR2 hdr_priv_data;
+ uint32 i;
+
+ prs_debug(ps, depth, desc, "net_io_sam_account_info");
+ depth++;
+
+ if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
+ return False;
+
+ if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
+ return False;
+ if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
+ return False;
+
+ if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
+ depth))
+ return False;
+
+ if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
+ depth))
+ return False;
+
+ if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
+ return False;
+ if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
+ return False;
+
+ if (!prs_uint32("logon_divs ", ps, depth, &info->logon_divs))
+ return False;
+ if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
+ return False;
+
+ if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
+ return False;
+ if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
+ return False;
+ if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
+ depth))
+ return False;
+ if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps,
+ depth))
+ return False;
+
+ if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
+ return False;
+ if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
+ return False;
+ if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
+ return False;
+ if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
+ return False;
+ if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
+ return False;
+ if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
+ return False;
+
+ if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps,
+ depth))
+ return False;
+ if (!prs_uint16("country", ps, depth, &info->country))
+ return False;
+ if (!prs_uint16("codepage", ps, depth, &info->codepage))
+ return False;
+
+ if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
+ return False;
+ if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
+ return False;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i],
+ ps, depth))
+ return False;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!prs_uint32("dw_reserved", ps, depth,
+ &info->dw_reserved[i]))
+ return False;
+ }
+
+ if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
+ info->hdr_acct_name.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
+ info->hdr_full_name.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
+ info->hdr_home_dir.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
+ info->hdr_dir_drive.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
+ info->hdr_logon_script.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
+ info->hdr_acct_desc.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
+ info->hdr_workstations.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+
+ if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
+ return False;
+ if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
+ return False;
+
+ if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
+ info->ptr_logon_hrs, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_comment", &info->uni_comment,
+ info->hdr_comment.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
+ info->hdr_parameters.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (hdr_priv_data.buffer != 0)
+ {
+ int old_offset = 0;
+ uint32 len = 0x44;
+ if (!prs_uint32("pwd_len", ps, depth, &len))
+ return False;
+ old_offset = ps->data_offset;
+ if (len == 0x44)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ if (!prs_hash1(ps, ps->data_offset, sess_key))
+ return False;
+ }
+ if (!net_io_sam_passwd_info("pass", &info->pass,
+ ps, depth))
+ return False;
+
+ if (!ps->io)
+ {
+ /* writing */
+ if (!prs_hash1(ps, old_offset, sess_key))
+ return False;
+ }
+ }
+ if (old_offset + len > ps->buffer_size)
+ return False;
+ ps->data_offset = old_offset + len;
+ }
+ if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
+ info->hdr_sec_desc.buffer, ps, depth))
+ return False;
+ prs_align(ps);
+ if (!smb_io_unistr2("uni_profile", &info->uni_profile,
+ info->hdr_profile.buffer, ps, depth))
+ return False;
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
+ prs_struct *ps, int depth)
+{
+ uint32 i;
+ fstring tmp;
+
+ prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
+ depth++;
+
+ prs_align(ps);
+ if (!prs_uint32("ptr_rids ", ps, depth, &info->ptr_rids))
+ return False;
+ if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
+ return False;
+ if (!prs_uint32("num_members", ps, depth, &info->num_members))
+ return False;
+
+ if (ps->data_offset + 16 > ps->buffer_size)
+ return False;
+ ps->data_offset += 16;
+
+ if (info->ptr_rids != 0)
+ {
+ if (!prs_uint32("num_members2", ps, depth,
+ &info->num_members2))
+ return False;
+
+ if (info->num_members2 != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ info->rids = talloc(ps->mem_ctx, sizeof(uint32) *
+ info->num_members2);
+
+ if (info->rids == NULL) {
+ DEBUG(0, ("out of memory allocating %d rids\n",
+ info->num_members2));
+ return False;
+ }
+
+ for (i = 0; i < info->num_members2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
+ if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
+ return False;
+ }
+ }
+
+ if (info->ptr_attribs != 0)
+ {
+ if (!prs_uint32("num_members3", ps, depth,
+ &info->num_members3))
+ return False;
+ if (info->num_members3 != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
+ info->num_members3);
+
+ if (info->attribs == NULL) {
+ DEBUG(0, ("out of memory allocating %d attribs\n",
+ info->num_members3));
+ return False;
+ }
+
+ for (i = 0; i < info->num_members3; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
+ if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
+ return False;
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_alias_info");
+ depth++;
+
+ if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
+ return False;
+ if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
+ return False;
+ if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
+ return False;
+
+ if (ps->data_offset + 40 > ps->buffer_size)
+ return False;
+ ps->data_offset += 40;
+
+ if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
+ info->hdr_als_name.buffer, ps, depth))
+ return False;
+ if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
+ info->hdr_sec_desc.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
+ info->hdr_als_name.buffer, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
+ prs_struct *ps, int depth)
+{
+ uint32 i;
+ fstring tmp;
+
+ prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
+ depth++;
+
+ prs_align(ps);
+ if (!prs_uint32("num_members", ps, depth, &info->num_members))
+ return False;
+ if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
+ return False;
+
+ if (info->ptr_members != 0)
+ {
+ if (ps->data_offset + 16 > ps->buffer_size)
+ return False;
+ ps->data_offset += 16;
+
+ if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
+ return False;
+ if (info->num_sids != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
+ info->num_sids);
+
+ if (info->ptr_sids == NULL) {
+ DEBUG(0, ("out of memory allocating %d ptr_sids\n",
+ info->num_sids));
+ return False;
+ }
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
+ if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
+ return False;
+ }
+
+ info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
+ info->num_sids);
+
+ if (info->sids == NULL) {
+ DEBUG(0, ("error allocating %d sids\n",
+ info->num_sids));
+ return False;
+ }
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ if (info->ptr_sids[i] != 0)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
+ i);
+ if (!smb_io_dom_sid2(tmp, &info->sids[i],
+ ps, depth))
+ return False;
+ }
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
+ SAM_DELTA_CTR * delta, uint16 type,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
+ depth++;
+
+ switch (type)
+ {
+ /* Seen in sam deltas */
+
+ case SAM_DELTA_SAM_STAMP:
+ {
+ if (!net_io_sam_delta_stamp("", &delta->stamp,
+ ps, depth))
+ return False;
+ break;
+ }
+
+ case SAM_DELTA_DOMAIN_INFO:
+ {
+ if (!net_io_sam_domain_info("", &delta->domain_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ case SAM_DELTA_GROUP_INFO:
+ {
+ if (!net_io_sam_group_info("", &delta->group_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ case SAM_DELTA_ACCOUNT_INFO:
+ {
+ if (!net_io_sam_account_info("", sess_key,
+ &delta->account_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ case SAM_DELTA_GROUP_MEM:
+ {
+ if (!net_io_sam_group_mem_info("",
+ &delta->grp_mem_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ case SAM_DELTA_ALIAS_INFO:
+ {
+ if (!net_io_sam_alias_info("", &delta->alias_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ case SAM_DELTA_ALIAS_MEM:
+ {
+ if (!net_io_sam_alias_mem_info("",
+ &delta->als_mem_info,
+ ps, depth))
+ return False;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,
+ ("Replication error: Unknown delta type 0x%x\n",
+ type));
+ break;
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_sync");
+ depth++;
+
+ if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
+ return False;
+ if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
+ return False;
+
+ if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
+ return False;
+ if (r_s->ptr_deltas != 0)
+ {
+ if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
+ return False;
+ if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
+ return False;
+ if (r_s->ptr_deltas2 != 0)
+ {
+ if (!prs_uint32("num_deltas2", ps, depth,
+ &r_s->num_deltas2))
+ return False;
+
+ if (r_s->num_deltas2 != r_s->num_deltas)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ if (r_s->num_deltas2 > 0) {
+ r_s->hdr_deltas = (SAM_DELTA_HDR *)
+ talloc(ps->mem_ctx, r_s->num_deltas2 *
+ sizeof(SAM_DELTA_HDR));
+
+ if (r_s->hdr_deltas == NULL) {
+ DEBUG(0, ("error tallocating memory "
+ "for %d delta headers\n",
+ r_s->num_deltas2));
+ return False;
+ }
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ if (!net_io_sam_delta_hdr("",
+ &r_s->hdr_deltas[i],
+ ps, depth))
+ return False;
+ }
+
+ if (r_s->num_deltas2 > 0) {
+ r_s->deltas = (SAM_DELTA_CTR *)
+ talloc(ps->mem_ctx, r_s->num_deltas2 *
+ sizeof(SAM_DELTA_CTR));
+
+ if (r_s->deltas == NULL) {
+ DEBUG(0, ("error tallocating memory "
+ "for %d deltas\n",
+ r_s->num_deltas2));
+ return False;
+ }
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ if (!net_io_sam_delta_ctr(
+ "", sess_key, &r_s->deltas[i],
+ r_s->hdr_deltas[i].type3,
+ ps, depth)) {
+ DEBUG(0, ("hmm, failed on i=%d\n", i));
+ return False;
+ }
+ }
+ }
+ }
+
+ prs_align(ps);
+ if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+makes a NET_Q_SAM_DELTAS structure.
+********************************************************************/
+BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name,
+ const char *cli_name, DOM_CRED *cli_creds,
+ uint32 database_id, UINT64_S dom_mod_count)
+{
+ DEBUG(5, ("init_net_q_sam_deltas\n"));
+
+ init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
+ init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
+
+ memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
+ memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
+
+ q_s->database_id = database_id;
+ q_s->dom_mod_count.low = dom_mod_count.low;
+ q_s->dom_mod_count.high = dom_mod_count.high;
+ q_s->max_size = 0xffff;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_q_sam_deltas(char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
+ int depth)
+{
+ prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
+ depth++;
+
+ if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
+ return False;
+ if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
+ return False;
+
+ if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
+ return False;
+ if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
+ return False;
+
+ if (!prs_uint32("database_id ", ps, depth, &q_s->database_id))
+ return False;
+ if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
+ return False;
+ if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_sam_deltas(char *desc, uint8 sess_key[16],
+ NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
+{
+ int i;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
+ depth++;
+
+ if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
+ return False;
+ if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
+ return False;
+
+ if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
+ return False;
+ if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
+ return False;
+ if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
+ return False;
+
+ if (r_s->num_deltas2 != 0)
+ {
+ if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
+ return False;
+
+ if (r_s->ptr_deltas != 0)
+ {
+ if (r_s->num_deltas > 0) {
+ r_s->hdr_deltas = (SAM_DELTA_HDR *)
+ talloc(ps->mem_ctx, r_s->num_deltas *
+ sizeof(SAM_DELTA_HDR));
+ if (r_s->hdr_deltas == NULL) {
+ DEBUG(0, ("error tallocating memory "
+ "for %d delta headers\n",
+ r_s->num_deltas));
+ return False;
+ }
+ }
+
+ for (i = 0; i < r_s->num_deltas; i++)
+ {
+ net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
+ ps, depth);
+ }
+
+ if (r_s->num_deltas > 0) {
+ r_s->deltas = (SAM_DELTA_CTR *)
+ talloc(ps->mem_ctx, r_s->num_deltas *
+ sizeof(SAM_DELTA_CTR));
+
+ if (r_s->deltas == NULL) {
+ DEBUG(0, ("error tallocating memory "
+ "for %d deltas\n",
+ r_s->num_deltas));
+ return False;
+ }
+ }
+
+ for (i = 0; i < r_s->num_deltas; i++)
+ {
+ if (!net_io_sam_delta_ctr(
+ "", sess_key,
+ &r_s->deltas[i],
+ r_s->hdr_deltas[i].type2,
+ ps, depth))
+
+ return False;
+ }
+ }
+ }
+
+ prs_align(ps);
+ if (!prs_ntstatus("status", ps, depth, &r_s->status))
+ return False;
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 6bab18ba9d7..b11dc7394da 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -21,11 +21,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-extern int DEBUGLEVEL;
-
#include "includes.h"
-
/*******************************************************************
dump a prs to a file
********************************************************************/
@@ -64,9 +61,14 @@ void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
}
-/*******************************************************************
- Initialise a parse structure - malloc the data if requested.
- ********************************************************************/
+/**
+ * Initialise an expandable parse structure.
+ *
+ * @param size Initial buffer size. If >0, a new buffer will be
+ * created with malloc().
+ *
+ * @return False if allocation fails, otherwise True.
+ **/
BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
{
ZERO_STRUCTP(ps);
@@ -85,6 +87,7 @@ BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
DEBUG(0,("prs_init: malloc fail for %u bytes.\n", (unsigned int)size));
return False;
}
+ memset(ps->data_p, '\0', (size_t)size);
ps->is_dynamic = True; /* We own this memory. */
}
@@ -116,15 +119,23 @@ BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout)
void prs_mem_free(prs_struct *ps)
{
- if(ps->is_dynamic && (ps->data_p != NULL))
- free(ps->data_p);
+ if(ps->is_dynamic)
+ SAFE_FREE(ps->data_p);
ps->is_dynamic = False;
- ps->data_p = NULL;
ps->buffer_size = 0;
ps->data_offset = 0;
}
/*******************************************************************
+ Clear the memory in a parse structure.
+ ********************************************************************/
+
+void prs_mem_clear(prs_struct *ps)
+{
+ memset(ps->data_p, '\0', (size_t)ps->buffer_size);
+}
+
+/*******************************************************************
Allocate memory when unmarshalling... Always zero clears.
********************************************************************/
@@ -240,7 +251,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space)
DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
return False;
}
- memset(new_data, '\0', new_size );
+ memset(new_data, '\0', (size_t)new_size );
} else {
/*
* If the current buffer size is bigger than the space needed, just
@@ -254,7 +265,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space)
return False;
}
- memset(&new_data[ps->buffer_size], '\0', new_size - ps->buffer_size);
+ memset(&new_data[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
}
ps->buffer_size = new_size;
ps->data_p = new_data;
@@ -285,7 +296,7 @@ BOOL prs_force_grow(prs_struct *ps, uint32 extra_space)
return False;
}
- memset(&new_data[ps->buffer_size], '\0', new_size - ps->buffer_size);
+ memset(&new_data[ps->buffer_size], '\0', (size_t)(new_size - ps->buffer_size));
ps->buffer_size = new_size;
ps->data_p = new_data;
@@ -551,6 +562,67 @@ BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
return True;
}
+/*******************************************************************
+ Stream a NTSTATUS
+ ********************************************************************/
+
+BOOL prs_ntstatus(char *name, prs_struct *ps, int depth, NTSTATUS *status)
+{
+ char *q = prs_mem_get(ps, sizeof(uint32));
+ if (q == NULL)
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ if (ps->bigendian_data)
+ *status = NT_STATUS(RIVAL(q,0));
+ else
+ *status = NT_STATUS(IVAL(q,0));
+ } else {
+ if (ps->bigendian_data)
+ RSIVAL(q,0,NT_STATUS_V(*status));
+ else
+ SIVAL(q,0,NT_STATUS_V(*status));
+ }
+
+ DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
+ get_nt_error_msg(*status)));
+
+ ps->data_offset += sizeof(uint32);
+
+ return True;
+}
+
+/*******************************************************************
+ Stream a WERROR
+ ********************************************************************/
+
+BOOL prs_werror(char *name, prs_struct *ps, int depth, WERROR *status)
+{
+ char *q = prs_mem_get(ps, sizeof(uint32));
+ if (q == NULL)
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ if (ps->bigendian_data)
+ *status = W_ERROR(RIVAL(q,0));
+ else
+ *status = W_ERROR(IVAL(q,0));
+ } else {
+ if (ps->bigendian_data)
+ RSIVAL(q,0,W_ERROR_V(*status));
+ else
+ SIVAL(q,0,W_ERROR_V(*status));
+ }
+
+ DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name,
+ werror_str(*status)));
+
+ ps->data_offset += sizeof(uint32);
+
+ return True;
+}
+
+
/******************************************************************
Stream an array of uint8s. Length is number of uint8s.
********************************************************************/
@@ -789,12 +861,12 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
{
int i;
- char *q = prs_mem_get(ps, str->str_str_len);
+ char *q = prs_mem_get(ps, str->str_max_len);
if (q == NULL)
return False;
if (UNMARSHALLING(ps)) {
- str->buffer = (unsigned char *)prs_alloc_mem(ps,str->str_str_len);
+ str->buffer = (unsigned char *)prs_alloc_mem(ps,str->str_max_len);
if (str->buffer == NULL)
return False;
}
@@ -1149,3 +1221,27 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
return 0;
}
+
+/*******************************************************************
+ hash a stream.
+ ********************************************************************/
+BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
+{
+ char *q;
+
+ q = prs_data_p(ps);
+ q = &q[offset];
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("prs_hash1\n"));
+ dump_data(100, sess_key, 16);
+ dump_data(100, q, 68);
+#endif
+ SamOEMhash((uchar *) q, sess_key, 68);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, q, 68);
+#endif
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index a7602434e54..181a3855926 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -5,7 +5,8 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
- * Copyright (C) Marc Jacobsen 1999.
+ * Copyright (C) Marc Jacobsen 1999.
+ * Copyright (C) Simo Sorce 2000.
*
* 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
@@ -22,17 +23,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
/*******************************************************************
Inits a structure.
********************************************************************/
-void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+void init_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
@@ -45,12 +42,12 @@ void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
{
if (r_q == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
+ prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
depth++;
if(!prs_align(ps))
@@ -76,12 +73,12 @@ BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int d
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
{
if (r_r == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
+ prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
depth++;
if(!prs_align(ps))
@@ -90,7 +87,76 @@ BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int d
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits a structure.
+********************************************************************/
+
+void init_reg_q_open_hklm(REG_Q_OPEN_HKLM * q_o,
+ uint16 unknown_0, uint32 access_mask)
+{
+ q_o->ptr = 1;
+ q_o->unknown_0 = unknown_0;
+ q_o->unknown_1 = 0x0; /* random - changes */
+ q_o->access_mask = access_mask;
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM * r_q, prs_struct *ps,
+ int depth)
+{
+ if (r_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr ", ps, depth, &(r_q->ptr)))
+ return False;
+ if (r_q->ptr != 0)
+ {
+ if (!prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0)))
+ return False;
+ if (!prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)))
+ return False;
+ if (!prs_uint32("access_mask", ps, depth, &(r_q->access_mask)))
+ return False;
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
+ int depth)
+{
+ if (r_r == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+ return False;
+
+ if (!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -142,7 +208,7 @@ BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int d
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -295,7 +361,7 @@ BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -362,7 +428,7 @@ BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, i
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -427,7 +493,7 @@ BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -516,7 +582,7 @@ BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int d
if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -569,7 +635,7 @@ BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
return False;
- if(!prs_uint32("status" , ps, depth, &r_r->status))
+ if(!prs_ntstatus("status" , ps, depth, &r_r->status))
return False;
return True;
@@ -635,7 +701,7 @@ BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int dep
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -695,7 +761,7 @@ BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -760,7 +826,7 @@ BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, in
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -821,7 +887,7 @@ makes a structure.
********************************************************************/
void init_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol,
uint32 buf_len, uint8 *buf,
- uint32 status)
+ NTSTATUS status)
{
r_i->ptr = 1;
init_buf_hdr(&r_i->hdr_sec, buf_len, buf_len);
@@ -858,7 +924,7 @@ BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, i
return False;
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -958,7 +1024,7 @@ BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
********************************************************************/
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- BUFFER2* buf, uint32 type, uint32 status)
+ BUFFER2* buf, uint32 type, NTSTATUS status)
{
if(r_r == NULL)
return False;
@@ -1033,7 +1099,7 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
return False;
}
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
return False;
return True;
@@ -1177,7 +1243,7 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
return False;
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1254,7 +1320,7 @@ BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, i
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1387,7 +1453,7 @@ BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int dep
return False;
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
+ if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1449,7 +1515,7 @@ 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, uint32 status)
+ POLICY_HND *pol, NTSTATUS status)
{
memcpy(&r_r->pol, pol, sizeof(r_r->pol));
r_r->status = status;
@@ -1473,7 +1539,141 @@ BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_r->status))
+ if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s,
+ const char *msg, uint32 timeout, uint16 flags)
+{
+ int msg_len;
+ msg_len = strlen(msg);
+
+ q_s->ptr_0 = 1;
+ q_s->ptr_1 = 1;
+ q_s->ptr_2 = 1;
+
+ init_uni_hdr(&(q_s->hdr_msg), msg_len);
+ init_unistr2(&(q_s->uni_msg), msg, msg_len);
+
+ q_s->timeout = timeout;
+ q_s->flags = flags;
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
+ int depth)
+{
+ if (q_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_shutdown");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_0", ps, depth, &(q_s->ptr_0)))
+ return False;
+ if (!prs_uint32("ptr_1", ps, depth, &(q_s->ptr_1)))
+ return False;
+ if (!prs_uint32("ptr_2", ps, depth, &(q_s->ptr_2)))
+ return False;
+
+ if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
+ return False;
+ if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
+ return False;
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
+ return False;
+ if (!prs_uint16("flags ", ps, depth, &(q_s->flags)))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
+ int depth)
+{
+ if (r_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_r_shutdown");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_s->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN * q_s)
+{
+
+ q_s->ptr_server = 0;
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_q_abort_shutdown(char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
+ prs_struct *ps, int depth)
+{
+ if (q_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_abort_shutdown");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+ return False;
+ if (q_s->ptr_server != 0)
+ if (!prs_uint16("server", ps, depth, &(q_s->server)))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_r_abort_shutdown(char *desc, REG_R_ABORT_SHUTDOWN * r_s,
+ prs_struct *ps, int depth)
+{
+ if (r_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_r_abort_shutdown");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_ntstatus("status", ps, depth, &r_s->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index f330c5947e6..2dec12dbd0a 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -26,9 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
/*******************************************************************
interface/version dce/rpc pipe identification
********************************************************************/
@@ -520,7 +517,7 @@ BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int de
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
depth++;
- if(!prs_uint32("status ", ps, depth, &rpc->status))
+ if(!prs_ntstatus("status ", ps, depth, &rpc->status))
return False;
if(!prs_uint32("reserved", ps, depth, &rpc->reserved))
return False;
@@ -885,6 +882,7 @@ void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
fstrcpy(rsp->user, user);
fstrcpy(rsp->wks, wks);
}
+
rsp->sess_key[0] = 0;
}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index e0e61efffaa..f207d32e55c 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -7,6 +7,7 @@
* Copyright (C) Paul Ashton 1997-2000,
* Copyright (C) Elrond 2000,
* Copyright (C) Jeremy Allison 2001
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +28,6 @@
#include "rpc_parse.h"
#include "nterr.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
inits a SAMR_Q_CLOSE_HND structure.
********************************************************************/
@@ -78,7 +77,7 @@ BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND * r_u,
if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -133,13 +132,13 @@ inits a SAMR_R_LOOKUP_DOMAIN structure.
********************************************************************/
void init_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN * r_u,
- DOM_SID *dom_sid, uint32 status)
+ DOM_SID *dom_sid, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_lookup_domain\n"));
r_u->status = status;
r_u->ptr_sid = 0;
- if (status == 0x0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->ptr_sid = 1;
init_dom_sid2(&r_u->dom_sid, dom_sid);
}
@@ -171,7 +170,7 @@ BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
return False;
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -233,7 +232,7 @@ BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -245,7 +244,7 @@ reads or writes a structure.
void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN * q_u,
POLICY_HND *pol, uint32 flags,
- DOM_SID *sid)
+ const DOM_SID *sid)
{
DEBUG(5, ("samr_init_samr_q_open_domain\n"));
@@ -301,7 +300,7 @@ BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN * r_u,
if(!smb_io_pol_hnd("domain_pol", &r_u->domain_pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -342,13 +341,21 @@ BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO * q_u,
Init.
********************************************************************/
-void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, uint32 status)
+void init_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *r_u, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_get_usrdom_pwinfo\n"));
r_u->unknown_0 = 0x0000;
- r_u->unknown_1 = 0x0015;
- r_u->unknown_2 = 0x00000000;
+
+ /*
+ * used to be
+ * r_u->unknown_1 = 0x0015;
+ * but for trusts.
+ */
+ r_u->unknown_1 = 0x01D1;
+ r_u->unknown_1 = 0x0015;
+
+ r_u->unknown_2 = 0x00000000;
r_u->status = status;
}
@@ -375,7 +382,7 @@ BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO * r_u,
return False;
if(!prs_uint32("unknown_2", ps, depth, &r_u->unknown_2))
return False;
- if(!prs_uint32("status ", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_u->status))
return False;
return True;
@@ -463,10 +470,10 @@ BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO * q_u,
inits a structure.
********************************************************************/
-void init_unk_info3(SAM_UNK_INFO_3 * u_3)
+void init_unk_info3(SAM_UNK_INFO_3 *u_3, NTTIME nt_logout)
{
- u_3->unknown_0 = 0x00000000;
- u_3->unknown_1 = 0x80000000;
+ u_3->logout.low = nt_logout.low;
+ u_3->logout.high = nt_logout.high;
}
/*******************************************************************
@@ -482,9 +489,7 @@ static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 * u_3,
prs_debug(ps, depth, desc, "sam_io_unk_info3");
depth++;
- if(!prs_uint32("unknown_0", ps, depth, &u_3->unknown_0)) /* 0x0000 0000 */
- return False;
- if(!prs_uint32("unknown_1", ps, depth, &u_3->unknown_1)) /* 0x8000 0000 */
+ if(!smb_io_time("logout", &u_3->logout, ps, depth))
return False;
return True;
@@ -556,14 +561,14 @@ static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 * u_7,
inits a structure.
********************************************************************/
-void init_unk_info12(SAM_UNK_INFO_12 * u_12)
+void init_unk_info12(SAM_UNK_INFO_12 * u_12, NTTIME nt_lock_duration, NTTIME nt_reset_time, uint16 lockout)
{
- u_12->unknown_0 = 0xcf1dcc00;
- u_12->unknown_1 = 0xfffffffb;
- u_12->unknown_2 = 0xcf1dcc00;
- u_12->unknown_3 = 0xfffffffb;
+ u_12->duration.low = nt_lock_duration.low;
+ u_12->duration.high = nt_lock_duration.high;
+ u_12->reset_count.low = nt_reset_time.low;
+ u_12->reset_count.high = nt_reset_time.high;
- u_12->unknown_4 = 0x8a880000;
+ u_12->bad_attempt_lockout = lockout;
}
/*******************************************************************
@@ -579,15 +584,45 @@ static BOOL sam_io_unk_info12(char *desc, SAM_UNK_INFO_12 * u_12,
prs_debug(ps, depth, desc, "sam_io_unk_info12");
depth++;
- if(!prs_uint32("unknown_0", ps, depth, &u_12->unknown_0))
+ if(!smb_io_time("duration", &u_12->duration, ps, depth))
+ return False;
+ if(!smb_io_time("reset_count", &u_12->reset_count, ps, depth))
return False;
- if(!prs_uint32("unknown_1", ps, depth, &u_12->unknown_1))
+ if(!prs_uint16("bad_attempt_lockout", ps, depth, &u_12->bad_attempt_lockout))
return False;
- if(!prs_uint32("unknown_2", ps, depth, &u_12->unknown_2))
+
+ return True;
+}
+
+/*******************************************************************
+inits a structure.
+********************************************************************/
+void init_unk_info5(SAM_UNK_INFO_5 * u_5,char *server)
+{
+ int len_server = strlen(server);
+
+ init_uni_hdr(&u_5->hdr_server, len_server);
+
+ init_unistr2(&u_5->uni_server, server, len_server);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_unk_info5(char *desc, SAM_UNK_INFO_5 * u_5,
+ prs_struct *ps, int depth)
+{
+ if (u_5 == NULL)
return False;
- if(!prs_uint32("unknown_3", ps, depth, &u_12->unknown_3))
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info5");
+ depth++;
+
+ if(!smb_io_unihdr("hdr_server", &u_5->hdr_server, ps, depth))
return False;
- if(!prs_uint32("unknown_4", ps, depth, &u_12->unknown_4))
+
+ if(!smb_io_unistr2("uni_server", &u_5->uni_server, u_5->hdr_server.buffer, ps, depth))
return False;
return True;
@@ -598,7 +633,7 @@ inits a structure.
********************************************************************/
void init_unk_info2(SAM_UNK_INFO_2 * u_2,
char *domain, char *server,
- uint32 seq_num)
+ uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias)
{
int len_domain = strlen(domain);
int len_server = strlen(server);
@@ -617,9 +652,9 @@ void init_unk_info2(SAM_UNK_INFO_2 * u_2,
u_2->unknown_4 = 0x00000001;
u_2->unknown_5 = 0x00000003;
u_2->unknown_6 = 0x00000001;
- u_2->num_domain_usrs = MAX_SAM_ENTRIES;
- u_2->num_domain_grps = MAX_SAM_ENTRIES;
- u_2->num_local_grps = MAX_SAM_ENTRIES;
+ u_2->num_domain_usrs = num_users;
+ u_2->num_domain_grps = num_groups;
+ u_2->num_local_grps = num_alias;
memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
@@ -691,11 +726,21 @@ static BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 * u_2,
inits a structure.
********************************************************************/
-void init_unk_info1(SAM_UNK_INFO_1 * u_1)
+void init_unk_info1(SAM_UNK_INFO_1 *u_1, uint16 min_pass_len, uint16 pass_hist,
+ uint32 flag, NTTIME nt_expire, NTTIME nt_min_age)
{
- memset(u_1->padding, 0, sizeof(u_1->padding)); /* 12 bytes zeros */
- u_1->unknown_1 = 0x80000000;
- u_1->unknown_2 = 0x00000000;
+ u_1->min_length_password = min_pass_len;
+ u_1->password_history = pass_hist;
+ u_1->flag = flag;
+
+ /* password never expire */
+ u_1->expire.high = nt_expire.high;
+ u_1->expire.low = nt_expire.low;
+
+ /* can change the password now */
+ u_1->min_passwordage.high = nt_min_age.high;
+ u_1->min_passwordage.low = nt_min_age.low;
+
}
/*******************************************************************
@@ -711,12 +756,15 @@ static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 * u_1,
prs_debug(ps, depth, desc, "sam_io_unk_info1");
depth++;
- if(!prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)))
+ if(!prs_uint16("min_length_password", ps, depth, &u_1->min_length_password))
return False;
-
- if(!prs_uint32("unknown_1", ps, depth, &u_1->unknown_1)) /* 0x8000 0000 */
+ if(!prs_uint16("password_history", ps, depth, &u_1->password_history))
+ return False;
+ if(!prs_uint32("flag", ps, depth, &u_1->flag))
+ return False;
+ if(!smb_io_time("expire", &u_1->expire, ps, depth))
return False;
- if(!prs_uint32("unknown_2", ps, depth, &u_1->unknown_2)) /* 0x0000 0000 */
+ if(!smb_io_time("min_passwordage", &u_1->min_passwordage, ps, depth))
return False;
return True;
@@ -728,7 +776,7 @@ inits a SAMR_R_QUERY_DOMAIN_INFO structure.
void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
uint16 switch_value, SAM_UNK_CTR * ctr,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_dom_info\n"));
@@ -736,7 +784,7 @@ void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO * r_u,
r_u->switch_value = 0;
r_u->status = status; /* return status */
- if (status == 0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->switch_value = switch_value;
r_u->ptr_0 = 1;
r_u->ctr = ctr;
@@ -781,6 +829,10 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth))
return False;
break;
+ case 0x05:
+ if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth))
+ return False;
+ break;
case 0x03:
if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth))
return False;
@@ -804,7 +856,7 @@ BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -833,7 +885,7 @@ BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ * r_u,
return False;
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -883,7 +935,6 @@ static void init_sam_entry1(SAM_ENTRY1 * sam, uint32 user_idx,
sam->user_idx = user_idx;
sam->rid_user = rid_user;
sam->acb_info = acb_info;
- sam->pad = 0;
init_uni_hdr(&sam->hdr_acct_name, len_sam_name);
init_uni_hdr(&sam->hdr_user_name, len_sam_full);
@@ -913,7 +964,8 @@ static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 * sam,
return False;
if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
return False;
- if(!prs_uint16("pad ", ps, depth, &sam->pad))
+
+ if(!prs_align(ps))
return False;
if (!smb_io_unihdr("hdr_acct_name", &sam->hdr_acct_name, ps, depth))
@@ -962,7 +1014,6 @@ static void init_sam_entry2(SAM_ENTRY2 * sam, uint32 user_idx,
sam->user_idx = user_idx;
sam->rid_user = rid_user;
sam->acb_info = acb_info;
- sam->pad = 0;
init_uni_hdr(&sam->hdr_srv_name, len_sam_name);
init_uni_hdr(&sam->hdr_srv_desc, len_sam_desc);
@@ -991,7 +1042,8 @@ static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 * sam,
return False;
if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
return False;
- if(!prs_uint16("pad ", ps, depth, &sam->pad))
+
+ if(!prs_align(ps))
return False;
if(!smb_io_unihdr("unihdr", &sam->hdr_srv_name, ps, depth)) /* account name unicode string header */
@@ -1086,8 +1138,7 @@ static void init_sam_entry4(SAM_ENTRY4 * sam, uint32 user_idx,
DEBUG(5, ("init_sam_entry4\n"));
sam->user_idx = user_idx;
- init_str_hdr(&sam->hdr_acct_name, len_acct_name, len_acct_name,
- len_acct_name != 0);
+ init_str_hdr(&sam->hdr_acct_name, len_acct_name+1, len_acct_name, len_acct_name != 0);
}
/*******************************************************************
@@ -1323,7 +1374,7 @@ BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS * r_u,
if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1386,62 +1437,53 @@ BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO * q_e,
inits a SAM_DISPINFO_1 structure.
********************************************************************/
-uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
uint32 len_sam_name, len_sam_full, len_sam_desc;
- uint32 max_entries, max_data_size;
- uint32 dsize = 0;
uint32 i;
+ SAM_ACCOUNT *pwd = NULL;
ZERO_STRUCTP(sam);
- max_entries = *num_entries;
- max_data_size = *data_size;
+ DEBUG(10, ("init_sam_dispinfo_1: num_entries: %d\n", num_entries));
- DEBUG(5, ("init_sam_dispinfo_1: max_entries: %d max_dsize: 0x%x\n",
- max_entries, max_data_size));
-
- if (max_entries==0)
+ if (num_entries==0)
return NT_STATUS_OK;
- sam->sam=(SAM_ENTRY1 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY1));
+ sam->sam=(SAM_ENTRY1 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY1));
if (!sam->sam)
return NT_STATUS_NO_MEMORY;
- sam->str=(SAM_STR1 *)talloc(ctx, max_entries*sizeof(SAM_STR1));
+ sam->str=(SAM_STR1 *)talloc(ctx, num_entries*sizeof(SAM_STR1));
if (!sam->str)
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(sam->sam);
ZERO_STRUCTP(sam->str);
- for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
- DEBUG(5, ("init_sam_dispinfo_1: entry: %d\n",i));
- len_sam_name = pass[i].uni_user_name.uni_str_len;
- len_sam_full = pass[i].uni_full_name.uni_str_len;
- len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
+ for (i = 0; i < num_entries ; i++) {
+ DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
+
+ pwd=disp_user_info[i+start_idx].sam;
+
+ len_sam_name = strlen(pdb_get_username(pwd));
+ len_sam_full = strlen(pdb_get_fullname(pwd));
+ len_sam_desc = strlen(pdb_get_acct_desc(pwd));
init_sam_entry1(&sam->sam[i], start_idx + i + 1,
len_sam_name, len_sam_full, len_sam_desc,
- pass[i].user_rid, pass[i].acb_info);
+ pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
ZERO_STRUCTP(&sam->str[i].uni_acct_name);
ZERO_STRUCTP(&sam->str[i].uni_full_name);
ZERO_STRUCTP(&sam->str[i].uni_acct_desc);
- copy_unistr2(&sam->str[i].uni_acct_name, &pass[i].uni_user_name);
- copy_unistr2(&sam->str[i].uni_full_name, &pass[i].uni_full_name);
- copy_unistr2(&sam->str[i].uni_acct_desc, &pass[i].uni_acct_desc);
-
- dsize += sizeof(SAM_ENTRY1);
- dsize += len_sam_name + len_sam_full + len_sam_desc;
+ init_unistr2(&sam->str[i].uni_acct_name, pdb_get_username(pwd), len_sam_name);
+ init_unistr2(&sam->str[i].uni_full_name, pdb_get_fullname(pwd), len_sam_full);
+ init_unistr2(&sam->str[i].uni_acct_desc, pdb_get_acct_desc(pwd), len_sam_desc);
}
- *num_entries = i;
- *data_size = dsize;
-
return NT_STATUS_OK;
}
@@ -1498,55 +1540,47 @@ static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 * sam,
inits a SAM_DISPINFO_2 structure.
********************************************************************/
-uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+NTSTATUS init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
uint32 len_sam_name, len_sam_desc;
- uint32 max_entries, max_data_size;
- uint32 dsize = 0;
uint32 i;
- DEBUG(5, ("init_sam_dispinfo_2\n"));
-
+ SAM_ACCOUNT *pwd = NULL;
ZERO_STRUCTP(sam);
- max_entries = *num_entries;
- max_data_size = *data_size;
+ DEBUG(10, ("init_sam_dispinfo_2: num_entries: %d\n", num_entries));
- if (max_entries==0)
+ if (num_entries==0)
return NT_STATUS_OK;
- if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY2))))
+ if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY2))))
return NT_STATUS_NO_MEMORY;
- if (!(sam->str=(SAM_STR2 *)talloc(ctx, max_entries*sizeof(SAM_STR2))))
+ if (!(sam->str=(SAM_STR2 *)talloc(ctx, num_entries*sizeof(SAM_STR2))))
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(sam->sam);
ZERO_STRUCTP(sam->str);
- for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
- len_sam_name = pass[i].uni_user_name.uni_str_len;
- len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
+ for (i = 0; i < num_entries; i++) {
+ DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
+ pwd=disp_user_info[i+start_idx].sam;
+
+ len_sam_name = strlen(pdb_get_username(pwd));
+ len_sam_desc = strlen(pdb_get_acct_desc(pwd));
init_sam_entry2(&sam->sam[i], start_idx + i + 1,
len_sam_name, len_sam_desc,
- pass[i].user_rid, pass[i].acb_info);
+ pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd));
ZERO_STRUCTP(&sam->str[i].uni_srv_name);
ZERO_STRUCTP(&sam->str[i].uni_srv_desc);
- copy_unistr2(&sam->str[i].uni_srv_name, &pass[i].uni_user_name);
- copy_unistr2(&sam->str[i].uni_srv_desc, &pass[i].uni_acct_desc);
-
- dsize += sizeof(SAM_ENTRY2);
- dsize += len_sam_name + len_sam_desc;
+ init_unistr2(&sam->str[i].uni_srv_name, pdb_get_username(pwd), len_sam_name);
+ init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), len_sam_desc);
}
- *num_entries = i;
- *data_size = dsize;
-
return NT_STATUS_OK;
}
@@ -1605,35 +1639,33 @@ static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 * sam,
inits a SAM_DISPINFO_3 structure.
********************************************************************/
-uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- DOMAIN_GRP * grp)
+NTSTATUS init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info)
{
uint32 len_sam_name, len_sam_desc;
- uint32 max_entries, max_data_size;
- uint32 dsize = 0;
uint32 i;
- DEBUG(5, ("init_sam_dispinfo_3\n"));
-
+ DOMAIN_GRP *grp;
ZERO_STRUCTP(sam);
- max_entries = *num_entries;
- max_data_size = *data_size;
+ DEBUG(5, ("init_sam_dispinfo_3: num_entries: %d\n", num_entries));
- if (max_entries==0)
+ if (num_entries==0)
return NT_STATUS_OK;
- if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY3))))
+ if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY3))))
return NT_STATUS_NO_MEMORY;
- if (!(sam->str=(SAM_STR3 *)talloc(ctx, max_entries*sizeof(SAM_STR3))))
+ if (!(sam->str=(SAM_STR3 *)talloc(ctx, num_entries*sizeof(SAM_STR3))))
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(sam->sam);
ZERO_STRUCTP(sam->str);
- for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
+ for (i = 0; i < num_entries; i++) {
+ DEBUG(11, ("init_sam_dispinfo_3: entry: %d\n",i));
+ grp=disp_group_info[i+start_idx].grp;
+
len_sam_name = strlen(grp[i].name);
len_sam_desc = strlen(grp[i].comment);
@@ -1641,15 +1673,8 @@ uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_ent
init_unistr2(&sam->str[i].uni_grp_name, grp[i].name, len_sam_name);
init_unistr2(&sam->str[i].uni_grp_desc, grp[i].comment, len_sam_desc);
-
- dsize += sizeof(SAM_ENTRY3);
- dsize += (len_sam_name + len_sam_desc) * 2;
- dsize += 14;
}
- *num_entries = i;
- *data_size = dsize;
-
return NT_STATUS_OK;
}
@@ -1708,50 +1733,40 @@ static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 * sam,
inits a SAM_DISPINFO_4 structure.
********************************************************************/
-uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+NTSTATUS init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_USER_INFO *disp_user_info)
{
- fstring sam_name;
uint32 len_sam_name;
- uint32 max_entries, max_data_size;
- uint32 dsize = 0;
uint32 i;
- DEBUG(5, ("init_sam_dispinfo_4\n"));
-
+ SAM_ACCOUNT *pwd = NULL;
ZERO_STRUCTP(sam);
- max_entries = *num_entries;
- max_data_size = *data_size;
+ DEBUG(5, ("init_sam_dispinfo_4: num_entries: %d\n", num_entries));
- if (max_entries==0)
+ if (num_entries==0)
return NT_STATUS_OK;
- if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY4))))
+ if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY4))))
return NT_STATUS_NO_MEMORY;
- if (!(sam->str=(SAM_STR4 *)talloc(ctx, max_entries*sizeof(SAM_STR4))))
+ if (!(sam->str=(SAM_STR4 *)talloc(ctx, num_entries*sizeof(SAM_STR4))))
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(sam->sam);
ZERO_STRUCTP(sam->str);
- for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
- len_sam_name = pass[i].uni_user_name.uni_str_len;
+ for (i = 0; i < num_entries; i++) {
+ DEBUG(11, ("init_sam_dispinfo_2: entry: %d\n",i));
+ pwd=disp_user_info[i+start_idx].sam;
+
+ len_sam_name = strlen(pdb_get_username(pwd));
init_sam_entry4(&sam->sam[i], start_idx + i + 1, len_sam_name);
- unistr2_to_ascii(sam_name, &pass[i].uni_user_name, sizeof(sam_name));
- init_string2(&sam->str[i].acct_name, sam_name, len_sam_name);
-
- dsize += sizeof(SAM_ENTRY4);
- dsize += len_sam_name;
+ init_string2(&sam->str[i].acct_name, pdb_get_username(pwd), len_sam_name+1, len_sam_name);
}
- *num_entries = i;
- *data_size = dsize;
-
return NT_STATUS_OK;
}
@@ -1800,8 +1815,6 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
if(!smb_io_string2("acct_name", &sam->str[i].acct_name,
sam->sam[i].hdr_acct_name.buffer, ps, depth))
return False;
- if(!prs_align(ps))
- return False;
}
return True;
@@ -1811,46 +1824,38 @@ static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 * sam,
inits a SAM_DISPINFO_5 structure.
********************************************************************/
-uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_entries,
- uint32 *data_size, uint32 start_idx,
- DOMAIN_GRP * grp)
+NTSTATUS init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 num_entries,
+ uint32 start_idx, DISP_GROUP_INFO *disp_group_info)
{
uint32 len_sam_name;
- uint32 max_entries, max_data_size;
- uint32 dsize = 0;
uint32 i;
- DEBUG(5, ("init_sam_dispinfo_5\n"));
-
+ DOMAIN_GRP *grp;
ZERO_STRUCTP(sam);
- max_entries = *num_entries;
- max_data_size = *data_size;
+ DEBUG(5, ("init_sam_dispinfo_5: num_entries: %d\n", num_entries));
- if (max_entries==0)
+ if (num_entries==0)
return NT_STATUS_OK;
- if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY5))))
+ if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, num_entries*sizeof(SAM_ENTRY5))))
return NT_STATUS_NO_MEMORY;
- if (!(sam->str=(SAM_STR5 *)talloc(ctx, max_entries*sizeof(SAM_STR5))))
+ if (!(sam->str=(SAM_STR5 *)talloc(ctx, num_entries*sizeof(SAM_STR5))))
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(sam->sam);
ZERO_STRUCTP(sam->str);
- for (i = 0; (i < max_entries) && (dsize < max_data_size); i++) {
+ for (i = 0; i < num_entries; i++) {
+ DEBUG(11, ("init_sam_dispinfo_5: entry: %d\n",i));
+ grp=disp_group_info[i+start_idx].grp;
+
len_sam_name = strlen(grp[i].name);
init_sam_entry5(&sam->sam[i], start_idx + i + 1, len_sam_name);
- init_string2(&sam->str[i].grp_name, grp[i].name, len_sam_name);
-
- dsize += sizeof(SAM_ENTRY5);
- dsize += len_sam_name;
+ init_string2(&sam->str[i].grp_name, grp[i].name, len_sam_name+1, len_sam_name);
}
-
- *num_entries = i;
- *data_size = dsize;
return NT_STATUS_OK;
}
@@ -1900,8 +1905,6 @@ static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 * sam,
if(!smb_io_string2("grp_name", &sam->str[i].grp_name,
sam->sam[i].hdr_grp_name.buffer, ps, depth))
return False;
- if(!prs_align(ps))
- return False;
}
return True;
@@ -1912,13 +1915,14 @@ inits a SAMR_R_QUERY_DISPINFO structure.
********************************************************************/
void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO * r_u,
- uint32 num_entries, uint32 data_size,
+ uint32 num_entries, uint32 total_size, uint32 data_size,
uint16 switch_level, SAM_DISPINFO_CTR * ctr,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_dispinfo: level %d\n", switch_level));
- r_u->total_size = data_size; /* not calculated */
+ r_u->total_size = total_size;
+
r_u->data_size = data_size;
r_u->switch_level = switch_level;
@@ -1968,7 +1972,7 @@ BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
if (r_u->ptr_entries==0) {
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2012,7 +2016,7 @@ BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2079,7 +2083,7 @@ BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP * r_u,
if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2148,6 +2152,38 @@ BOOL samr_io_group_info1(char *desc, GROUP_INFO1 * gr1,
}
/*******************************************************************
+inits a GROUP_INFO3 structure.
+********************************************************************/
+
+void init_samr_group_info3(GROUP_INFO3 *gr3)
+{
+ DEBUG(5, ("init_samr_group_info3\n"));
+
+ gr3->unknown_1 = 0x3;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_group_info3(char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int depth)
+{
+ if (gr3 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_group_info3");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("unknown_1", ps, depth, &gr3->unknown_1))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
inits a GROUP_INFO4 structure.
********************************************************************/
@@ -2204,18 +2240,18 @@ static BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR **ctr,
if(!prs_uint16("switch_value1", ps, depth, &(*ctr)->switch_value1))
return False;
- if(!prs_uint16("switch_value2", ps, depth, &(*ctr)->switch_value2))
- return False;
switch ((*ctr)->switch_value1) {
case 1:
- if(!samr_io_group_info1("group_info1",
- &(*ctr)->group.info1, ps, depth))
+ if(!samr_io_group_info1("group_info1", &(*ctr)->group.info1, ps, depth))
+ return False;
+ break;
+ case 3:
+ if(!samr_io_group_info3("group_info3", &(*ctr)->group.info3, ps, depth))
return False;
break;
case 4:
- if(!samr_io_group_info4("group_info4",
- &(*ctr)->group.info4, ps, depth))
+ if(!samr_io_group_info4("group_info4", &(*ctr)->group.info4, ps, depth))
return False;
break;
default:
@@ -2300,7 +2336,7 @@ BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP * r_u,
if(!prs_uint32("rid ", ps, depth, &r_u->rid))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2356,7 +2392,10 @@ BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2405,7 +2444,7 @@ inits a SAMR_R_DEL_GROUPMEM structure.
********************************************************************/
void init_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM * r_u, POLICY_HND *pol,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_del_groupmem\n"));
@@ -2428,7 +2467,7 @@ BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2480,7 +2519,7 @@ inits a SAMR_R_ADD_GROUPMEM structure.
********************************************************************/
void init_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM * r_u, POLICY_HND *pol,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_add_groupmem\n"));
@@ -2503,7 +2542,7 @@ BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2551,7 +2590,7 @@ BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO * q_e,
inits a SAMR_R_SET_GROUPINFO structure.
********************************************************************/
-void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, uint32 status)
+void init_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO * r_u, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_set_groupinfo\n"));
@@ -2574,7 +2613,7 @@ BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2624,11 +2663,11 @@ inits a SAMR_R_QUERY_GROUPINFO structure.
********************************************************************/
void init_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO * r_u,
- GROUP_INFO_CTR * ctr, uint32 status)
+ GROUP_INFO_CTR * ctr, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_groupinfo\n"));
- r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
+ r_u->ptr = (NT_STATUS_IS_OK(status) && ctr != NULL) ? 1 : 0;
r_u->ctr = ctr;
r_u->status = status;
}
@@ -2659,7 +2698,7 @@ BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2704,11 +2743,11 @@ inits a SAMR_R_QUERY_GROUPMEM structure.
void init_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM * r_u,
uint32 num_entries, uint32 *rid,
- uint32 *attr, uint32 status)
+ uint32 *attr, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_groupmem\n"));
- if (status == 0x0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->ptr = 1;
r_u->num_entries = num_entries;
@@ -2792,7 +2831,7 @@ BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM * r_u,
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -2838,11 +2877,11 @@ inits a SAMR_R_QUERY_USERGROUPS structure.
void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS * r_u,
uint32 num_gids, DOM_GID * gid,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_usergroups\n"));
- if (status == 0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->ptr_0 = 1;
r_u->num_entries = num_gids;
r_u->ptr_1 = (num_gids != 0) ? 1 : 0;
@@ -2930,7 +2969,7 @@ BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3069,7 +3108,7 @@ BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS * r_u,
return False;
if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3203,7 +3242,7 @@ BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS * r_u,
return False;
if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3338,7 +3377,64 @@ BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES * r_u,
return False;
if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+inits a ALIAS_INFO1 structure.
+********************************************************************/
+
+void init_samr_alias_info1(ALIAS_INFO1 * al1, char *acct_name, uint32 num_member, char *acct_desc)
+{
+ int acct_len_name = acct_name != NULL ? strlen(acct_name) : 0;
+ int acct_len_desc = acct_desc != NULL ? strlen(acct_desc) : 0;
+
+ DEBUG(5, ("init_samr_alias_info1\n"));
+
+ init_uni_hdr(&al1->hdr_acct_name, acct_len_name);
+ init_unistr2(&al1->uni_acct_name, acct_name, acct_len_name);
+
+ al1->num_member=num_member;
+
+ init_uni_hdr(&al1->hdr_acct_desc, acct_len_desc);
+ init_unistr2(&al1->uni_acct_desc, acct_desc, acct_len_desc);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_alias_info1(char *desc, ALIAS_INFO1 * al1,
+ prs_struct *ps, int depth)
+{
+ if (al1 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_alias_info1");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unihdr("hdr_acct_name", &al1->hdr_acct_name, ps, depth))
+ return False;
+ if(!prs_uint32("num_member", ps, depth, &al1->num_member))
+ return False;
+ if(!smb_io_unihdr("hdr_acct_desc", &al1->hdr_acct_desc, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("uni_acct_name", &al1->uni_acct_name,
+ al1->hdr_acct_name.buffer, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unistr2("uni_acct_desc", &al1->uni_acct_desc,
+ al1->hdr_acct_desc.buffer, ps, depth))
return False;
return True;
@@ -3402,6 +3498,10 @@ BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR * ctr,
return False;
switch (ctr->switch_value1) {
+ case 1:
+ if(!samr_io_alias_info1("alias_info1", &ctr->alias.info1, ps, depth))
+ return False;
+ break;
case 3:
if(!samr_io_alias_info3("alias_info3", &ctr->alias.info3, ps, depth))
return False;
@@ -3457,11 +3557,11 @@ inits a SAMR_R_QUERY_ALIASINFO structure.
********************************************************************/
void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO * r_u,
- ALIAS_INFO_CTR * ctr, uint32 status)
+ ALIAS_INFO_CTR * ctr, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_aliasinfo\n"));
- r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
+ r_u->ptr = (NT_STATUS_IS_OK(status) && ctr != NULL) ? 1 : 0;
r_u->ctr = *ctr;
r_u->status = status;
}
@@ -3492,7 +3592,7 @@ BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3550,7 +3650,7 @@ BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3643,11 +3743,11 @@ inits a SAMR_R_QUERY_USERALIASES structure.
void init_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES * r_u,
uint32 num_rids, uint32 *rid,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_useraliases\n"));
- if (status == 0x0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->num_entries = num_rids;
r_u->ptr = 1;
r_u->num_entries2 = num_rids;
@@ -3729,7 +3829,7 @@ BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3795,7 +3895,7 @@ BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS * r_u,
if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3989,7 +4089,7 @@ BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS * r_u,
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4046,7 +4146,7 @@ BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4126,7 +4226,7 @@ BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS * r_u,
if(!prs_uint32("rid", ps, depth, &r_u->rid))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4185,7 +4285,7 @@ BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4244,7 +4344,7 @@ BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4289,7 +4389,7 @@ inits a SAMR_R_DELETE_DOM_ALIAS structure.
********************************************************************/
void init_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS * r_u,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_delete_dom_alias\n"));
@@ -4312,7 +4412,7 @@ BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4358,11 +4458,11 @@ inits a SAMR_R_QUERY_ALIASMEM structure.
void init_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM * r_u,
uint32 num_sids, DOM_SID2 * sid,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_aliasmem\n"));
- if (status == 0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->num_sids = num_sids;
r_u->ptr = (num_sids != 0) ? 1 : 0;
r_u->num_sids1 = num_sids;
@@ -4424,7 +4524,7 @@ BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4434,7 +4534,7 @@ BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM * r_u,
inits a SAMR_Q_LOOKUP_NAMES structure.
********************************************************************/
-uint32 init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
+NTSTATUS init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
POLICY_HND *pol, uint32 flags,
uint32 num_names, char **name)
{
@@ -4523,14 +4623,14 @@ BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES * q_u,
inits a SAMR_R_LOOKUP_NAMES structure.
********************************************************************/
-uint32 init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
+NTSTATUS init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
uint32 num_rids,
uint32 *rid, uint32 *type,
- uint32 status)
+ NTSTATUS status)
{
DEBUG(5, ("init_samr_r_lookup_names\n"));
- if ((status == 0) && (num_rids != 0)) {
+ if (NT_STATUS_IS_OK(status) && (num_rids != 0)) {
uint32 i;
r_u->num_types1 = num_rids;
@@ -4653,7 +4753,7 @@ BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES * r_u,
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4709,7 +4809,9 @@ BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
+ return False;
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4776,7 +4878,7 @@ BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER * r_u,
if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4789,7 +4891,7 @@ reads or writes a structure.
void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
POLICY_HND *pol,
- char *name,
+ const char *name,
uint32 acb_info, uint32 access_mask)
{
int len_name;
@@ -4863,7 +4965,7 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
return False;
if(!prs_uint32("user_rid ", ps, depth, &r_u->user_rid))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4942,7 +5044,7 @@ inits a SAM_USER_INFO_12 structure.
********************************************************************/
void init_sam_user_info12(SAM_USER_INFO_12 * usr,
- uint8 lm_pwd[16], uint8 nt_pwd[16])
+ const uint8 lm_pwd[16], const uint8 nt_pwd[16])
{
DEBUG(5, ("init_sam_user_info12\n"));
@@ -5172,9 +5274,10 @@ static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr,
if(!prs_align(ps))
return False;
- if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass)))
+ if(!prs_uint8s(False, "password", ps, depth, usr->pass,
+ sizeof(usr->pass)))
return False;
-
+
if (MARSHALLING(ps) && (usr->pw_len != 0)) {
if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
return False;
@@ -5733,15 +5836,15 @@ void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw)
len_description, len_workstations, len_unknown_str,
len_munged_dial;
- char* user_name = pdb_get_username(pw);
- char* full_name = pdb_get_fullname(pw);
- char* home_dir = pdb_get_homedir(pw);
- char* dir_drive = pdb_get_dirdrive(pw);
- char* logon_script = pdb_get_logon_script(pw);
- char* profile_path = pdb_get_profile_path(pw);
- char* description = pdb_get_acct_desc(pw);
- char* workstations = pdb_get_workstations(pw);
- char* munged_dial = pdb_get_munged_dial(pw);
+ const char* user_name = pdb_get_username(pw);
+ const char* full_name = pdb_get_fullname(pw);
+ const char* home_dir = pdb_get_homedir(pw);
+ const char* dir_drive = pdb_get_dirdrive(pw);
+ const char* logon_script = pdb_get_logon_script(pw);
+ const char* profile_path = pdb_get_profile_path(pw);
+ const char* description = pdb_get_acct_desc(pw);
+ const char* workstations = pdb_get_workstations(pw);
+ const char* munged_dial = pdb_get_munged_dial(pw);
len_user_name = user_name != NULL ? strlen(user_name )+1 : 0;
len_full_name = full_name != NULL ? strlen(full_name )+1 : 0;
@@ -5934,11 +6037,47 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
return True;
}
+void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw)
+{
+ int len_munged_dial;
+ const char* munged_dial = pdb_get_munged_dial(pw);
+
+ len_munged_dial = munged_dial != NULL ? strlen(munged_dial )+1 : 0;
+ init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+ init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info20(char *desc, SAM_USER_INFO_20 *usr,
+ prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info20");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* wkstas user can log on from */
+ return False;
+
+ if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial,usr->hdr_munged_dial.buffer, ps, depth)) /* worksations user can log on from */
+ return False;
+
+ return True;
+}
+
/*******************************************************************
inits a SAM_USERINFO_CTR structure.
********************************************************************/
-uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
+NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
uint16 switch_value,
SAM_USER_INFO_21 * usr)
{
@@ -6091,6 +6230,16 @@ static BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR **ppctr,
}
ret = sam_io_user_info12("", ctr->info.id12, ps, depth);
break;
+ case 20:
+ if (UNMARSHALLING(ps))
+ ctr->info.id20 = (SAM_USER_INFO_20 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_20));
+
+ if (ctr->info.id20 == NULL) {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ ret = sam_io_user_info20("", ctr->info.id20, ps, depth);
+ break;
case 21:
if (UNMARSHALLING(ps))
ctr->info.id21 = (SAM_USER_INFO_21 *)prs_alloc_mem(ps,sizeof(SAM_USER_INFO_21));
@@ -6145,14 +6294,14 @@ inits a SAMR_R_QUERY_USERINFO structure.
********************************************************************/
void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO * r_u,
- SAM_USERINFO_CTR * ctr, uint32 status)
+ SAM_USERINFO_CTR * ctr, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_query_userinfo\n"));
r_u->ptr = 0;
r_u->ctr = NULL;
- if (status == 0) {
+ if (NT_STATUS_IS_OK(status)) {
r_u->ptr = 1;
r_u->ctr = ctr;
}
@@ -6186,7 +6335,7 @@ BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6237,7 +6386,7 @@ BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO * q_u,
inits a SAMR_R_SET_USERINFO structure.
********************************************************************/
-void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, uint32 status)
+void init_samr_r_set_userinfo(SAMR_R_SET_USERINFO * r_u, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_set_userinfo\n"));
@@ -6260,7 +6409,7 @@ BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6325,7 +6474,7 @@ BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 * q_u,
inits a SAMR_R_SET_USERINFO2 structure.
********************************************************************/
-void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, uint32 status)
+void init_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 * r_u, NTSTATUS status)
{
DEBUG(5, ("init_samr_r_set_userinfo2\n"));
@@ -6348,7 +6497,7 @@ BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6421,7 +6570,7 @@ BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6488,7 +6637,7 @@ BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON * r_u,
if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6567,7 +6716,7 @@ BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6740,7 +6889,7 @@ BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER * q_u,
inits a SAMR_R_CHGPASSWD_USER structure.
********************************************************************/
-void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, uint32 status)
+void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER * r_u, NTSTATUS status)
{
DEBUG(5, ("init_r_chgpasswd_user\n"));
@@ -6763,8 +6912,259 @@ BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER * r_u,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
return False;
return True;
}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value)
+{
+ DEBUG(5, ("init_samr_q_unknown_2e\n"));
+
+ q_u->domain_pol = *domain_pol;
+ q_u->switch_value = switch_value;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_unknown_2e(char *desc, SAMR_Q_UNKNOWN_2E *q_u,
+ prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_2e");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
+ return False;
+
+ if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+inits a SAMR_R_QUERY_DOMAIN_INFO structure.
+********************************************************************/
+
+void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u,
+ uint16 switch_value, SAM_UNK_CTR * ctr,
+ NTSTATUS status)
+{
+ DEBUG(5, ("init_samr_r_samr_unknown_2e\n"));
+
+ r_u->ptr_0 = 0;
+ r_u->switch_value = 0;
+ r_u->status = status; /* return status */
+
+ if (NT_STATUS_IS_OK(status)) {
+ r_u->switch_value = switch_value;
+ r_u->ptr_0 = 1;
+ r_u->ctr = ctr;
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_samr_unknown_2e(char *desc, SAMR_R_UNKNOWN_2E * r_u,
+ prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
+ return False;
+
+ if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
+ if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ switch (r_u->switch_value) {
+ case 0x0c:
+ if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
+ return False;
+ break;
+ case 0x07:
+ if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth))
+ return False;
+ break;
+ case 0x06:
+ if(!sam_io_unk_info6("unk_inf6",&r_u->ctr->info.inf6, ps,depth))
+ return False;
+ break;
+ case 0x05:
+ if(!sam_io_unk_info5("unk_inf5",&r_u->ctr->info.inf5, ps,depth))
+ return False;
+ break;
+ case 0x03:
+ if(!sam_io_unk_info3("unk_inf3",&r_u->ctr->info.inf3, ps,depth))
+ return False;
+ break;
+ case 0x02:
+ if(!sam_io_unk_info2("unk_inf2",&r_u->ctr->info.inf2, ps,depth))
+ return False;
+ break;
+ case 0x01:
+ if(!sam_io_unk_info1("unk_inf1",&r_u->ctr->info.inf1, ps,depth))
+ return False;
+ break;
+ default:
+ DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n",
+ r_u->switch_value));
+ r_u->status = NT_STATUS_INVALID_INFO_CLASS;
+ return False;
+ }
+ }
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+void init_samr_q_set_domain_info(SAMR_Q_SET_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value, SAM_UNK_CTR *ctr)
+{
+ DEBUG(5, ("init_samr_q_set_domain_info\n"));
+
+ q_u->domain_pol = *domain_pol;
+ q_u->switch_value0 = switch_value;
+
+ q_u->switch_value = switch_value;
+ q_u->ctr = ctr;
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_set_domain_info(char *desc, SAMR_Q_SET_DOMAIN_INFO *q_u,
+ prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_set_domain_info");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
+ return False;
+
+ if(!prs_uint16("switch_value0", ps, depth, &q_u->switch_value0))
+ return False;
+
+ if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ((q_u->ctr = (SAM_UNK_CTR *)prs_alloc_mem(ps, sizeof(SAM_UNK_CTR))) == NULL)
+ return False;
+
+ switch (q_u->switch_value) {
+
+ case 0x0c:
+ if(!sam_io_unk_info12("unk_inf12", &q_u->ctr->info.inf12, ps, depth))
+ return False;
+ break;
+ case 0x07:
+ if(!sam_io_unk_info7("unk_inf7",&q_u->ctr->info.inf7, ps,depth))
+ return False;
+ break;
+ case 0x06:
+ if(!sam_io_unk_info6("unk_inf6",&q_u->ctr->info.inf6, ps,depth))
+ return False;
+ break;
+ case 0x05:
+ if(!sam_io_unk_info5("unk_inf5",&q_u->ctr->info.inf5, ps,depth))
+ return False;
+ break;
+ case 0x03:
+ if(!sam_io_unk_info3("unk_inf3",&q_u->ctr->info.inf3, ps,depth))
+ return False;
+ break;
+ case 0x02:
+ if(!sam_io_unk_info2("unk_inf2",&q_u->ctr->info.inf2, ps,depth))
+ return False;
+ break;
+ case 0x01:
+ if(!sam_io_unk_info1("unk_inf1",&q_u->ctr->info.inf1, ps,depth))
+ return False;
+ break;
+ default:
+ DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n",
+ q_u->switch_value));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+inits a SAMR_R_QUERY_DOMAIN_INFO structure.
+********************************************************************/
+
+void init_samr_r_set_domain_info(SAMR_R_SET_DOMAIN_INFO * r_u, NTSTATUS status)
+{
+ DEBUG(5, ("init_samr_r_set_domain_info\n"));
+
+ r_u->status = status; /* return status */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_set_domain_info(char *desc, SAMR_R_SET_DOMAIN_INFO * r_u,
+ prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index b202c2a3566..3813326293b 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -22,11 +22,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include "includes.h"
-extern int DEBUGLEVEL;
-
#define SD_HEADER_SIZE 0x14
/*******************************************************************
@@ -71,8 +68,8 @@ void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 f
t->size = sid_size(sid) + 8;
t->info = mask;
- ZERO_STRUCTP(&t->sid);
- sid_copy(&t->sid, sid);
+ ZERO_STRUCTP(&t->trustee);
+ sid_copy(&t->trustee, sid);
}
/*******************************************************************
@@ -110,7 +107,7 @@ BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
if(!prs_align(ps))
return False;
- if(!smb_io_dom_sid("sid ", &psa->sid , ps, depth))
+ if(!smb_io_dom_sid("sid ", &psa->trustee , ps, depth))
return False;
if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
@@ -138,14 +135,15 @@ SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *a
/* Now we need to return a non-NULL address for the ace list even
if the number of aces required is zero. This is because there
is a distinct difference between a NULL ace and an ace with zero
- entries in it. This is achieved by always making the number of
- bytes allocated by talloc() positive. Heh. */
+ entries in it. This is achieved by checking that num_aces is a
+ positive number. */
- if((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces + 1))
- == NULL) {
+ if ((num_aces) &&
+ ((dst->ace = (SEC_ACE *)talloc(ctx, sizeof(SEC_ACE) * num_aces))
+ == NULL)) {
return NULL;
}
-
+
for (i = 0; i < num_aces; i++) {
dst->ace[i] = ace_list[i]; /* Structure copy. */
dst->size += ace_list[i].size;
@@ -283,7 +281,7 @@ BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
/* Check SID */
- if (!sid_equal(&s1->sid, &s2->sid)) {
+ if (!sid_equal(&s1->trustee, &s2->trustee)) {
return False;
}
@@ -298,9 +296,10 @@ BOOL sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
{
int i, j;
- /* Trivial case */
+ /* Trivial cases */
if (!s1 && !s2) return True;
+ if (!s1 || !s2) return False;
/* Check top level stuff */
@@ -544,7 +543,7 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
offset = SD_HEADER_SIZE;
dst->off_sacl = offset;
- offset += ((sacl->size + 3) & ~3);
+ offset += ((dst->sacl->size + 3) & ~3);
}
if (dst->dacl != NULL) {
@@ -553,7 +552,7 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision,
offset = SD_HEADER_SIZE;
dst->off_dacl = offset;
- offset += ((dacl->size + 3) & ~3);
+ offset += ((dst->dacl->size + 3) & ~3);
}
*sd_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset);
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index cbdd961066d..94bf6f906b7 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -4,8 +4,9 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- * Copyright (C) Jean François Micouleau 1998-2000.
- * Copyright (C) Gerald Carter 2000
+ * Copyright (C) Jean François Micouleau 1998-2000,
+ * Copyright (C) Gerald Carter 2000,
+ * Copyright (C) Tim Potter 2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,8 +25,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
return the length of a UNISTR string.
********************************************************************/
@@ -49,21 +48,21 @@ This should be moved in a more generic lib.
static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
{
- if(!prs_uint16("year", ps, depth, &(systime->year)))
+ if(!prs_uint16("year", ps, depth, &systime->year))
return False;
- if(!prs_uint16("month", ps, depth, &(systime->month)))
+ if(!prs_uint16("month", ps, depth, &systime->month))
return False;
- if(!prs_uint16("dayofweek", ps, depth, &(systime->dayofweek)))
+ if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
return False;
- if(!prs_uint16("day", ps, depth, &(systime->day)))
+ if(!prs_uint16("day", ps, depth, &systime->day))
return False;
- if(!prs_uint16("hour", ps, depth, &(systime->hour)))
+ if(!prs_uint16("hour", ps, depth, &systime->hour))
return False;
- if(!prs_uint16("minute", ps, depth, &(systime->minute)))
+ if(!prs_uint16("minute", ps, depth, &systime->minute))
return False;
- if(!prs_uint16("second", ps, depth, &(systime->second)))
+ if(!prs_uint16("second", ps, depth, &systime->second))
return False;
- if(!prs_uint16("milliseconds", ps, depth, &(systime->milliseconds)))
+ if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
return False;
return True;
@@ -193,6 +192,10 @@ static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_
reads or writes an NOTIFY OPTION TYPE structure.
********************************************************************/
+/* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
+ structure. The _TYPE structure is really the deferred referrants (i.e
+ the notify fields array) of the _TYPE structure. -tpot */
+
static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_notify_option_type");
@@ -635,7 +638,8 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
}
DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
- if (!prs_uint8s(True, "private", ps, depth, devmode->private, devmode->driverextra))
+ if (!prs_uint8s(False, "private", ps, depth,
+ devmode->private, devmode->driverextra))
return False;
}
@@ -760,6 +764,7 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
/*******************************************************************
* init a structure.
********************************************************************/
+
BOOL make_spoolss_q_addprinterex(
TALLOC_CTX *mem_ctx,
SPOOL_Q_ADDPRINTEREX *q_u,
@@ -773,6 +778,8 @@ BOOL make_spoolss_q_addprinterex(
if (!ctr) return False;
+ ZERO_STRUCTP(q_u);
+
q_u->server_name_ptr = (srv_name!=NULL)?1:0;
init_unistr2(&q_u->server_name, srv_name, strlen(srv_name));
@@ -780,12 +787,10 @@ BOOL make_spoolss_q_addprinterex(
q_u->info.level = level;
q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
- switch (level)
- {
+ switch (level) {
case 2:
/* init q_u->info.info2 from *info */
- if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2))
- {
+ if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
return False;
}
@@ -794,8 +799,6 @@ BOOL make_spoolss_q_addprinterex(
break;
}
- q_u->unk0 = q_u->unk1 = q_u->unk2 = q_u->unk3 = 0;
-
q_u->user_switch=1;
q_u->user_ctr.level=1;
@@ -818,18 +821,14 @@ BOOL make_spoolss_q_addprinterex(
create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
*******************************************************************/
-BOOL make_spoolss_printer_info_2(
- TALLOC_CTX *mem_ctx,
- SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
- PRINTER_INFO_2 *info
-)
+BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
+ PRINTER_INFO_2 *info)
{
SPOOL_PRINTER_INFO_LEVEL_2 *inf;
/* allocate the necessary memory */
- if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2))))
- {
+ if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2)))) {
DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
return False;
}
@@ -866,7 +865,6 @@ BOOL make_spoolss_printer_info_2(
init_unistr2_from_unistr(&inf->datatype, &info->datatype);
init_unistr2_from_unistr(&inf->parameters, &info->parameters);
init_unistr2_from_unistr(&inf->datatype, &info->datatype);
- inf->secdesc = inf->secdesc;
*spool_info2 = inf;
@@ -952,7 +950,7 @@ BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_
if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
return False;
- if (!prs_uint32("status code", ps, depth, &(r_u->status)))
+ if (!prs_werror("status code", ps, depth, &(r_u->status)))
return False;
return True;
@@ -1040,7 +1038,7 @@ BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u,
{
prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1074,7 +1072,7 @@ BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_st
if (!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1126,7 +1124,7 @@ BOOL spoolss_io_r_abortprinter(char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct
{
prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1170,7 +1168,7 @@ BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_stru
if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1220,7 +1218,7 @@ BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r
if (!prs_align(ps))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1266,7 +1264,7 @@ BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct
if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1307,7 +1305,7 @@ BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_
depth++;
if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1343,7 +1341,7 @@ BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_stru
{
prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1379,7 +1377,7 @@ BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, pr
{
prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1415,7 +1413,7 @@ BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_st
{
prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1469,7 +1467,7 @@ BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct
depth++;
if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1531,7 +1529,7 @@ BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, in
prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1593,7 +1591,7 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, in
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1807,19 +1805,19 @@ static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16
buffer->string_at_end -= (q-p+1)*sizeof(uint16);
if(!prs_set_offset(ps, buffer->string_at_end)) {
- free(chaine.buffer);
+ SAFE_FREE(chaine.buffer);
return False;
}
/* write the string */
if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) {
- free(chaine.buffer);
+ SAFE_FREE(chaine.buffer);
return False;
}
q++;
p=q;
- free(chaine.buffer);
+ SAFE_FREE(chaine.buffer);
}
if(!prs_set_offset(ps, struct_offset))
@@ -1862,18 +1860,16 @@ static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16
if (l_chaine > 0)
{
uint16 *tc2;
-
+
realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
/* Yes this should be realloc - it's freed below. JRA */
if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
- if (chaine2)
- free(chaine2);
+ SAFE_FREE(chaine2);
return False;
- } else
- chaine2 = tc2;
-
+ }
+ else chaine2 = tc2;
memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
l_chaine2+=l_chaine+1;
}
@@ -1886,7 +1882,7 @@ static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16
{
chaine2[l_chaine2] = '\0';
*string=(uint16 *)talloc_memdup(prs_get_mem_context(ps),chaine2,realloc_size);
- free(chaine2);
+ SAFE_FREE(chaine2);
}
if(!prs_set_offset(ps, old_offset))
@@ -2239,6 +2235,54 @@ BOOL smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info,
}
/*******************************************************************
+ Parse a PRINTER_INFO_4 structure.
+********************************************************************/
+
+BOOL smb_io_printer_info_4(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
+{
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "smb_io_printer_info_4");
+ depth++;
+
+ buffer->struct_start=prs_offset(ps);
+
+ if (!smb_io_relstr("printername", buffer, depth, &info->printername))
+ return False;
+ if (!smb_io_relstr("servername", buffer, depth, &info->servername))
+ return False;
+ if (!prs_uint32("attributes", ps, depth, &info->attributes))
+ return False;
+ return True;
+}
+
+/*******************************************************************
+ Parse a PRINTER_INFO_5 structure.
+********************************************************************/
+
+BOOL smb_io_printer_info_5(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
+{
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "smb_io_printer_info_5");
+ depth++;
+
+ buffer->struct_start=prs_offset(ps);
+
+ if (!smb_io_relstr("printername", buffer, depth, &info->printername))
+ return False;
+ if (!smb_io_relstr("portname", buffer, depth, &info->portname))
+ return False;
+ if (!prs_uint32("attributes", ps, depth, &info->attributes))
+ return False;
+ if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
+ return False;
+ if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
+ return False;
+ return True;
+}
+
+/*******************************************************************
Parse a PORT_INFO_1 structure.
********************************************************************/
@@ -2671,6 +2715,7 @@ static BOOL spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER
move a BUFFER from the query to the reply.
As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
this is ok. This is an OPTIMIZATION and is not strictly neccessary.
+ Clears the memory to zero also.
********************************************************************/
void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
@@ -2678,8 +2723,8 @@ void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
prs_switch_type(&src->prs, MARSHALL);
if(!prs_set_offset(&src->prs, 0))
return;
- prs_force_dynamic(&(src->prs));
-
+ prs_force_dynamic(&src->prs);
+ prs_mem_clear(&src->prs);
*dest=src;
}
@@ -2949,6 +2994,39 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
return the size required by a struct in the stream
********************************************************************/
+uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
+{
+ uint32 size=0;
+
+ size+=size_of_relative_string( &info->printername );
+ size+=size_of_relative_string( &info->servername );
+
+ size+=size_of_uint32( &info->attributes );
+ return size;
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+
+uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
+{
+ uint32 size=0;
+
+ size+=size_of_relative_string( &info->printername );
+ size+=size_of_relative_string( &info->portname );
+
+ size+=size_of_uint32( &info->attributes );
+ size+=size_of_uint32( &info->device_not_selected_timeout );
+ size+=size_of_uint32( &info->transmission_retry_timeout );
+ return size;
+}
+
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+
uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
{
/* The 4 is for the self relative pointer.. */
@@ -3174,6 +3252,21 @@ uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
return the size required by a struct in the stream
********************************************************************/
+uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
+{
+ int size=0;
+
+ size=str_len_uni(&info->name); /* the string length */
+ size=size+1; /* add the leading zero */
+ size=size*2; /* convert in char */
+
+ return size;
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
+
uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
{
int size=0;
@@ -3215,6 +3308,25 @@ uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
+uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
+{
+ uint32 size = 0;
+
+ if (!p)
+ return 0;
+
+ /* 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->type);
+
+ return size;
+}
+
+/*******************************************************************
+return the size required by a struct in the stream
+********************************************************************/
uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
{
@@ -3331,7 +3443,7 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
return False;
if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3441,7 +3553,7 @@ BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3470,7 +3582,7 @@ BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps
if (!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3534,40 +3646,28 @@ BOOL make_spoolss_q_getprinter(
/*******************************************************************
* init a structure.
********************************************************************/
-BOOL make_spoolss_q_setprinter(
- TALLOC_CTX *mem_ctx,
- SPOOL_Q_SETPRINTER *q_u,
- const POLICY_HND *hnd,
- uint32 level,
- PRINTER_INFO_CTR *info,
- uint32 command
-)
+BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u,
+ const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info,
+ uint32 command)
{
SEC_DESC *secdesc;
DEVICEMODE *devmode;
if (q_u == NULL)
- {
return False;
- }
memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
q_u->level = level;
q_u->info.level = level;
q_u->info.info_ptr = (info != NULL) ? 1 : 0;
- switch (level)
- {
+ switch (level) {
case 2:
secdesc = info->printers_2->secdesc;
devmode = info->printers_2->devmode;
- /* FIXMEE!! HACK ALERT!!! --jerry */
- info->printers_2->devmode = NULL;
- info->printers_2->secdesc = NULL;
-
make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
-#if 0 /* JERRY TEST */
+#if 1 /* JERRY TEST */
q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
if (!q_u->secdesc_ctr)
return False;
@@ -3577,7 +3677,7 @@ BOOL make_spoolss_q_setprinter(
q_u->secdesc_ctr->sec = secdesc;
q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
- q_u->devmode_ctr.size = sizeof(DEVICEMODE) + (3*sizeof(uint32));
+ q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
q_u->devmode_ctr.devmode = devmode;
#else
q_u->secdesc_ctr = NULL;
@@ -3610,7 +3710,7 @@ BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3659,15 +3759,16 @@ BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps
if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
return False;
} else {
- uint32 dummy;
+ uint32 dummy = 0;
/* Parse a NULL security descriptor. This should really
happen inside the sec_io_desc_buf() function. */
prs_debug(ps, depth, "", "sec_io_desc_buf");
- if (!prs_uint32("size", ps, depth + 1, &dummy)) return False;
+ if (!prs_uint32("size", ps, depth + 1, &dummy))
+ return False;
if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
- False;
+ False;
}
if(!prs_uint32("command", ps, depth, &q_u->command))
@@ -3687,7 +3788,7 @@ BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3732,7 +3833,7 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de
if(!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3789,7 +3890,7 @@ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, in
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3859,7 +3960,7 @@ BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3895,7 +3996,7 @@ BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int de
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -3952,7 +4053,7 @@ BOOL spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4070,7 +4171,7 @@ BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps,
if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4129,7 +4230,7 @@ BOOL spoolss_io_r_getform(char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int
if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4159,7 +4260,7 @@ BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps,
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4404,6 +4505,8 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
{
+ uint32 ptr_sec_desc = 0;
+
prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
depth++;
@@ -4423,26 +4526,33 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
return False;
- /* the 4 unknown are all 0 */
-
- /*
- * en fait ils sont pas inconnu
- * par recoupement avec rpcSetPrinter
- * c'est le devicemode
- * et le security descriptor.
- */
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
- return False;
- if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
- return False;
- if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
- return False;
- if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
+ if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
return False;
+ switch (q_u->level) {
+ case 2:
+ ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
+ break;
+ case 3:
+ ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
+ break;
+ }
+ if (ptr_sec_desc) {
+ if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
+ return False;
+ } else {
+ uint32 dummy;
+
+ /* Parse a NULL security descriptor. This should really
+ happen inside the sec_io_desc_buf() function. */
+
+ prs_debug(ps, depth, "", "sec_io_desc_buf");
+ if (!prs_uint32("size", ps, depth + 1, &dummy))
+ return False;
+ if (!prs_uint32("ptr", ps, depth + 1, &dummy))
+ return False;
+ }
+
if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
return False;
if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
@@ -4463,7 +4573,7 @@ BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u,
if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -4714,7 +4824,8 @@ static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
int n = 0;
char *src;
- if (buf5==NULL) return False;
+ if (buf5==NULL)
+ return False;
src = (char *)buf5->buffer;
*ar = NULL;
@@ -4731,10 +4842,13 @@ static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
n++;
}
fstrcpy((*ar)[n], "");
-
+
return True;
}
+
+
+
/*******************************************************************
read a UNICODE array with null terminated strings
and null terminated array
@@ -4890,7 +5004,7 @@ BOOL make_spoolss_driver_info_3(
inf->dependentfilessize = len;
if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
{
- safe_free (inf);
+ SAFE_FREE(inf);
return False;
}
@@ -4902,13 +5016,7 @@ BOOL make_spoolss_driver_info_3(
/*******************************************************************
make a BUFFER5 struct from a uint16*
******************************************************************/
-
-BOOL make_spoolss_buffer5(
- TALLOC_CTX *mem_ctx,
- BUFFER5 *buf5,
- uint32 len,
- uint16 *src
-)
+BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
{
buf5->buf_len = len;
@@ -4957,7 +5065,7 @@ BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, pr
prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
depth++;
- if(!prs_uint32("status", ps, depth, &q_u->status))
+ if(!prs_werror("status", ps, depth, &q_u->status))
return False;
return True;
@@ -5004,9 +5112,11 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
- uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles );
-
- return True;
+ if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
+ return True;
+
+ SAFE_FREE(*asc);
+ return False;
}
/*******************************************************************
@@ -5049,10 +5159,16 @@ BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
- uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles );
- uniarray_2_dosarray(&uni->previousnames, &d->previousnames );
-
+ if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
+ goto error;
+ if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
+ goto error;
+
return True;
+
+error:
+ SAFE_FREE(*asc);
+ return False;
}
BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
@@ -5076,7 +5192,6 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
* addprinter(ex) so we can do one time stuff here.
*/
(*asc)->setuptime=time_unix;
-
}
DEBUGADD(8,("start converting\n"));
@@ -5186,7 +5301,7 @@ BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r
if (!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5215,7 +5330,7 @@ BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5308,7 +5423,7 @@ BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u,
if (!prs_align(ps))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5337,7 +5452,7 @@ BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATY
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5443,7 +5558,7 @@ BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u,
if (!prs_uint32("returned", ps, depth, &r_u->returned))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5483,7 +5598,7 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_
if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5528,6 +5643,24 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
/*******************************************************************
********************************************************************/
+BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
+ char* value, char* data)
+{
+ UNISTR2 tmp;
+
+ memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
+ q_u->type = REG_SZ;
+ init_unistr2(&q_u->value, value, strlen(value)+1);
+
+ init_unistr2(&tmp, data, strlen(data)+1);
+ q_u->max_len = q_u->real_len = tmp.uni_max_len*2;
+ q_u->data = talloc(ctx, q_u->real_len);
+ memcpy(q_u->data, tmp.buffer, q_u->real_len);
+
+ return True;
+}
+/*******************************************************************
+********************************************************************/
BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
{
@@ -5552,10 +5685,10 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st
switch (q_u->type)
{
- case 0x1:
- case 0x3:
- case 0x4:
- case 0x7:
+ case REG_SZ:
+ case REG_BINARY:
+ case REG_DWORD:
+ case REG_MULTI_SZ:
if (q_u->max_len) {
if (UNMARSHALLING(ps))
q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
@@ -5585,7 +5718,7 @@ BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_st
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5692,7 +5825,7 @@ BOOL spoolss_io_r_deleteform(char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5737,7 +5870,7 @@ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5788,7 +5921,7 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5815,7 +5948,7 @@ BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int de
if (!prs_uint32("needed", ps, depth, &r_u->needed))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -5855,14 +5988,14 @@ BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int de
void free_devmode(DEVICEMODE *devmode)
{
if (devmode!=NULL) {
- safe_free(devmode->private);
- safe_free(devmode);
+ SAFE_FREE(devmode->private);
+ SAFE_FREE(devmode);
}
}
void free_printer_info_1(PRINTER_INFO_1 *printer)
{
- safe_free(printer);
+ SAFE_FREE(printer);
}
void free_printer_info_2(PRINTER_INFO_2 *printer)
@@ -5870,15 +6003,23 @@ void free_printer_info_2(PRINTER_INFO_2 *printer)
if (printer!=NULL) {
free_devmode(printer->devmode);
printer->devmode = NULL;
- safe_free(printer);
+ SAFE_FREE(printer);
}
}
void free_printer_info_3(PRINTER_INFO_3 *printer)
{
- if (printer!=NULL) {
- safe_free(printer);
- }
+ SAFE_FREE(printer);
+}
+
+void free_printer_info_4(PRINTER_INFO_4 *printer)
+{
+ SAFE_FREE(printer);
+}
+
+void free_printer_info_5(PRINTER_INFO_5 *printer)
+{
+ SAFE_FREE(printer);
}
void free_job_info_2(JOB_INFO_2 *job)
@@ -5954,7 +6095,7 @@ BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, pr
if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6007,7 +6148,7 @@ BOOL spoolss_io_r_replycloseprinter(char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u,
if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -6083,7 +6224,7 @@ BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *
BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
+ prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
depth++;
if (!prs_align(ps))
@@ -6092,8 +6233,448 @@ BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *
if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
+
+/*******************************************************************
+ * read a structure.
+ * called from spoolss_q_getprinterdataex (srv_spoolss.c)
+ ********************************************************************/
+
+BOOL spoolss_io_q_getprinterdataex(char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
+ return False;
+ if (!prs_align(ps))
+ return False;
+ if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
+ return False;
+ if (!prs_align(ps))
+ return False;
+ if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
+ return False;
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("size", ps, depth, &q_u->size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ * called from spoolss_r_getprinterdataex (srv_spoolss.c)
+ ********************************************************************/
+
+BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("type", ps, depth, &r_u->type))
+ return False;
+ if (!prs_uint32("size", ps, depth, &r_u->size))
+ return False;
+
+ if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("needed", ps, depth, &r_u->needed))
+ return False;
+ if (!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * read a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_q_setprinterdataex(char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
+ return False;
+ if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("type", ps, depth, &q_u->type))
+ return False;
+
+ if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
+ return False;
+
+ switch (q_u->type)
+ {
+ case 0x1:
+ case 0x3:
+ case 0x4:
+ case 0x7:
+ if (q_u->max_len) {
+ if (UNMARSHALLING(ps))
+ q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
+ if(q_u->data == NULL)
+ return False;
+ if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
+ return False;
+ }
+ if(!prs_align(ps))
+ return False;
+ break;
+ }
+
+ if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_r_setprinterdataex(char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+ * read a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_q_enumprinterkey(char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("size", ps, depth, &q_u->size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!smb_io_buffer5("", &r_u->keys, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("needed", ps, depth, &r_u->needed))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+ * read a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_q_enumprinterdataex(char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("size", ps, depth, &q_u->size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps,
+ PRINTER_ENUM_VALUES_CTR *ctr, int depth)
+{
+ int i;
+ uint32 valuename_offset,
+ data_offset,
+ current_offset;
+ const uint32 basic_unit = 20; /* size of static portion of enum_values */
+
+ 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 */
+
+ current_offset = basic_unit * ctr->size_of_array;
+
+ /* first loop to write basic enum_value information */
+
+ for (i=0; i<ctr->size_of_array; i++)
+ {
+ valuename_offset = current_offset;
+ if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
+ return False;
+
+ if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
+ return False;
+
+ if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
+ 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;
+ }
+
+ /* loop #2 for writing the dynamically size objects
+ while viewing conversations between Win2k -> Win2k,
+ 4-byte alignment does not seem to matter here --jerry */
+
+ for (i=0; i<ctr->size_of_array; i++)
+ {
+
+ if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
+ return False;
+
+ if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
+ return False;
+ }
+
+
+
+ return True;
+}
+
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
+{
+ 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 ))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("needed", ps, depth, &r_u->needed))
+ return False;
+
+ if(!prs_uint32("returned", ps, depth, &r_u->returned))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+/*
+ uint32 GetPrintProcessorDirectory(
+ [in] unistr2 *name,
+ [in] unistr2 *environment,
+ [in] uint32 level,
+ [in,out] NEW_BUFFER buffer,
+ [in] uint32 offered,
+ [out] uint32 needed,
+ [out] uint32 returned
+ );
+
+*/
+
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
+{
+ DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
+
+ init_unistr2(&q_u->name, name, strlen(name)+1);
+ init_unistr2(&q_u->environment, environment, strlen(environment)+1);
+
+ q_u->level = level;
+
+ q_u->buffer = buffer;
+ q_u->offered = offered;
+
+ return True;
+}
+
+BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
+{
+ uint32 ptr;
+
+ prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr", ps, depth, &ptr))
+ return False;
+
+ if (ptr) {
+ if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
+ return False;
+ }
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr", ps, depth, &ptr))
+ return False;
+
+ if (ptr) {
+ if(!smb_io_unistr2("environment", &q_u->environment, True,
+ ps, depth))
+ return False;
+ }
+
+ if (!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("level", ps, depth, &q_u->level))
+ return False;
+
+ if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("offered", ps, depth, &q_u->offered))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ * write a structure.
+ ********************************************************************/
+
+BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("needed", ps, depth, &r_u->needed))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
+{
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
+ depth++;
+
+ buffer->struct_start=prs_offset(ps);
+
+ if (!smb_io_unistr(desc, &info->name, ps, depth))
+ return False;
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 637b8342660..fa52b244956 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -22,11 +22,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
Inits a SH_INFO_1_STR structure
********************************************************************/
@@ -617,7 +614,7 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -742,7 +739,7 @@ BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status", ps, depth, &r_n->status))
return False;
return True;
@@ -803,7 +800,7 @@ BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_
if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value))
return False;
- if(!prs_uint32("status ", ps, depth, &q_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &q_n->status))
return False;
return True;
@@ -861,7 +858,7 @@ BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps
if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value))
return False;
- if(!prs_uint32("status ", ps, depth, &q_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &q_n->status))
return False;
return True;
@@ -908,7 +905,7 @@ BOOL srv_io_r_net_share_del(char *desc, SRV_R_NET_SHARE_DEL *q_n, prs_struct *ps
if(!prs_align(ps))
return False;
- if(!prs_uint32("status ", ps, depth, &q_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &q_n->status))
return False;
return True;
@@ -1311,7 +1308,7 @@ BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -1676,7 +1673,7 @@ BOOL srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *p
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -1954,7 +1951,7 @@ BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2240,13 +2237,13 @@ BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_stru
********************************************************************/
void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
- uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status)
+ uint32 switch_value, SRV_INFO_CTR *ctr, NTSTATUS status)
{
DEBUG(5,("init_srv_r_net_srv_get_info\n"));
srv->ctr = ctr;
- if (status == 0x0) {
+ if (NT_STATUS_IS_OK(status)) {
srv->ctr->switch_value = switch_value;
srv->ctr->ptr_srv_ctr = 1;
} else {
@@ -2262,7 +2259,7 @@ void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
********************************************************************/
void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
- uint32 switch_value, uint32 status)
+ uint32 switch_value, NTSTATUS status)
{
DEBUG(5,("init_srv_r_net_srv_set_info\n"));
@@ -2326,7 +2323,7 @@ BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_stru
if(!srv_io_info_ctr("ctr", r_n->ctr, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2348,7 +2345,7 @@ BOOL srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n,
if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2467,7 +2464,7 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *
if(!srv_io_time_of_day_info("tod", r_n->tod, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_n->status))
return False;
return True;
@@ -2566,7 +2563,7 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
- if(!prs_uint32("status", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status", ps, depth, &r_n->status))
return False;
return True;
@@ -2626,7 +2623,7 @@ BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_st
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status", ps, depth, &r_n->status))
return False;
return True;
@@ -2713,7 +2710,7 @@ BOOL srv_io_r_net_file_query_secdesc(char *desc, SRV_R_NET_FILE_QUERY_SECDESC *r
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status", ps, depth, &r_n->status))
return False;
return True;
@@ -2791,7 +2788,7 @@ BOOL srv_io_r_net_file_set_secdesc(char *desc, SRV_R_NET_FILE_SET_SECDESC *r_n,
if(!prs_align(ps))
return False;
- if(!prs_uint32("status", ps, depth, &r_n->status))
+ if(!prs_ntstatus("status", ps, depth, &r_n->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_wks.c b/source/rpc_parse/parse_wks.c
index 7357e3d2f3a..ecd4a201ae4 100644
--- a/source/rpc_parse/parse_wks.c
+++ b/source/rpc_parse/parse_wks.c
@@ -1,4 +1,3 @@
-
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
@@ -22,11 +21,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
Init
********************************************************************/
@@ -135,8 +131,8 @@ static BOOL wks_io_wks_info_100(char *desc, WKS_INFO_100 *inf, prs_struct *ps, i
********************************************************************/
void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
- uint32 switch_value, WKS_INFO_100 *wks100,
- int status)
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ NTSTATUS status)
{
DEBUG(5,("init_wks_r_unknown_0: %d\n", __LINE__));
@@ -173,7 +169,7 @@ BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int
if(!wks_io_wks_info_100("inf", r_u->wks100, ps, depth))
return False;
- if(!prs_uint32("status ", ps, depth, &r_u->status))
+ if(!prs_ntstatus("status ", ps, depth, &r_u->status))
return False;
return True;
diff --git a/source/rpc_server/srv_dfs.c b/source/rpc_server/srv_dfs.c
index fe797e84f6e..6b48a46b466 100644
--- a/source/rpc_server/srv_dfs.c
+++ b/source/rpc_server/srv_dfs.c
@@ -29,7 +29,6 @@
#define MAX_MSDFS_JUNCTIONS 256
-extern int DEBUGLEVEL;
extern pstring global_myname;
#ifdef WITH_MSDFS
diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c
index 9bc12e2a965..5dcf7894f33 100644
--- a/source/rpc_server/srv_dfs_nt.c
+++ b/source/rpc_server/srv_dfs_nt.c
@@ -27,12 +27,13 @@
#include "includes.h"
#include "nterr.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
+#define MAX_MSDFS_JUNCTIONS 256
#ifdef WITH_MSDFS
-#define MAX_MSDFS_JUNCTIONS 256
+/* This function does not return a WERROR or NTSTATUS code but rather 1 if
+ dfs exists, or 0 otherwise. */
uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u)
{
@@ -42,7 +43,7 @@ uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u)
return 0;
}
-uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
+WERROR _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
{
struct current_user user;
struct junction_map jn;
@@ -56,11 +57,7 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
if (user.uid != 0) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
-
- /* RPC calls return Windows errors. NT_STATUS_ACCESS_DENIED
- doesn't work as a return code for RPC calls
- */
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
@@ -89,14 +86,14 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
if(jn.referral_list == NULL)
{
DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
- return NERR_DfsInternalError;
+ return WERR_DFS_INTERNAL_ERROR;
}
if(old_referral_list)
{
memcpy(jn.referral_list, old_referral_list,
sizeof(struct referral)*jn.referral_count-1);
- free(old_referral_list);
+ SAFE_FREE(old_referral_list);
}
jn.referral_list[jn.referral_count-1].proximity = 0;
@@ -105,12 +102,13 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
if(!create_msdfs_link(&jn, exists))
- return NERR_DfsCantCreateJunctionPoint;
+ return WERR_DFS_CANT_CREATE_JUNCT;
- return ERRsuccess;
+ return WERR_OK;
}
-uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u)
+WERROR _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u,
+ DFS_R_DFS_REMOVE *r_u)
{
struct current_user user;
struct junction_map jn;
@@ -123,10 +121,7 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
if (user.uid != 0) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
- /* NT_STATUS_ACCESS_DENIED will not work as a status code
- for RPC calls
- */
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
@@ -148,13 +143,13 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
dfspath, servername, sharename));
if(!get_referred_path(dfspath, &jn, NULL, NULL))
- return NERR_DfsNoSuchVolume;
+ return WERR_DFS_NO_SUCH_VOL;
/* if no server-share pair given, remove the msdfs link completely */
if(!q_u->ptr_ServerName && !q_u->ptr_ShareName)
{
if(!remove_msdfs_link(&jn))
- return NERR_DfsNoSuchVolume;
+ return WERR_DFS_NO_SUCH_VOL;
}
else
{
@@ -176,22 +171,22 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
}
}
if(!found)
- return NERR_DfsNoSuchShare;
+ return WERR_DFS_NO_SUCH_SHARE;
/* Only one referral, remove it */
if(jn.referral_count == 1)
{
if(!remove_msdfs_link(&jn))
- return NERR_DfsNoSuchVolume;
+ return WERR_DFS_NO_SUCH_VOL;
}
else
{
if(!create_msdfs_link(&jn, True))
- return NERR_DfsCantCreateJunctionPoint;
+ return WERR_DFS_CANT_CREATE_JUNCT;
}
}
- return ERRsuccess;
+ return WERR_OK;
}
static BOOL init_reply_dfs_info_1(struct junction_map* j, DFS_INFO_1* dfs1, int num_j)
@@ -281,8 +276,9 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_I
return True;
}
-static uint32 init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ctr,
- struct junction_map* jn, int num_jn)
+static WERROR init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level,
+ DFS_INFO_CTR* ctr, struct junction_map* jn,
+ int num_jn)
{
/* do the levels */
switch(level)
@@ -292,7 +288,7 @@ static uint32 init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ct
DFS_INFO_1* dfs1;
dfs1 = (DFS_INFO_1*) talloc(ctx, num_jn * sizeof(DFS_INFO_1));
if (!dfs1)
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
init_reply_dfs_info_1(jn, dfs1, num_jn);
ctr->dfs.info1 = dfs1;
break;
@@ -302,7 +298,7 @@ static uint32 init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ct
DFS_INFO_2* dfs2;
dfs2 = (DFS_INFO_2*) talloc(ctx, num_jn * sizeof(DFS_INFO_2));
if (!dfs2)
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
init_reply_dfs_info_2(jn, dfs2, num_jn);
ctr->dfs.info2 = dfs2;
break;
@@ -312,18 +308,18 @@ static uint32 init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ct
DFS_INFO_3* dfs3;
dfs3 = (DFS_INFO_3*) talloc(ctx, num_jn * sizeof(DFS_INFO_3));
if (!dfs3)
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
init_reply_dfs_info_3(ctx, jn, dfs3, num_jn);
ctr->dfs.info3 = dfs3;
break;
}
default:
- return NT_STATUS_INVALID_LEVEL;
+ return WERR_INVALID_PARAM;
}
- return NT_STATUS_OK;
+ return WERR_OK;
}
-uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
+WERROR _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
{
uint32 level = q_u->level;
struct junction_map jn[MAX_MSDFS_JUNCTIONS];
@@ -342,7 +338,7 @@ uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
r_u->ctr = (DFS_INFO_CTR*)talloc(p->mem_ctx, sizeof(DFS_INFO_CTR));
if (!r_u->ctr)
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
ZERO_STRUCTP(r_u->ctr);
r_u->ctr->switch_value = level;
r_u->ctr->num_entries = num_jn;
@@ -353,7 +349,8 @@ uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
return r_u->status;
}
-uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u)
+WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
+ DFS_R_DFS_GET_INFO *r_u)
{
UNISTR2* uni_path = &q_u->uni_path;
uint32 level = q_u->level;
@@ -362,10 +359,10 @@ uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INF
unistr2_to_ascii(path, uni_path, sizeof(path)-1);
if(!create_junction(path, &jn))
- return NERR_DfsNoSuchServer;
+ return WERR_DFS_NO_SUCH_SERVER;
+ return WERR_DFS_NO_SUCH_VOL;
if(!get_referred_path(path, &jn, NULL, NULL))
- return NERR_DfsNoSuchVolume;
r_u->level = level;
r_u->ptr_ctr = 1;
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 005398924ee..ec7fb8f5e1a 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -26,8 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/***************************************************************************
api_lsa_open_policy2
***************************************************************************/
@@ -269,6 +267,98 @@ static BOOL api_lsa_open_secret(pipes_struct *p)
}
/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_privs(pipes_struct *p)
+{
+ LSA_Q_ENUM_PRIVS q_u;
+ LSA_R_ENUM_PRIVS r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_privs("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_privs: failed to unmarshall LSA_Q_ENUM_PRIVS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_privs(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_privs("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_privs: Failed to marshall LSA_R_ENUM_PRIVS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_priv_get_dispname(pipes_struct *p)
+{
+ LSA_Q_PRIV_GET_DISPNAME q_u;
+ LSA_R_PRIV_GET_DISPNAME r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_priv_get_dispname("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_priv_get_dispname: failed to unmarshall LSA_Q_PRIV_GET_DISPNAME.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_priv_get_dispname(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_priv_get_dispname("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_priv_get_dispname: Failed to marshall LSA_R_PRIV_GET_DISPNAME.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+#if 0
+/***************************************************************************
+ api_lsa_open_secret.
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_accounts(pipes_struct *p)
+{
+ LSA_Q_ENUM_ACCOUNTS q_u;
+ LSA_R_ENUM_ACCOUNTS r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_accounts("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_accounts: failed to unmarshall LSA_Q_ENUM_ACCOUNTS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_accounts(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_accounts("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_accounts: Failed to marshall LSA_R_ENUM_ACCOUNTS.\n"));
+ return False;
+ }
+
+ return True;
+}
+#endif
+
+/***************************************************************************
api_lsa_UNK_GET_CONNUSER
***************************************************************************/
@@ -300,6 +390,102 @@ static BOOL api_lsa_unk_get_connuser(pipes_struct *p)
}
/***************************************************************************
+ api_lsa_open_user
+ ***************************************************************************/
+
+static BOOL api_lsa_open_account(pipes_struct *p)
+{
+ LSA_Q_OPENACCOUNT q_u;
+ LSA_R_OPENACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_open_account("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_open_account: failed to unmarshall LSA_Q_OPENACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_open_account(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_open_account("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_open_account: Failed to marshall LSA_R_OPENACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+#if 0
+/***************************************************************************
+ api_lsa_get_privs
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_privsaccount(pipes_struct *p)
+{
+ LSA_Q_ENUMPRIVSACCOUNT q_u;
+ LSA_R_ENUMPRIVSACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_privsaccount("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_privsaccount: failed to unmarshall LSA_Q_ENUMPRIVSACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_privsaccount(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_privsaccount: Failed to marshall LSA_R_ENUMPRIVSACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+#endif
+
+/***************************************************************************
+ api_lsa_getsystemaccount
+ ***************************************************************************/
+
+static BOOL api_lsa_getsystemaccount(pipes_struct *p)
+{
+ LSA_Q_GETSYSTEMACCOUNT q_u;
+ LSA_R_GETSYSTEMACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_getsystemaccount("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_getsystemaccount: failed to unmarshall LSA_Q_GETSYSTEMACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_getsystemaccount(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_getsystemaccount("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_getsystemaccount: Failed to marshall LSA_R_GETSYSTEMACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/***************************************************************************
\PIPE\ntlsa commands
***************************************************************************/
@@ -313,7 +499,17 @@ static struct api_struct api_lsa_cmds[] =
{ "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
{ "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
{ "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
+ { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs },
+ { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
+#if 0
+ { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
+#endif
{ "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser},
+ { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
+#if 0
+ { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
+#endif
+ { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount},
{ NULL , 0 , NULL }
};
diff --git a/source/rpc_server/srv_lsa_hnd.c b/source/rpc_server/srv_lsa_hnd.c
index 393f50a498e..5504e4cf9c1 100644
--- a/source/rpc_server/srv_lsa_hnd.c
+++ b/source/rpc_server/srv_lsa_hnd.c
@@ -23,8 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* This is the max handles across all instances of a pipe name. */
#ifndef MAX_OPEN_POLS
#define MAX_OPEN_POLS 1024
@@ -112,15 +110,16 @@ BOOL create_policy_hnd(pipes_struct *p, POLICY_HND *hnd, void (*free_fn)(void *)
pol->data_ptr = data_ptr;
pol->free_fn = free_fn;
- pol_hnd_low++;
- if (pol_hnd_low == 0) (pol_hnd_high)++;
+ pol_hnd_low++;
+ if (pol_hnd_low == 0)
+ (pol_hnd_high)++;
- SIVAL(&pol->pol_hnd.data1, 0 , 0); /* first bit must be null */
- SIVAL(&pol->pol_hnd.data2, 0 , pol_hnd_low ); /* second bit is incrementing */
- SSVAL(&pol->pol_hnd.data3, 0 , pol_hnd_high); /* second bit is incrementing */
- SSVAL(&pol->pol_hnd.data4, 0 , (pol_hnd_high>>16)); /* second bit is incrementing */
- SIVAL(pol->pol_hnd.data5, 0, time(NULL)); /* something random */
- SIVAL(pol->pol_hnd.data5, 4, sys_getpid()); /* something more random */
+ SIVAL(&pol->pol_hnd.data1, 0 , 0); /* first bit must be null */
+ SIVAL(&pol->pol_hnd.data2, 0 , pol_hnd_low ); /* second bit is incrementing */
+ SSVAL(&pol->pol_hnd.data3, 0 , pol_hnd_high); /* second bit is incrementing */
+ SSVAL(&pol->pol_hnd.data4, 0 , (pol_hnd_high>>16)); /* second bit is incrementing */
+ SIVAL(pol->pol_hnd.data5, 0, time(NULL)); /* something random */
+ SIVAL(pol->pol_hnd.data5, 4, sys_getpid()); /* something more random */
DLIST_ADD(p->pipe_handles->Policy, pol);
p->pipe_handles->count++;
@@ -158,6 +157,7 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, POLICY_HND *h
DEBUG(4,("Policy not found: "));
dump_data(4, (char *)hnd, sizeof(*hnd));
+ p->bad_handle_fault_state = True;
return NULL;
}
@@ -194,7 +194,7 @@ BOOL close_policy_hnd(pipes_struct *p, POLICY_HND *hnd)
ZERO_STRUCTP(pol);
- free(pol);
+ SAFE_FREE(pol);
return True;
}
@@ -217,7 +217,7 @@ void close_policy_by_pipe(pipes_struct *p)
p->pipe_handles->Policy = NULL;
p->pipe_handles->count = 0;
- free(p->pipe_handles);
+ SAFE_FREE(p->pipe_handles);
p->pipe_handles = NULL;
DEBUG(10,("close_policy_by_pipe: deleted handle list for pipe %s\n", p->name ));
}
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index a14a479984b..916850e1490 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -26,11 +26,34 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern DOM_SID global_sam_sid;
extern fstring global_myworkgroup;
extern pstring global_myname;
+static PRIVS privs[] = {
+ {SE_PRIV_NONE, "no_privs", "No privilege"},
+ {SE_PRIV_ADD_USERS, "add_users", "add users"},
+ {SE_PRIV_ADD_MACHINES, "add_computers", "add computers to domain"},
+ {SE_PRIV_PRINT_OPERATOR, "print_op", "printer operator"},
+ {SE_PRIV_ALL, "all_privs", "all privileges"}
+};
+
+struct lsa_info {
+ DOM_SID sid;
+ uint32 access;
+};
+
+/*******************************************************************
+ Function to free the per handle data.
+ ********************************************************************/
+
+static void free_lsa_info(void *ptr)
+{
+ struct lsa_info *lsa = (struct lsa_info *)ptr;
+
+ SAFE_FREE(lsa);
+}
+
/***************************************************************************
Init dom_query
***************************************************************************/
@@ -283,7 +306,7 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
_lsa_open_policy2.
***************************************************************************/
-uint32 _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
+NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
{
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
@@ -298,7 +321,7 @@ uint32 _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2
_lsa_open_policy
***************************************************************************/
-uint32 _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
+NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
{
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
@@ -313,7 +336,7 @@ uint32 _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_
_lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
***************************************************************************/
-uint32 _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u)
+NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENUM_TRUST_DOM *r_u)
{
uint32 enum_context = 0;
char *dom_name = NULL;
@@ -324,7 +347,7 @@ uint32 _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENU
/* set up the LSA QUERY INFO response */
init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, dom_name, dom_sid,
- dom_name != NULL ? NT_STATUS_OK : NT_STATUS_UNABLE_TO_FREE_VM);
+ dom_name != NULL ? NT_STATUS_OK : NT_STATUS_NO_MORE_ENTRIES);
return r_u->status;
}
@@ -333,11 +356,12 @@ uint32 _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENU
_lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
***************************************************************************/
-uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
+NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
{
LSA_INFO_UNION *info = &r_u->dom;
DOM_SID domain_sid;
fstring dos_domain;
+ fstring dos_myname;
char *name = NULL;
DOM_SID *sid = NULL;
@@ -346,6 +370,9 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
+ fstrcpy(dos_myname, global_myname);
+ unix_to_dos(dos_myname, True);
+
fstrcpy(dos_domain, global_myworkgroup);
unix_to_dos(dos_domain, True);
@@ -355,13 +382,13 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
unsigned int i;
/* fake info: We audit everything. ;) */
info->id2.auditing_enabled = 1;
- info->id2.count1 = 7;
- info->id2.count2 = 7;
+ info->id2.count1 = 7;
+ info->id2.count2 = 7;
if ((info->id2.auditsettings = (uint32 *)talloc(p->mem_ctx,7*sizeof(uint32))) == NULL)
- return False;
- for (i = 0; i < 7; i++)
- info->id2.auditsettings[i] = 3;
- break;
+ return NT_STATUS_NO_MEMORY;
+ for (i = 0; i < 7; i++)
+ info->id2.auditsettings[i] = 3;
+ break;
}
case 0x03:
/* Request PolicyPrimaryDomainInformation. */
@@ -382,7 +409,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
break;
case ROLE_STANDALONE:
name = dos_domain;
- sid = NULL; /* Tell it we're not in a domain. */
+ sid = NULL;
break;
default:
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
@@ -398,11 +425,11 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
sid = &global_sam_sid;
break;
case ROLE_DOMAIN_MEMBER:
- name = dos_domain;
+ name = dos_myname;
sid = &global_sam_sid;
break;
case ROLE_STANDALONE:
- name = dos_domain;
+ name = dos_myname;
sid = &global_sam_sid;
break;
default:
@@ -434,7 +461,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
break;
}
- if(r_u->status == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(r_u->status)) {
r_u->undoc_buffer = 0x22000000; /* bizarre */
r_u->info_class = q_u->info_class;
}
@@ -446,7 +473,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
_lsa_lookup_sids
***************************************************************************/
-uint32 _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u)
+NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SIDS *r_u)
{
DOM_SID2 *sid = q_u->sids.sid;
int num_entries = q_u->sids.num_entries;
@@ -474,7 +501,7 @@ uint32 _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_SI
lsa_reply_lookup_names
***************************************************************************/
-uint32 _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
+NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
{
UNISTR2 *names = q_u->uni_name;
int num_entries = q_u->num_entries;
@@ -502,7 +529,7 @@ uint32 _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_N
_lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
***************************************************************************/
-uint32 _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
+NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
{
if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
@@ -515,12 +542,82 @@ uint32 _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
"No more secrets Marty...." :-).
***************************************************************************/
-uint32 _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
+NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
{
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
-uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
+/***************************************************************************
+_lsa_enum_privs.
+ ***************************************************************************/
+
+NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
+{
+ uint32 i;
+
+ uint32 enum_context=q_u->enum_context;
+ LSA_PRIV_ENTRY *entry;
+ LSA_PRIV_ENTRY *entries;
+
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if (enum_context >= PRIV_ALL_INDEX)
+ return NT_STATUS_UNABLE_TO_FREE_VM;
+
+ entries = (LSA_PRIV_ENTRY *)talloc_zero(p->mem_ctx, sizeof(LSA_PRIV_ENTRY) * (PRIV_ALL_INDEX-enum_context));
+ if (entries==NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ entry = entries;
+ for (i = 0; i < PRIV_ALL_INDEX-enum_context; i++, entry++) {
+ init_uni_hdr(&entry->hdr_name, strlen(privs[i+1-enum_context].priv));
+ init_unistr2(&entry->name, privs[i+1-enum_context].priv, strlen(privs[i+1-enum_context].priv) );
+ entry->luid_low = privs[i+1-enum_context].se_priv;
+ entry->luid_high = 1;
+ }
+
+ init_lsa_r_enum_privs(r_u, i+enum_context, PRIV_ALL_INDEX-enum_context, entries);
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
+_lsa_priv_get_dispname.
+ ***************************************************************************/
+
+NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
+{
+ fstring name_asc;
+ fstring desc_asc;
+ int i;
+
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
+
+ DEBUG(0,("_lsa_priv_get_dispname: %s", name_asc));
+
+ for (i=1; privs[i].se_priv!=SE_PRIV_ALL; i++) {
+ if ( strcmp(name_asc, privs[i].priv)) {
+
+ fstrcpy(desc_asc, privs[i].description);
+
+ }
+ }
+ DEBUG(0,(": %s\n", desc_asc));
+
+ init_uni_hdr(&r_u->hdr_desc, strlen(desc_asc));
+ init_unistr2(&r_u->desc, desc_asc, strlen(desc_asc) );
+
+ r_u->ptr_info=0xdeadbeef;
+ r_u->lang_id=q_u->lang_id;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
{
fstring username, domname;
int ulen, dlen;
@@ -549,3 +646,49 @@ uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R
return r_u->status;
}
+
+/***************************************************************************
+
+ ***************************************************************************/
+
+NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
+{
+ struct lsa_info *info;
+
+ r_u->status = NT_STATUS_OK;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* associate the user/group SID with the (unique) handle. */
+ if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ ZERO_STRUCTP(info);
+ info->sid = q_u->sid.sid;
+ info->access = q_u->access;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ return r_u->status;
+}
+
+/***************************************************************************
+
+ ***************************************************************************/
+
+NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
+{
+ r_u->status = NT_STATUS_OK;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
+
+ r_u->access=3;
+
+ return r_u->status;
+}
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index 4c13ad0c670..06e2f75ead4 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -26,8 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*************************************************************************
api_net_req_chal:
*************************************************************************/
@@ -282,6 +280,40 @@ static BOOL api_net_logon_ctrl2(pipes_struct *p)
return True;
}
+/*************************************************************************
+ api_net_logon_ctrl:
+ *************************************************************************/
+
+static BOOL api_net_logon_ctrl(pipes_struct *p)
+{
+ NET_Q_LOGON_CTRL q_u;
+ NET_R_LOGON_CTRL r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ DEBUG(6,("api_net_logon_ctrl: %d\n", __LINE__));
+
+ /* grab the lsa netlogon ctrl query... */
+ if(!net_io_q_logon_ctrl("", &q_u, data, 0)) {
+ DEBUG(0,("api_net_logon_ctrl: Failed to unmarshall NET_Q_LOGON_CTRL.\n"));
+ return False;
+ }
+
+ r_u.status = _net_logon_ctrl(p, &q_u, &r_u);
+
+ if(!net_io_r_logon_ctrl("", &r_u, rdata, 0)) {
+ DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
+ return False;
+ }
+
+ DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+
+ return True;
+}
+
/*******************************************************************
array of \PIPE\NETLOGON operations
********************************************************************/
@@ -295,6 +327,7 @@ static struct api_struct api_net_cmds [] =
{ "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
{ "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
{ "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
+ { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl },
{ NULL , 0 , NULL }
};
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index 62c49f5b89a..baec307b888 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -6,6 +6,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 1998-2001.
+ * Copyirht (C) Andrew Bartlett 2001.
*
* 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,8 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern BOOL sam_logon_in_ssb;
extern pstring samlogon_user;
extern pstring global_myname;
@@ -38,7 +37,7 @@ extern DOM_SID global_sam_sid;
*************************************************************************/
static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
- DOM_CHAL *srv_chal, int status)
+ DOM_CHAL *srv_chal, NTSTATUS status)
{
DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
@@ -53,20 +52,47 @@ static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
#define ERROR_NO_LOGON_SERVERS 0x51f
/*************************************************************************
+ net_reply_logon_ctrl:
+ *************************************************************************/
+
+/* Some flag values reverse engineered from NLTEST.EXE */
+
+#define LOGON_CTRL_IN_SYNC 0x00
+#define LOGON_CTRL_REPL_NEEDED 0x01
+#define LOGON_CTRL_REPL_IN_PROGRESS 0x02
+
+NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u,
+ NET_R_LOGON_CTRL *r_u)
+{
+ uint32 flags = 0x0;
+ uint32 pdc_connection_status = 0x00; /* Maybe a win32 error code? */
+
+ /* Setup the Logon Control response */
+
+ init_net_r_logon_ctrl(r_u, q_u->query_level, flags,
+ pdc_connection_status);
+
+ return r_u->status;
+}
+
+/*************************************************************************
net_reply_logon_ctrl2:
*************************************************************************/
-uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u)
+NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u)
{
- /* lkclXXXX - guess what - absolutely no idea what these are! */
- uint32 flags = 0x0;
- uint32 pdc_connection_status = 0x0;
- uint32 logon_attempts = 0x0;
- uint32 tc_status = ERROR_NO_LOGON_SERVERS;
- char *trusted_domain = "test_domain";
+ uint32 flags = 0x0;
+ uint32 pdc_connection_status = 0x0;
+ uint32 logon_attempts = 0x0;
+ uint32 tc_status = ERROR_NO_LOGON_SERVERS;
+ char *trusted_domain = "test_domain";
+
+ DEBUG(0, ("*** net long ctrl2 %d, %d, %d\n",
+ q_u->function_code, q_u->query_level, q_u->switch_value));
DEBUG(6,("_net_logon_ctrl2: %d\n", __LINE__));
+
/* set up the Logon Control2 response */
init_net_r_logon_ctrl2(r_u, q_u->query_level,
flags, pdc_connection_status, logon_attempts,
@@ -81,7 +107,7 @@ uint32 _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTR
net_reply_trust_dom_list:
*************************************************************************/
-uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u)
+NTSTATUS _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRUST_DOM_LIST *r_u)
{
char *trusted_domain = "test_domain";
uint32 num_trust_domains = 1;
@@ -101,7 +127,7 @@ uint32 _net_trust_dom_list(pipes_struct *p, NET_Q_TRUST_DOM_LIST *q_u, NET_R_TRU
***********************************************************************************/
static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
- DOM_CRED *srv_cred, int status)
+ DOM_CRED *srv_cred, NTSTATUS status)
{
DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
@@ -168,9 +194,9 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
_net_req_chal
*************************************************************************/
-uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
+NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
fstring mach_acct;
if (!get_valid_user_struct(p->vuid))
@@ -217,7 +243,7 @@ uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
init_net_r_auth:
*************************************************************************/
-static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status)
+static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS status)
{
memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
r_a->status = status;
@@ -227,9 +253,9 @@ static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status)
_net_auth
*************************************************************************/
-uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
+NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DOM_CHAL srv_cred;
UTIME srv_time;
@@ -262,7 +288,7 @@ uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
*************************************************************************/
static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
- DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
+ DOM_CHAL *resp_cred, NEG_FLAGS *flgs, NTSTATUS status)
{
memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
@@ -273,9 +299,9 @@ static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
_net_auth_2
*************************************************************************/
-uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
+NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DOM_CHAL srv_cred;
UTIME srv_time;
NEG_FLAGS srv_flgs;
@@ -310,9 +336,9 @@ uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
_net_srv_pwset
*************************************************************************/
-uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
+NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_WRONG_PASSWORD;
DOM_CRED srv_cred;
pstring mach_acct;
SAM_ACCOUNT *sampass=NULL;
@@ -336,6 +362,16 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+ /*
+ * Check the machine account name we're changing is the same
+ * as the one we've authenticated from. This prevents arbitrary
+ * machines changing other machine account passwords.
+ */
+
+ if (!strequal(mach_acct, p->dc.mach_acct)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
pdb_init_sam(&sampass);
become_root();
@@ -349,19 +385,6 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
return NT_STATUS_NO_SUCH_USER;
}
-
- /*
- * Check the machine account name we're changing is the same
- * as the one we've authenticated from. This prevents arbitrary
- * machines changing other machine account passwords.
- */
-
- if (!strequal(mach_acct, p->dc.mach_acct)) {
- pdb_free_sam(sampass);
- return NT_STATUS_ACCESS_DENIED;
- }
-
-
DEBUG(100,("Server password set : new given value was :\n"));
for(i = 0; i < 16; i++)
DEBUG(100,("%02X ", q_u->pwd[i]));
@@ -399,7 +422,7 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
_net_sam_logoff:
*************************************************************************/
-uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u)
+NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u)
{
DOM_CRED srv_cred;
@@ -426,7 +449,7 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
net_login_interactive:
*************************************************************************/
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
+static NTSTATUS net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
{
uint8 *stored_nt_pwd, *stored_lanman_pwd;
char nt_pwd[16];
@@ -493,7 +516,7 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pi
_net_login_network:
*************************************************************************/
-static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
+static NTSTATUS net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
{
uint8 *nt_pwd, *lanman_pwd;
@@ -539,9 +562,9 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
_net_sam_logon
*************************************************************************/
-uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
+NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
NET_USER_INFO_3 *usr_info = NULL;
DOM_CRED srv_cred;
SAM_ACCOUNT *sampass = NULL;
@@ -610,8 +633,11 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
unbecome_root();
if (!ret)
+ {
+ pdb_free_sam(sampass);
return NT_STATUS_NO_SUCH_USER;
-
+ }
+
acct_ctrl = pdb_get_acct_ctrl(sampass);
/* Validate password - if required. */
@@ -629,19 +655,25 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
}
}
- if (status != NT_STATUS_OK)
+ if (!NT_STATUS_IS_OK(status)) {
+ pdb_free_sam(sampass);
return status;
+ }
#ifdef WITH_PAM
become_root();
status = smb_pam_accountcheck(pdb_get_username(sampass));
unbecome_root();
- if (status != NT_STATUS_OK)
+ if (!NT_STATUS_IS_OK(status)) {
+ pdb_free_sam(sampass);
return status;
+ }
#endif
- if (acct_ctrl & ACB_DISABLED)
+ if (acct_ctrl & ACB_DISABLED) {
+ pdb_free_sam(sampass);
return NT_STATUS_ACCOUNT_DISABLED;
+ }
/* lkclXXXX this is the point at which, if the login was
successful, that the SAM Local Security Authority should
@@ -690,7 +722,8 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
&global_sam_sid, /* DOM_SID *dom_sid */
NULL); /* char *other_sids */
- }
+ }
- return status;
+ pdb_free_sam(sampass);
+ return status;
}
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index 174a21a4c50..73f8fe45d6c 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -40,8 +40,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
unsigned char *hash = p->ntlmssp_hash;
@@ -93,7 +91,7 @@ BOOL create_next_pdu(pipes_struct *p)
*/
if(p->fault_state) {
- setup_fault_pdu(p, 0x1c010002);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
return True;
}
@@ -382,20 +380,20 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
unbecome_root();
- /* Quit if the account was disabled. */
- if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) {
+ /* Quit if the account was disabled. */
+ if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) {
DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name));
pdb_free_sam(sampass);
return False;
- }
+ }
if(!pdb_get_nt_passwd(sampass)) {
DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name));
pdb_free_sam(sampass);
return False;
- }
+ }
- smb_passwd_ptr = pdb_get_lanman_passwd(sampass);
+ smb_passwd_ptr = pdb_get_lanman_passwd(sampass);
}
/*
@@ -456,9 +454,10 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
/* 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,
- guest_user);
+ guest_user, NULL);
p->ntlmssp_auth_validated = True;
+ pdb_free_sam(sampass);
return True;
}
@@ -615,7 +614,7 @@ static BOOL setup_bind_nak(pipes_struct *p)
Marshall a fault pdu.
*******************************************************************/
-BOOL setup_fault_pdu(pipes_struct *p, uint32 status)
+BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
{
prs_struct outgoing_pdu;
RPC_HDR fault_hdr;
@@ -1134,7 +1133,6 @@ BOOL api_pipe_request(pipes_struct *p)
{
int i = 0;
BOOL ret = False;
- BOOL changed_user_id = False;
if (p->ntlmssp_auth_validated) {
@@ -1142,8 +1140,6 @@ BOOL api_pipe_request(pipes_struct *p)
prs_mem_free(&p->out_data.rdata);
return False;
}
-
- changed_user_id = True;
}
for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
@@ -1156,8 +1152,8 @@ BOOL api_pipe_request(pipes_struct *p)
}
}
- if(changed_user_id)
- unbecome_authenticated_pipe_user(p);
+ if (p->ntlmssp_auth_validated)
+ unbecome_authenticated_pipe_user();
return ret;
}
@@ -1181,7 +1177,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
- DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));
+ DEBUG(3,("api_rpcTNP: pipe %u rpc command: %s\n", (unsigned int)p->pnum, api_rpc_cmds[fn_num].name));
break;
}
}
@@ -1193,7 +1189,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
* and not put the pipe into fault state. JRA.
*/
DEBUG(4, ("unknown\n"));
- setup_fault_pdu(p, 0x1c010002);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
return True;
}
@@ -1206,6 +1202,13 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
return False;
}
+ if (p->bad_handle_fault_state) {
+ DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
+ p->bad_handle_fault_state = False;
+ setup_fault_pdu(p, NT_STATUS(0x1C00001A));
+ return True;
+ }
+
slprintf(name, sizeof(name)-1, "out_%s", rpc_name);
offset2 = prs_offset(&p->out_data.rdata);
prs_set_offset(&p->out_data.rdata, offset1);
@@ -1228,7 +1231,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name,
if (data) {
prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data,
data_len);
- free(data);
+ SAFE_FREE(data);
}
}
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index c9fb06da4db..65725bc2baa 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -28,14 +28,25 @@
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
-extern int DEBUGLEVEL;
static pipes_struct *chain_p;
static int pipes_open;
#ifndef MAX_OPEN_PIPES
-#define MAX_OPEN_PIPES 64
+#define MAX_OPEN_PIPES 2048
#endif
+/*
+ * Sometimes I can't decide if I hate Windows printer driver
+ * writers more than I hate the Windows spooler service driver
+ * writers. This gets around a combination of bugs in the spooler
+ * and the HP 8500 PCL driver that causes a spooler spin. JRA.
+ */
+
+#ifndef MAX_OPEN_SPOOLSS_PIPES
+#define MAX_OPEN_SPOOLSS_PIPES 20
+#endif
+static int current_spoolss_pipes_open;
+
static pipes_struct *Pipes;
static struct bitmap *bmap;
@@ -84,7 +95,7 @@ void init_rpc_pipe_hnd(void)
{
bmap = bitmap_allocate(MAX_OPEN_PIPES);
if (!bmap)
- exit_server("out of memory in init_rpc_pipe_hnd\n");
+ exit_server("out of memory in init_rpc_pipe_hnd");
}
/****************************************************************************
@@ -127,11 +138,20 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
int i;
pipes_struct *p;
static int next_pipe;
+ BOOL is_spoolss_pipe = False;
DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
pipe_name, pipes_open));
-
+ if (strstr(pipe_name, "spoolss"))
+ is_spoolss_pipe = True;
+
+ if (is_spoolss_pipe && current_spoolss_pipes_open >= MAX_OPEN_SPOOLSS_PIPES) {
+ DEBUG(10,("open_rpc_pipe_p: spooler bug workaround. Denying open on pipe %s\n",
+ pipe_name ));
+ return NULL;
+ }
+
/* not repeating pipe numbers makes it easier to track things in
log files and prevents client bugs where pipe numbers are reused
over connection restarts */
@@ -159,14 +179,14 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
if ((p->mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
- free(p);
+ SAFE_FREE(p);
return NULL;
}
if (!init_pipe_handle_list(p, pipe_name)) {
DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
talloc_destroy(p->mem_ctx);
- free(p);
+ SAFE_FREE(p);
return NULL;
}
@@ -244,6 +264,9 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
for (p = Pipes; p; p = p->next)
DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+ if (is_spoolss_pipe)
+ current_spoolss_pipes_open++;
+
return chain_p;
}
@@ -475,9 +498,12 @@ authentication failed. Denying the request.\n", p->name));
/*
* Check the data length doesn't go over the 10Mb limit.
+ * increased after observing a bug in the Windows NT 4.0 SP6a
+ * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
+ * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
*/
- if(prs_data_size(&p->in_data.data) + data_len > 10*1024*1024) {
+ if(prs_data_size(&p->in_data.data) + data_len > 15*1024*1024) {
DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
(unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
set_incoming_fault(p);
@@ -570,7 +596,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
p->name ));
set_incoming_fault(p);
- setup_fault_pdu(p, 0x1c010002);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
return (ssize_t)data_len;
}
@@ -619,7 +645,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
if (!reply) {
DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
set_incoming_fault(p);
- setup_fault_pdu(p, 0x1c010002);
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
prs_mem_free(&rpc_in);
} else {
/*
@@ -904,6 +930,9 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
return False;
}
+ if (strstr(p->name, "spoolss"))
+ current_spoolss_pipes_open--;
+
prs_mem_free(&p->out_data.rdata);
prs_mem_free(&p->in_data.data);
@@ -927,7 +956,7 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
ZERO_STRUCTP(p);
- free(p);
+ SAFE_FREE(p);
return True;
}
diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c
index 2a0e2d172ce..d9fa93206ac 100644
--- a/source/rpc_server/srv_reg.c
+++ b/source/rpc_server/srv_reg.c
@@ -27,8 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
api_reg_close
********************************************************************/
@@ -134,6 +132,59 @@ static BOOL api_reg_info(pipes_struct *p)
return True;
}
+#if 0
+/*******************************************************************
+ api_reg_shutdown
+ ********************************************************************/
+
+static BOOL api_reg_shutdown(pipes_struct *p)
+{
+ REG_Q_SHUTDOWN q_u;
+ REG_R_SHUTDOWN r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg shutdown */
+ if(!reg_io_q_shutdown("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_shutdown(p, &q_u, &r_u);
+
+ if(!reg_io_r_shutdown("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ api_reg_abort_shutdown
+ ********************************************************************/
+
+static BOOL api_reg_abort_shutdown(pipes_struct *p)
+{
+ REG_Q_ABORT_SHUTDOWN q_u;
+ REG_R_ABORT_SHUTDOWN r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg shutdown */
+ if(!reg_io_q_abort_shutdown("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_abort_shutdown(p, &q_u, &r_u);
+
+ if(!reg_io_r_abort_shutdown("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+#endif
/*******************************************************************
array of \PIPE\reg operations
@@ -144,6 +195,10 @@ static struct api_struct api_reg_cmds[] =
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
{ "REG_OPEN" , REG_OPEN_HKLM , api_reg_open },
{ "REG_INFO" , REG_INFO , api_reg_info },
+#if 0
+ { "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },
+ { "REG_ABORT_SHUTDOWN", REG_ABORT_SHUTDOWN, api_reg_abort_shutdown },
+#endif
{ NULL, 0 , NULL }
};
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index c3b4a1a7a5d..5ba1b9b0087 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -27,26 +27,24 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
struct reg_info
{
- /* for use by \PIPE\winreg */
- fstring name; /* name of registry key */
+ /* for use by \PIPE\winreg */
+ fstring name; /* name of registry key */
};
static void free_reg_info(void *ptr)
{
struct reg_info *info = (struct reg_info *)ptr;
- safe_free(info);
+ SAFE_FREE(info);
}
/*******************************************************************
reg_reply_unknown_1
********************************************************************/
-uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
+NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
{
/* set up the REG unknown_1 response */
ZERO_STRUCT(r_u->pol);
@@ -62,7 +60,7 @@ uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
reg_reply_open
********************************************************************/
-uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
+NTSTATUS _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
{
if (!create_policy_hnd(p, &r_u->pol, free_reg_info, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -74,7 +72,7 @@ uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
reg_reply_open_entry
********************************************************************/
-uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
+NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
{
POLICY_HND pol;
fstring name;
@@ -114,9 +112,9 @@ uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
reg_reply_info
********************************************************************/
-uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
+NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
char *key = NULL;
uint32 type=0x1; /* key type: REG_SZ */
@@ -126,7 +124,7 @@ uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
DEBUG(5,("_reg_info: %d\n", __LINE__));
- if (find_policy_by_hnd(p, &q_u->pol, NULL) == -1)
+ if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
fstrcpy(name, dos_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len));
@@ -141,7 +139,7 @@ uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
if ( strequal(name, "RefusePasswordChange") ) {
type=0xF770;
- status = ERRbadfile;
+ status = NT_STATUS_NO_SUCH_FILE;
init_unistr2(uni_key, "", 0);
init_buffer2(buf, (uint8*) uni_key->buffer, uni_key->uni_str_len*2);
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index cd1cc6926fc..0d2e4a81e66 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -32,8 +32,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
api_samr_close_hnd
********************************************************************/
@@ -672,7 +670,7 @@ static BOOL api_samr_set_userinfo(pipes_struct *p)
DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
/* Fix for W2K SP2 */
if (q_u.switch_value == 0x1a) {
- setup_fault_pdu(p, 0x1c000006);
+ setup_fault_pdu(p, NT_STATUS(0x1c000006));
return True;
}
return False;
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 9c2f37d4ce0..2f1f6bce8c2 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -6,7 +6,8 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Marc Jacobsen 1999.
- * Copyright (C) Jeremy Allison 2001.
+ * Copyright (C) Jeremy Allison 2001-2002.
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,445 +30,356 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern fstring global_myworkgroup;
extern pstring global_myname;
extern DOM_SID global_sam_sid;
+extern DOM_SID global_sid_Builtin;
extern rid_name domain_group_rids[];
extern rid_name domain_alias_rids[];
extern rid_name builtin_alias_rids[];
+typedef struct _disp_info {
+ BOOL user_dbloaded;
+ uint32 num_user_account;
+ DISP_USER_INFO *disp_user_info;
+ BOOL group_dbloaded;
+ uint32 num_group_account;
+ DISP_GROUP_INFO *disp_group_info;
+} DISP_INFO;
+
struct samr_info {
- /* for use by the \PIPE\samr policy */
- DOM_SID sid;
- uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
+ /* for use by the \PIPE\samr policy */
+ DOM_SID sid;
+ uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
+ DISP_INFO disp_info;
};
/*******************************************************************
- Function to free the per handle data.
+ Create a samr_info struct.
********************************************************************/
-static void free_samr_info(void *ptr)
+static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
{
- struct samr_info *samr = (struct samr_info *)ptr;
+ struct samr_info *info;
+ fstring sid_str;
- safe_free(samr);
+ if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ return NULL;
+
+ ZERO_STRUCTP(info);
+ if (psid) {
+ DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_to_string(sid_str, psid) ));
+ sid_copy( &info->sid, psid);
+ } else {
+ DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
+ }
+ return info;
}
/*******************************************************************
- This next function should be replaced with something that
- dynamically returns the correct user info..... JRA.
+ Function to free the per handle data.
********************************************************************/
-static uint32 get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
- int *total_entries, int *num_entries,
- int max_num_entries, uint16 acb_mask)
+static void free_samr_db(struct samr_info *info)
{
- SAM_ACCOUNT *pwd = NULL;
- BOOL not_finished = True;
+ int i;
- (*num_entries) = 0;
- (*total_entries) = 0;
+ if (info->disp_info.group_dbloaded) {
+ for (i=0; i<info->disp_info.num_group_account; i++)
+ SAFE_FREE(info->disp_info.disp_group_info[i].grp);
- if (pw_buf == NULL)
- return NT_STATUS_NO_MEMORY;
+ SAFE_FREE(info->disp_info.disp_group_info);
+ }
- pdb_init_sam(&pwd);
+ if (info->disp_info.user_dbloaded){
+ for (i=0; i<info->disp_info.num_user_account; i++)
+ pdb_free_sam(info->disp_info.disp_user_info[i].sam);
- if (!pdb_setsampwent(False)) {
- DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
- pdb_free_sam(pwd);
- return NT_STATUS_ACCESS_DENIED;
+ SAFE_FREE(info->disp_info.disp_user_info);
}
- while (((not_finished = pdb_getsampwent(pwd)) != False)
- && (*num_entries) < max_num_entries)
- {
- int user_name_len;
+ info->disp_info.user_dbloaded=False;
+ info->disp_info.group_dbloaded=False;
+ info->disp_info.num_group_account=0;
+ info->disp_info.num_user_account=0;
+}
- if (start_idx > 0) {
- /* skip the requested number of entries.
- not very efficient, but hey... */
- pdb_reset_sam(pwd);
- start_idx--;
- continue;
- }
+/*******************************************************************
+ Function to free the per handle data.
+ ********************************************************************/
- user_name_len = strlen(pdb_get_username(pwd))+1;
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
- pw_buf[(*num_entries)].user_rid = pwd->user_rid;
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+static void free_samr_info(void *ptr)
+{
+ struct samr_info *info=(struct samr_info *) ptr;
- /* Now check if the NT compatible password is available. */
- if (pdb_get_nt_passwd(pwd))
- memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
+ free_samr_db(info);
+ SAFE_FREE(info);
+}
- pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
+/*******************************************************************
+ Ensure password info is never given out. Paranioa... JRA.
+ ********************************************************************/
- DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
- (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
+static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
+{
+ int i;
- if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
- DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
- (*num_entries)++;
- } else
- DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ if (!pass)
+ return;
- (*total_entries)++;
- pdb_reset_sam(pwd);
+ for (i = 0; i < num_entries; i++) {
+ memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
+ memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
}
+}
- pdb_endsampwent();
- pdb_free_sam(pwd);
+static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
+{
+ if (!sam_pass)
+ return;
- if (not_finished)
- return STATUS_MORE_ENTRIES;
- else
- return NT_STATUS_OK;
+ if (sam_pass->lm_pw)
+ memset(sam_pass->lm_pw, '\0', 16);
+ if (sam_pass->nt_pw)
+ memset(sam_pass->nt_pw, '\0', 16);
}
-static uint32 jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
- int *total_entries, uint32 *num_entries,
- int max_num_entries, uint16 acb_mask)
+static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask)
{
SAM_ACCOUNT *pwd = NULL;
- BOOL not_finished = True;
+ DISP_USER_INFO *pwd_array = NULL;
- *num_entries = 0;
- *total_entries = 0;
+ DEBUG(10,("load_sampwd_entries\n"));
- if (pw_buf == NULL)
- return NT_STATUS_NO_MEMORY;
-
- DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
- start_idx, max_num_entries, acb_mask));
+ /* if the snapshoot is already loaded, return */
+ if (info->disp_info.user_dbloaded==True) {
+ DEBUG(10,("load_sampwd_entries: already in memory\n"));
+ return NT_STATUS_OK;
+ }
if (!pdb_setsampwent(False)) {
- DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
+ DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
return NT_STATUS_ACCESS_DENIED;
}
- pdb_init_sam(&pwd);
-
- while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
- int user_name_len;
- int full_name_len;
-
- if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
- pdb_reset_sam(pwd);
- continue;
- }
-
- if (start_idx > 0) {
- /* skip the requested number of entries.
- not very efficient, but hey...
- */
- start_idx--;
- pdb_reset_sam(pwd);
+ for (pdb_init_sam(&pwd); pdb_getsampwent(pwd) == True; pwd=NULL, pdb_init_sam(&pwd) ) {
+
+ if (acb_mask != 0 && !(pwd->acct_ctrl & acb_mask)) {
+ pdb_free_sam(pwd);
+ DEBUG(5,(" acb_mask %x reject\n", acb_mask));
continue;
}
- ZERO_STRUCTP(&pw_buf[(*num_entries)]);
-
- user_name_len = strlen(pdb_get_username(pwd));
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
-
- full_name_len = strlen(pdb_get_fullname(pwd));
- init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
-
- pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+ /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
+ if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
+
+ DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
+ pwd_array=(DISP_USER_INFO *)Realloc(info->disp_info.disp_user_info,
+ (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(DISP_USER_INFO));
- /* Now check if the NT compatible password is available. */
- if (pdb_get_nt_passwd(pwd))
- memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
+ if (pwd_array==NULL)
+ return NT_STATUS_NO_MEMORY;
- pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
+ info->disp_info.disp_user_info=pwd_array;
+ }
+
+ /* link the SAM_ACCOUNT to the array */
+ info->disp_info.disp_user_info[info->disp_info.num_user_account].sam=pwd;
- DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
- pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
+ DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
- (*num_entries)++;
-
- pdb_reset_sam(pwd);
+ info->disp_info.num_user_account++;
}
pdb_endsampwent();
- *total_entries = *num_entries;
-
- pdb_free_sam(pwd);
+ /* the snapshoot is in memory, we're ready to enumerate fast */
- if (not_finished)
- return STATUS_MORE_ENTRIES;
- else
- return NT_STATUS_OK;
+ info->disp_info.user_dbloaded=True;
+
+ DEBUG(12,("load_sampwd_entries: done\n"));
+
+ return NT_STATUS_OK;
}
/*
- * These next two functions are not used. Tagged
- * for deletion
+ * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
+ * Return a malloced map so we can free it.
*/
-#if 0
-/*******************************************************************
- This function uses the username map file and tries to map a UNIX
- user name to an DOS name. (Sort of the reverse of the
- map_username() function.) Since more than one DOS name can map
- to the UNIX name, to reverse the mapping you have to specify
- which corresponding DOS name you want; that's where the name_idx
- parameter comes in. Returns the string requested or NULL if it
- fails or can't complete the request for any reason. This doesn't
- handle group names (starting with '@') or names starting with
- '+' or '&'. If they are encountered, they are skipped.
-********************************************************************/
-
-static char *unmap_unixname(char *unix_user_name, int name_idx)
+static int setup_fake_group_map(GROUP_MAP **ret_map)
{
- char *mapfile = lp_username_map();
- char **lines;
- static pstring tok;
- int i;
-
- if (!*unix_user_name) return NULL;
- if (!*mapfile) return NULL;
+ static GROUP_MAP static_map[2];
+ static BOOL group_map_init;
+ extern DOM_SID global_sam_sid;
- lines = file_lines_load(mapfile, NULL,False);
- if (!lines) {
- DEBUG(0,("unmap_unixname: can't open username map %s\n", mapfile));
- return NULL;
+ *ret_map = (GROUP_MAP *)malloc(sizeof(GROUP_MAP)*2);
+ if (!ret_map)
+ return 2;
+
+ if (group_map_init) {
+ memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
+ return sizeof(static_map)/sizeof(GROUP_MAP);
}
- DEBUG(5,("unmap_unixname: scanning username map %s, index: %d\n", mapfile, name_idx));
-
- for (i=0; lines[i]; i++) {
- char *unixname = lines[i];
- char *dosname = strchr(unixname,'=');
-
- if (!dosname)
- continue;
-
- *dosname++ = 0;
-
- while (isspace(*unixname))
- unixname++;
- if ('!' == *unixname) {
- unixname++;
- while (*unixname && isspace(*unixname))
- unixname++;
- }
-
- if (!*unixname || strchr("#;",*unixname))
- continue;
-
- if (strncmp(unixname, unix_user_name, strlen(unix_user_name)))
- continue;
+ group_map_init = True;
- /* We have matched the UNIX user name */
-
- while(next_token(&dosname, tok, LIST_SEP, sizeof(tok))) {
- if (!strchr("@&+", *tok)) {
- name_idx--;
- if (name_idx < 0 ) {
- break;
- }
- }
- }
+ static_map[0].gid = (gid_t)-1;
+ sid_copy(&static_map[0].sid, &global_sam_sid);
+ sid_append_rid(&static_map[1].sid, DOMAIN_GROUP_RID_ADMINS);
+ static_map[0].sid_name_use = SID_NAME_DOM_GRP;
+ fstrcpy(static_map[0].nt_name, "Domain Admins");
+ fstrcpy(static_map[0].comment, "Administrators for the domain");
+ static_map[0].privilege = 0;
- if (name_idx >= 0) {
- DEBUG(0,("unmap_unixname: index too high - not that many DOS names\n"));
- file_lines_free(lines);
- return NULL;
- } else {
- file_lines_free(lines);
- return tok;
- }
- }
+ static_map[1].gid = (gid_t)-1;
+ sid_copy(&static_map[1].sid, &global_sam_sid);
+ sid_append_rid(&static_map[1].sid, DOMAIN_GROUP_RID_USERS);
+ static_map[1].sid_name_use = SID_NAME_DOM_GRP;
+ fstrcpy(static_map[1].nt_name, "Domain Users");
+ fstrcpy(static_map[1].comment, "Users in the domain");
+ static_map[1].privilege = 0;
- DEBUG(0,("unmap_unixname: Couldn't find the UNIX user name\n"));
- file_lines_free(lines);
- return NULL;
+ memcpy( *ret_map, &static_map[0], sizeof(GROUP_MAP)*2);
+ return sizeof(static_map)/sizeof(GROUP_MAP);
}
-/*******************************************************************
- This function sets up a list of users taken from the list of
- users that UNIX knows about, as well as all the user names that
- Samba maps to a valid UNIX user name. (This should work with
- /etc/passwd or NIS.)
-********************************************************************/
-
-static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
- int start_idx,
- int *total_entries, int *num_entries,
- int max_num_entries,
- uint16 acb_mask)
+static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
{
- static struct passwd *pwd = NULL;
- static uint32 pw_rid;
- static BOOL orig_done = False;
- static int current_idx = 0;
- static int mapped_idx = 0;
- char *sep;
-
- DEBUG(5, ("get_passwd_entries: retrieving a list of UNIX users\n"));
-
- (*num_entries) = 0;
- (*total_entries) = 0;
-
- /* Skip all this stuff if we're in appliance mode */
-
- if (lp_hide_local_users()) goto done;
+ GROUP_MAP *map;
+ DISP_GROUP_INFO *grp_array = NULL;
+ uint32 group_entries = 0;
+ uint32 i;
- if (pw_buf == NULL) return False;
+ DEBUG(10,("load_group_domain_entries\n"));
- if (current_idx == 0) {
- sys_setpwent();
+ /* if the snapshoot is already loaded, return */
+ if (info->disp_info.group_dbloaded==True) {
+ DEBUG(10,("load_group_domain_entries: already in memory\n"));
+ return NT_STATUS_OK;
}
- /* These two cases are inefficient, but should be called very rarely */
- /* they are the cases where the starting index isn't picking up */
- /* where we left off last time. It is efficient when it starts over */
- /* at zero though. */
- if (start_idx > current_idx) {
- /* We aren't far enough; advance to start_idx */
- while (current_idx <= start_idx) {
- char *unmap_name;
+ /*
+ * This is a really ugly hack to make this interface work in the 2.2.x code. JRA.
+ */
- if(!orig_done) {
- if ((pwd = sys_getpwent()) == NULL) break;
- current_idx++;
- orig_done = True;
- }
+ group_entries = setup_fake_group_map(&map);
- while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
- (current_idx < start_idx)) {
- current_idx++;
- mapped_idx++;
- }
-
- if (unmap_name == NULL) {
- orig_done = False;
- mapped_idx = 0;
- }
- }
- } else if (start_idx < current_idx) {
- /* We are already too far; start over and advance to start_idx */
- sys_endpwent();
- sys_setpwent();
- current_idx = 0;
- mapped_idx = 0;
- orig_done = False;
- while (current_idx < start_idx) {
- char *unmap_name;
-
- if(!orig_done) {
- if ((pwd = sys_getpwent()) == NULL) break;
- current_idx++;
- orig_done = True;
- }
+ info->disp_info.num_group_account=group_entries;
- while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
- (current_idx < start_idx)) {
- current_idx++;
- mapped_idx++;
- }
+ grp_array=(DISP_GROUP_INFO *)malloc(info->disp_info.num_group_account*sizeof(DISP_GROUP_INFO));
- if (unmap_name == NULL) {
- orig_done = False;
- mapped_idx = 0;
- }
- }
+ if (group_entries!=0 && grp_array==NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- sep = lp_winbind_separator();
+ info->disp_info.disp_group_info=grp_array;
+
+ for (i=0; i<group_entries; i++) {
+
+ grp_array[i].grp=(DOMAIN_GRP *)malloc(sizeof(DOMAIN_GRP));
+
+ fstrcpy(grp_array[i].grp->name, map[i].nt_name);
+ fstrcpy(grp_array[i].grp->comment, map[i].comment);
+ sid_split_rid(&map[i].sid, &grp_array[i].grp->rid);
+ grp_array[i].grp->attr=SID_NAME_DOM_GRP;
+ }
- /* now current_idx == start_idx */
- while ((*num_entries) < max_num_entries) {
- int user_name_len;
- char *unmap_name;
+ SAFE_FREE(map);
- /* This does the original UNIX user itself */
- if(!orig_done) {
- if ((pwd = sys_getpwent()) == NULL) break;
+ /* the snapshoot is in memory, we're ready to enumerate fast */
- /* Don't enumerate winbind users as they are not local */
+ info->disp_info.group_dbloaded=True;
- if (strchr(pwd->pw_name, *sep) != NULL) {
- continue;
- }
+ DEBUG(12,("load_group_domain_entries: done\n"));
- user_name_len = strlen(pwd->pw_name);
-
- /* skip the trust account stored in the /etc/passwd file */
- if (pwd->pw_name[user_name_len-1]=='$')
- continue;
-
- pw_rid = pdb_uid_to_user_rid(pwd->pw_uid);
- ZERO_STRUCTP(&pw_buf[(*num_entries)]);
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->pw_name, user_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
- pw_buf[(*num_entries)].user_rid = pw_rid;
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+ return NT_STATUS_OK;
+}
- pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
+/*******************************************************************
+ This next function should be replaced with something that
+ dynamically returns the correct user info..... JRA.
+ ********************************************************************/
- DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
+static NTSTATUS get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
+ int *total_entries, int *num_entries,
+ int max_num_entries, uint16 acb_mask)
+{
+ SAM_ACCOUNT *pwd = NULL;
+ BOOL not_finished = True;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
- (*num_entries)++;
- (*total_entries)++;
- current_idx++;
- orig_done = True;
- }
+ if (pw_buf == NULL)
+ return NT_STATUS_NO_MEMORY;
- /* This does all the user names that map to the UNIX user */
- while (((unmap_name = unmap_unixname(pwd->pw_name, mapped_idx)) != NULL) &&
- (*num_entries < max_num_entries)) {
- user_name_len = strlen(unmap_name);
- ZERO_STRUCTP(&pw_buf[(*num_entries)]);
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, unmap_name, user_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
- pw_buf[(*num_entries)].user_rid = pw_rid;
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+ pdb_init_sam(&pwd);
- pw_buf[(*num_entries)].acb_info = ACB_NORMAL;
+ if (!pdb_setsampwent(False)) {
+ DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
+ pdb_free_sam(pwd);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ while (((not_finished = pdb_getsampwent(pwd)) != False)
+ && (*num_entries) < max_num_entries)
+ {
+ int user_name_len;
+
+ if (start_idx > 0) {
- DEBUG(5, ("get_passwd_entries: entry idx %d user %s, rid 0x%x\n", (*num_entries), pwd->pw_name, pw_rid));
+ pdb_reset_sam(pwd);
+ /* skip the requested number of entries.
+ not very efficient, but hey... */
+ start_idx--;
+ continue;
+ }
+
+ user_name_len = strlen(pdb_get_username(pwd))+1;
+ init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
+ init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
+ pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+
+ /* Now check if the NT compatible password is available. */
+ if (pdb_get_nt_passwd(pwd))
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
+
+ pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
+
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
+ (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
+
+ if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
(*num_entries)++;
- (*total_entries)++;
- current_idx++;
- mapped_idx++;
+ } else {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
}
- if (unmap_name == NULL) {
- /* done with 'aliases', go on to next UNIX user */
- orig_done = False;
- mapped_idx = 0;
- }
- }
+ (*total_entries)++;
+
+ pdb_reset_sam(pwd);
- if (pwd == NULL) {
- /* totally done, reset everything */
- sys_endpwent();
- current_idx = 0;
- mapped_idx = 0;
}
+
+ pdb_endsampwent();
+ pdb_free_sam(pwd);
-done:
- return (*num_entries) > 0;
+ if (not_finished)
+ return STATUS_MORE_ENTRIES;
+ else
+ return NT_STATUS_OK;
}
-#endif
/*******************************************************************
_samr_close_hnd
********************************************************************/
-uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
+NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
{
r_u->status = NT_STATUS_OK;
@@ -484,7 +396,7 @@ uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND
samr_reply_open_domain
********************************************************************/
-uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
+NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
{
struct samr_info *info;
@@ -495,12 +407,9 @@ uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_D
return NT_STATUS_INVALID_HANDLE;
/* associate the domain SID with the (unique) handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->sid = q_u->dom_sid.sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -513,8 +422,8 @@ uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_D
static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
{
if (!info) {
- DEBUG(3,("Error getting policy\n"));
- return 0xffffffff;
+ DEBUG(3,("Error getting policy\n"));
+ return 0xffffffff;
}
return info->sid.sub_auths[info->sid.num_auths-1];
@@ -524,7 +433,7 @@ static uint32 get_lsa_policy_samr_rid(struct samr_info *info)
_samr_get_usrdom_pwinfo
********************************************************************/
-uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
+NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
{
struct samr_info *info = NULL;
@@ -551,7 +460,7 @@ uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, S
samr_make_usr_obj_sd
********************************************************************/
-static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
+static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID *usr_sid)
{
extern DOM_SID global_sid_Builtin;
extern DOM_SID global_sid_World;
@@ -612,7 +521,7 @@ static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *s
_samr_query_sec_obj
********************************************************************/
-uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
+NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
{
DOM_SID pol_sid;
@@ -625,7 +534,7 @@ uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QU
r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
- if (r_u->status == NT_STATUS_OK)
+ if (NT_STATUS_IS_OK(r_u->status))
r_u->ptr = 1;
return r_u->status;
@@ -669,36 +578,10 @@ static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR
}
/*******************************************************************
- Ensure password info is never given out. Paranioa... JRA.
- ********************************************************************/
-
-static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
-{
- int i;
-
- if (!pass)
- return;
-
- for (i = 0; i < num_entries; i++) {
- memset(&pass[i].lm_pwd, '\0', sizeof(pass[i].lm_pwd));
- memset(&pass[i].nt_pwd, '\0', sizeof(pass[i].nt_pwd));
- }
-}
-
-static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
-{
- if (!sam_pass)
- return;
-
- if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
- if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
-}
-
-/*******************************************************************
samr_reply_enum_dom_users
********************************************************************/
-uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
+NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ENUM_DOM_USERS *r_u)
{
SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
int num_entries = 0;
@@ -717,7 +600,7 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_
MAX_SAM_ENTRIES, q_u->acb_mask);
unbecome_root();
- if (r_u->status != NT_STATUS_OK && r_u->status != STATUS_MORE_ENTRIES)
+ if (NT_STATUS_IS_ERR(r_u->status))
return r_u->status;
samr_clear_passwd_fields(pass, num_entries);
@@ -788,7 +671,7 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
Get the group entries - similar to get_sampwd_entries().
********************************************************************/
-static uint32 get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
+static NTSTATUS get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
uint32 *p_num_entries, uint32 max_entries)
{
fstring sid_str;
@@ -889,7 +772,7 @@ static uint32 get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 st
Get the group entries - similar to get_sampwd_entries().
********************************************************************/
-static uint32 get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
+static NTSTATUS get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
uint32 *p_num_entries, uint32 max_entries)
{
fstring sid_str;
@@ -926,7 +809,7 @@ static uint32 get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 s
a real PDC. JRA.
********************************************************************/
-uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
+NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
{
DOMAIN_GRP grp[2];
uint32 num_entries;
@@ -955,7 +838,7 @@ uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_
samr_reply_enum_dom_aliases
********************************************************************/
-uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
+NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
{
DOMAIN_GRP grp[MAX_SAM_ENTRIES];
uint32 num_entries = 0;
@@ -972,8 +855,7 @@ uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAM
r_u->status = get_group_alias_entries(grp, &sid, q_u->start_idx,
&num_entries, MAX_SAM_ENTRIES);
-
- if (r_u->status != NT_STATUS_OK && r_u->status != STATUS_MORE_ENTRIES)
+ if (NT_STATUS_IS_ERR(r_u->status))
return r_u->status;
make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
@@ -988,90 +870,119 @@ uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAM
/*******************************************************************
samr_reply_query_dispinfo
********************************************************************/
-
-uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
+NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_QUERY_DISPINFO *r_u)
{
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- DOMAIN_GRP grps[MAX_SAM_ENTRIES];
- uint16 acb_mask = ACB_NORMAL;
- uint32 num_entries = 0;
- int orig_num_entries = 0;
- int total_entries = 0;
- uint32 data_size = 0;
- DOM_SID sid;
- uint32 disp_ret;
+ 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;
+ uint32 max_size=q_u->max_size;
+
SAM_DISPINFO_CTR *ctr;
+ uint32 temp_size=0, total_data_size=0;
+ NTSTATUS disp_ret;
+ uint32 num_account = 0;
+ enum remote_arch_types ra_type = get_remote_arch();
+ int max_sam_entries;
- DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
+ max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
+ DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
r_u->status = NT_STATUS_OK;
- if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
+ /* find the policy handle. open a policy on it. */
+ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- /* decide how many entries to get depending on the max_entries
- and max_size passed by client */
+ /*
+ * calculate how many entries we will return.
+ * based on
+ * - the number of entries the client asked
+ * - our limit on that
+ * - the starting point (enumeration context)
+ * - the buffer size the client will accept
+ */
+
+ /*
+ * We are a lot more like W2K. Instead of reading the SAM
+ * each time to find the records we need to send back,
+ * we read it once and link that copy to the sam handle.
+ * For large user list (over the MAX_SAM_ENTRIES)
+ * it's a definitive win.
+ * second point to notice: between enumerations
+ * our sam is now the same as it's a snapshoot.
+ * third point: got rid of the static SAM_USER_21 struct
+ * no more intermediate.
+ * con: it uses much more memory, as a full copy is stored
+ * in memory.
+ *
+ * If you want to change it, think twice and think
+ * of the second point , that's really important.
+ *
+ * JFM, 12/20/2001
+ */
+
+ /* Get what we need from the password database */
- if(q_u->max_entries > MAX_SAM_ENTRIES)
- q_u->max_entries = MAX_SAM_ENTRIES;
+ 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 0x2:
- acb_mask = ACB_WSTRUST;
- /* Fall through */
- case 0x1:
- case 0x4:
- become_root();
-#if 0
- r_u->status = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
- MAX_SAM_ENTRIES, acb_mask);
-#endif
-#if 0
- /*
- * Which should we use here ? JRA.
- */
- r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
- MAX_SAM_ENTRIES, acb_mask);
-#endif
-#if 1
- r_u->status = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
- MAX_SAM_ENTRIES, acb_mask);
-#endif
- unbecome_root();
- if (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_OK) {
- DEBUG(5, ("get_sampwd_entries: failed\n"));
- return r_u->status;
- }
- break;
- case 0x3:
- case 0x5:
- r_u->status = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
- if (r_u->status!=NT_STATUS_OK)
- return NT_STATUS_ACCESS_DENIED;
- break;
- default:
- DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
- return NT_STATUS_INVALID_INFO_CLASS;
+ case 0x1:
+ case 0x2:
+ case 0x4:
+ become_root();
+ r_u->status=load_sampwd_entries(info, acb_mask);
+ unbecome_root();
+ if (NT_STATUS_IS_ERR(r_u->status)) {
+ DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
+ return r_u->status;
+ }
+ num_account = info->disp_info.num_user_account;
+ break;
+ case 0x3:
+ case 0x5:
+ r_u->status = load_group_domain_entries(info, &info->sid);
+ if (NT_STATUS_IS_ERR(r_u->status))
+ return r_u->status;
+ num_account = info->disp_info.num_group_account;
+ break;
+ default:
+ DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- orig_num_entries = num_entries;
-
- if (num_entries > q_u->max_entries)
- num_entries = q_u->max_entries;
+ /* first limit the number of entries we will return */
+ if(max_entries > max_sam_entries) {
+ DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
+ max_entries = max_sam_entries;
+ }
- if (num_entries > MAX_SAM_ENTRIES) {
- num_entries = MAX_SAM_ENTRIES;
- DEBUG(5, ("limiting number of entries to %d\n", num_entries));
+ if (enum_context > num_account) {
+ DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
+ return NT_STATUS_OK;
}
- /* Ensure password info is never given out here. PARANOIA... JRA */
- samr_clear_passwd_fields(pass, num_entries);
+ /* verify we won't overflow */
+ if (max_entries > num_account-enum_context) {
+ max_entries = num_account-enum_context;
+ DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
+ }
- data_size = q_u->max_size;
+ /* calculate the size and limit on the number of entries we will return */
+ temp_size=(enum_context+max_entries)*struct_size;
+
+ if (temp_size>max_size) {
+ max_entries=max_size/struct_size;
+ DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
+ }
- ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
- if (!ctr)
+ if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(ctr);
@@ -1079,70 +990,75 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
/* Now create reply structure */
switch (q_u->switch_level) {
case 0x1:
- if (num_entries) {
- if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1))))
+ if (max_entries) {
+ if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_1(p->mem_ctx,ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_OK)
+ disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, info->disp_info.disp_user_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x2:
- if (num_entries) {
- if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2))))
+ if (max_entries) {
+ if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_2(p->mem_ctx,ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_OK)
+ disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, info->disp_info.disp_user_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x3:
- if (num_entries) {
- if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3))))
+ if (max_entries) {
+ if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_3(p->mem_ctx,ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
- if (disp_ret != NT_STATUS_OK)
+ disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x4:
- if (num_entries) {
- if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4))))
+ if (max_entries) {
+ if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_4(p->mem_ctx,ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_OK)
+ disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
case 0x5:
- if (num_entries) {
- if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5))))
+ if (max_entries) {
+ if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
return NT_STATUS_NO_MEMORY;
}
- disp_ret = init_sam_dispinfo_5(p->mem_ctx,ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
- if (disp_ret != NT_STATUS_OK)
+ disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
+ if (NT_STATUS_IS_ERR(disp_ret))
return disp_ret;
break;
+
default:
ctr->sam.info = NULL;
return NT_STATUS_INVALID_INFO_CLASS;
}
- DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
+ /* calculate the total size */
+ total_data_size=num_account*struct_size;
- if (num_entries < orig_num_entries)
+ if (enum_context+max_entries < num_account)
r_u->status = STATUS_MORE_ENTRIES;
- init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status);
+ DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
+
+ init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
return r_u->status;
+
}
/*******************************************************************
samr_reply_query_aliasinfo
********************************************************************/
-uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
+NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
{
fstring alias_desc = "Local Unix group";
fstring alias="";
@@ -1244,62 +1160,82 @@ uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_
_samr_lookup_names
********************************************************************/
-uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
+NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
{
- uint32 rid[MAX_SAM_ENTRIES];
- enum SID_NAME_USE type[MAX_SAM_ENTRIES];
- int i;
- int num_rids = q_u->num_names2;
- DOM_SID pol_sid;
+ uint32 rid[MAX_SAM_ENTRIES];
+ uint32 local_rid;
+ enum SID_NAME_USE type[MAX_SAM_ENTRIES];
+ enum SID_NAME_USE local_type;
+ int i;
+ int num_rids = q_u->num_names2;
+ DOM_SID pol_sid;
+ fstring sid_str;
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
+ DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
- ZERO_ARRAY(rid);
- ZERO_ARRAY(type);
+ ZERO_ARRAY(rid);
+ ZERO_ARRAY(type);
- if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
- init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
- return r_u->status;
- }
+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid)) {
+ init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
+ return r_u->status;
+ }
- if (num_rids > MAX_SAM_ENTRIES) {
- num_rids = MAX_SAM_ENTRIES;
- DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
- }
+ if (num_rids > MAX_SAM_ENTRIES) {
+ num_rids = MAX_SAM_ENTRIES;
+ DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
+ }
- for (i = 0; i < num_rids; i++) {
- fstring name;
+ DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
- r_u->status = NT_STATUS_NONE_MAPPED;
+ for (i = 0; i < num_rids; i++) {
+ fstring name;
+ DOM_SID sid;
- rid [i] = 0xffffffff;
- type[i] = SID_NAME_UNKNOWN;
+ r_u->status = NT_STATUS_NONE_MAPPED;
- fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
+ rid [i] = 0xffffffff;
+ type[i] = SID_NAME_UNKNOWN;
- if(sid_equal(&pol_sid, &global_sam_sid)) {
- DOM_SID sid;
- if(local_lookup_name(global_myname, name, &sid, &type[i])) {
- sid_split_rid( &sid, &rid[i]);
- r_u->status = NT_STATUS_OK;
- }
- }
- }
+ fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer, q_u->uni_name[i].uni_str_len));
- init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
+ /*
+ * we are only looking for a name
+ * the SID we get back can be outside
+ * the scope of the pol_sid
+ *
+ * in clear: it prevents to reply to domain\group: yes
+ * when only builtin\group exists.
+ *
+ * a cleaner code is to add the sid of the domain we're looking in
+ * to the local_lookup_name function.
+ */
+
+ if(local_lookup_name(global_myname, name, &sid, &local_type)) {
+ sid_split_rid(&sid, &local_rid);
+
+ if (sid_equal(&sid, &pol_sid)) {
+ rid[i]=local_rid;
+ type[i]=local_type;
+ r_u->status = NT_STATUS_OK;
+ }
+ }
+ }
- DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
+ init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
- return r_u->status;
+ DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
+
+ return r_u->status;
}
/*******************************************************************
_samr_chgpasswd_user
********************************************************************/
-uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
+NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
{
fstring user_name;
fstring wks;
@@ -1377,7 +1313,7 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
_samr_lookup_rids
********************************************************************/
-uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
+NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
{
fstring group_names[MAX_SAM_ENTRIES];
uint32 *group_attrs = NULL;
@@ -1442,7 +1378,7 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
_api_samr_open_user. Safe - gives out no passwd info.
********************************************************************/
-uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
+NTSTATUS _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
{
SAM_ACCOUNT *sampass=NULL;
DOM_SID sid;
@@ -1482,12 +1418,9 @@ uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_U
return NT_STATUS_NO_SUCH_USER;
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->sid = sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1538,7 +1471,7 @@ static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
user. JRA.
*************************************************************************/
-static BOOL get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
+static NTSTATUS get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
{
SAM_ACCOUNT *smbpass=NULL;
BOOL ret;
@@ -1577,7 +1510,7 @@ static BOOL get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 us
return NT_STATUS_OK;
}
-#if 0 /* JERRY */
+#if 1 /* JRA - re-enabled... JERRY - why was this removed ? */
/*************************************************************************
get_user_info_20
*************************************************************************/
@@ -1616,6 +1549,7 @@ static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
return True;
}
#endif
+
/*************************************************************************
get_user_info_21
*************************************************************************/
@@ -1658,7 +1592,7 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
_samr_query_userinfo
********************************************************************/
-uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
+NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
{
SAM_USERINFO_CTR *ctr;
uint32 rid = 0;
@@ -1725,10 +1659,18 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
if (ctr->info.id12 == NULL)
return NT_STATUS_NO_MEMORY;
- if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid))!=NT_STATUS_OK)
+ if (NT_STATUS_IS_ERR(r_u->status = get_user_info_12(p, ctr->info.id12, rid)))
return r_u->status;
break;
+ case 20:
+ ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
+ if (ctr->info.id20 == NULL)
+ return NT_STATUS_NO_MEMORY;
+ if (!get_user_info_20(ctr->info.id20, rid))
+ return NT_STATUS_NO_SUCH_USER;
+ break;
+
case 21:
ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
if (ctr->info.id21 == NULL)
@@ -1752,7 +1694,7 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
samr_reply_query_usergroups
********************************************************************/
-uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
+NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
DOM_GID *gids = NULL;
@@ -1782,6 +1724,7 @@ uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAM
if (ret == False) {
samr_clear_sam_passwd(sam_pass);
+ pdb_free_sam(sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
@@ -1795,6 +1738,7 @@ uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAM
DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
samr_clear_sam_passwd(sam_pass);
+ pdb_free_sam(sam_pass);
return r_u->status;
}
@@ -1803,59 +1747,118 @@ uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAM
_samr_query_dom_info
********************************************************************/
-uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
+NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
{
- SAM_UNK_CTR *ctr;
+ struct samr_info *info = NULL;
+ SAM_UNK_CTR *ctr;
+ uint32 min_pass_len,pass_hist,flag;
+ time_t u_expire, u_min_age;
+ NTTIME nt_expire, nt_min_age;
+
+ time_t u_lock_duration, u_reset_time;
+ NTTIME nt_lock_duration, nt_reset_time;
+ uint32 lockout;
+
+ time_t u_logout;
+ NTTIME nt_logout;
+
+ uint32 num_users=0, num_groups=0, num_aliases=0;
if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(ctr);
+ ZERO_STRUCTP(ctr);
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
- return NT_STATUS_INVALID_HANDLE;
+ /* find the policy handle. open a policy on it. */
+ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
- switch (q_u->switch_value) {
- case 0x01:
- init_unk_info1(&ctr->info.inf1);
- break;
- case 0x02:
+ switch (q_u->switch_value) {
+ case 0x01:
+ /* Use defaults until we merge with HEAD db. JRA */
+ min_pass_len = MINPASSWDLENGTH; /* 5 chars minimum */
+ pass_hist = 0; /* don't keep any old password */
+ flag = 0; /* don't force user to logon */
+ u_expire = MAX_PASSWORD_AGE; /* 21 days */
+ u_min_age = 0; /* 0 days */
+
+ unix_to_nt_time_abs(&nt_expire, u_expire);
+ unix_to_nt_time_abs(&nt_min_age, u_min_age);
+
+ init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
+ flag, nt_expire, nt_min_age);
+ break;
+ case 0x02:
+ become_root();
+ r_u->status=load_sampwd_entries(info, ACB_NORMAL);
+ unbecome_root();
+ if (NT_STATUS_IS_ERR(r_u->status)) {
+ DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
+ return r_u->status;
+ }
+ num_users=info->disp_info.num_user_account;
+ free_samr_db(info);
+
+ r_u->status=load_group_domain_entries(info, &global_sam_sid);
+ if (NT_STATUS_IS_ERR(r_u->status)) {
+ DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
+ return r_u->status;
+ }
+ num_groups=info->disp_info.num_group_account;
+ free_samr_db(info);
+
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL));
- break;
- case 0x03:
- init_unk_info3(&ctr->info.inf3);
- break;
- case 0x06:
- init_unk_info6(&ctr->info.inf6);
- break;
- case 0x07:
- init_unk_info7(&ctr->info.inf7);
- break;
- case 0x0c:
- init_unk_info12(&ctr->info.inf12);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- }
+ init_unk_info2(&ctr->info.inf2, global_myworkgroup, global_myname, (uint32) time(NULL),
+ num_users, num_groups, num_aliases);
+ break;
+ case 0x03:
+ /* Use defaults until we merge with HEAD db. JRA */
+ u_logout = -1; /* don't force logout */
+ unix_to_nt_time_abs(&nt_logout, u_logout);
+ init_unk_info3(&ctr->info.inf3, nt_logout);
+ break;
+ case 0x05:
+ init_unk_info5(&ctr->info.inf5, global_myname);
+ break;
+ case 0x06:
+ init_unk_info6(&ctr->info.inf6);
+ break;
+ case 0x07:
+ init_unk_info7(&ctr->info.inf7);
+ break;
+ case 0x0c:
+ /* Use defaults until we merge with HEAD db. JRA */
+ u_lock_duration = 0; /* lockout for 0 minutes */
+ u_reset_time = 0; /* reset immediatly */
+ lockout = 0; /* don't lockout */
+
+ unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
+ unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
+
+ init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
+ break;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
- init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
+ init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
- DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
- return r_u->status;
+ return r_u->status;
}
/*******************************************************************
_api_samr_create_user
+ Create an account, can be either a normal user or a machine.
+ This funcion will need to be updated for bdc/domain trusts.
********************************************************************/
-uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
+NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
fstring mach_acct;
@@ -1915,14 +1918,14 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR
* So we go the easy way, only check after if the account exists.
* JFM (2/3/2001), to clear any possible bad understanding (-:
*/
-
+
pstrcpy(add_script, lp_adduser_script());
-
+
if(*add_script)
smb_create_user(mach_acct, NULL);
+
/* add the user in the smbpasswd file or the Samba authority database */
- if (!local_password_change(mach_acct, local_flags, NULL, err_str,
- sizeof(err_str), msg_str, sizeof(msg_str))) {
+ if (!local_password_change(mach_acct, local_flags, NULL, err_str, sizeof(err_str), msg_str, sizeof(msg_str))) {
DEBUG(0, ("%s\n", err_str));
pdb_free_sam(sam_pass);
return NT_STATUS_ACCESS_DENIED;
@@ -1950,14 +1953,12 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR
}
/* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
+
+ if ((info = get_samr_info_by_sid(&sid)) == NULL) {
pdb_free_sam(sam_pass);
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(info);
- info->sid = sid;
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
pdb_free_sam(sam_pass);
@@ -1976,61 +1977,59 @@ uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CR
samr_reply_connect_anon
********************************************************************/
-uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
+NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
{
struct samr_info *info = NULL;
- /* set up the SAMR connect_anon response */
+ /* set up the SAMR connect_anon response */
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- /* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
+ /* associate the user's SID with the new handle. */
+ if ((info = get_samr_info_by_sid(NULL)) == NULL)
+ return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->status = q_u->unknown_0;
+ info->status = q_u->unknown_0;
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return r_u->status;
+ return r_u->status;
}
/*******************************************************************
samr_reply_connect
********************************************************************/
-uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
+NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
{
struct samr_info *info = NULL;
- DEBUG(5,("_samr_connect: %d\n", __LINE__));
+ DEBUG(5,("_samr_connect: %d\n", __LINE__));
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- /* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
+ /* associate the user's SID with the new handle. */
+ if ((info = get_samr_info_by_sid(NULL)) == NULL)
+ return NT_STATUS_NO_MEMORY;
- ZERO_STRUCTP(info);
- info->status = q_u->access_mask;
+ info->status = q_u->access_mask;
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- DEBUG(5,("_samr_connect: %d\n", __LINE__));
+ DEBUG(5,("_samr_connect: %d\n", __LINE__));
- return r_u->status;
+ return r_u->status;
}
/**********************************************************************
api_samr_lookup_domain
**********************************************************************/
-uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
+NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
{
r_u->status = NT_STATUS_OK;
@@ -2086,7 +2085,7 @@ static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
api_samr_enum_domains
**********************************************************************/
-uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
+NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
{
uint32 num_entries = 2;
fstring dom[2];
@@ -2108,7 +2107,7 @@ uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM
api_samr_open_alias
********************************************************************/
-uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
+NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
{
DOM_SID sid;
POLICY_HND domain_pol = q_u->dom_pol;
@@ -2135,12 +2134,9 @@ uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN
* JFM.
*/
- /* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- ZERO_STRUCTP(info);
- info->sid = sid;
+ /* associate the user's SID with the new handle. */
+ if ((info = get_samr_info_by_sid(&sid)) == NULL)
+ return NT_STATUS_NO_MEMORY;
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
@@ -2173,7 +2169,10 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
return False;
}
- pdb_set_acct_ctrl(pwd, id10->acb_info);
+ if (!pdb_set_acct_ctrl(pwd, id10->acb_info)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
if(!pdb_update_sam_account(pwd, True)) {
pdb_free_sam(pwd);
@@ -2231,7 +2230,7 @@ static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
- SAM_ACCOUNT *new_pwd = NULL;
+ BOOL result = True;
if (id21 == NULL) {
DEBUG(5, ("set_user_info_21: NULL id21\n"));
@@ -2239,17 +2238,14 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
}
pdb_init_sam(&pwd);
- pdb_init_sam(&new_pwd);
if (!pdb_getsampwrid(pwd, rid)) {
- pdb_free_sam(pwd);
- pdb_free_sam(new_pwd);
- return False;
+ result = False;
+ goto done;
}
/* we make a copy so that we can modify stuff */
- copy_sam_passwd(new_pwd, pwd);
- copy_id21_to_sam_passwd(new_pwd, id21);
+ copy_id21_to_sam_passwd(pwd, id21);
/*
* The funny part about the previous two calls is
@@ -2259,16 +2255,14 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
*/
/* write the change out */
- if(!pdb_update_sam_account(new_pwd, True)) {
- pdb_free_sam(pwd);
- pdb_free_sam(new_pwd);
- return False;
+ if(!pdb_update_sam_account(pwd, True)) {
+ result = False;
+ goto done;
}
+done:
pdb_free_sam(pwd);
- pdb_free_sam(new_pwd);
-
- return True;
+ return result;
}
/*******************************************************************
@@ -2278,12 +2272,12 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
{
SAM_ACCOUNT *pwd = NULL;
- SAM_ACCOUNT *new_pwd = NULL;
uint8 nt_hash[16];
uint8 lm_hash[16];
pstring buf;
uint32 len;
uint16 acct_ctrl;
+ BOOL result = True;
if (id23 == NULL) {
DEBUG(5, ("set_user_info_23: NULL id23\n"));
@@ -2291,33 +2285,28 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
}
pdb_init_sam(&pwd);
- pdb_init_sam(&new_pwd);
if (!pdb_getsampwrid(pwd, rid)) {
- pdb_free_sam(pwd);
- pdb_free_sam(new_pwd);
- return False;
+ result = False;
+ goto done;
}
acct_ctrl = pdb_get_acct_ctrl(pwd);
-
- copy_sam_passwd(new_pwd, pwd);
- pdb_free_sam(pwd);
- copy_id23_to_sam_passwd(new_pwd, id23);
+ copy_id23_to_sam_passwd(pwd, id23);
if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
- pdb_free_sam(new_pwd);
- return False;
+ result = False;
+ goto done;
}
- if (!pdb_set_lanman_passwd (new_pwd, lm_hash)) {
- pdb_free_sam(new_pwd);
- return False;
+ if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
+ result = False;
+ goto done;
}
- if (!pdb_set_nt_passwd(new_pwd, nt_hash)) {
- pdb_free_sam(new_pwd);
- return False;
+ if (!pdb_set_nt_passwd(pwd, nt_hash)) {
+ result = False;
+ goto done;
}
/* if it's a trust account, don't update /etc/passwd */
@@ -2328,22 +2317,22 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
} else {
/* update the UNIX password */
if (lp_unix_password_sync() )
- if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
- pdb_free_sam(new_pwd);
- return False;
+ if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
+ result = False;
+ goto done;
}
}
memset(buf, 0, sizeof(buf));
- if(!pdb_update_sam_account(new_pwd, True)) {
- pdb_free_sam(new_pwd);
- return False;
+ if(!pdb_update_sam_account(pwd, True)) {
+ result = False;
+ goto done;
}
- pdb_free_sam(new_pwd);
-
- return True;
+done:
+ pdb_free_sam(pwd);
+ return result;
}
/*******************************************************************
@@ -2417,7 +2406,7 @@ static BOOL set_user_info_pw(char *pass, uint32 rid)
samr_reply_set_userinfo
********************************************************************/
-uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
+NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
{
uint32 rid = 0x0;
DOM_SID sid;
@@ -2475,6 +2464,7 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
pdb_free_sam(sam_pass);
+ sam_pass = NULL;
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch (switch_value) {
@@ -2532,7 +2522,7 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
samr_reply_set_userinfo2
********************************************************************/
-uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
+NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
{
DOM_SID sid;
uint32 rid = 0x0;
@@ -2585,7 +2575,7 @@ uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SE
_samr_query_aliasmem
*********************************************************************/
-uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
+NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
uint32 *rid=NULL;
int num_rids;
@@ -2601,144 +2591,145 @@ uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, S
init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_OK);
- return r_u->status;
+ return NT_STATUS_OK;
+
}
/*********************************************************************
_samr_query_aliasmem
*********************************************************************/
-uint32 _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
+NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
{
- DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_query_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_query_groupmem
*********************************************************************/
-uint32 _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
+NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
{
- DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_query_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_add_aliasmem
*********************************************************************/
-uint32 _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
+NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
{
- DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_add_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_del_aliasmem
*********************************************************************/
-uint32 _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
+NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
{
- DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_del_aliasmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_add_groupmem
*********************************************************************/
-uint32 _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
+NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
{
- DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_add_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_del_groupmem
*********************************************************************/
-uint32 _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
+NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
{
- DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_del_groupmem: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_delete_dom_user
*********************************************************************/
-uint32 _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
+NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
{
- DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_delete_dom_user: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_delete_dom_group
*********************************************************************/
-uint32 _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
+NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
{
- DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_delete_dom_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_delete_dom_alias
*********************************************************************/
-uint32 _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
+NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
{
- DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_delete_dom_alias: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_create_dom_group
*********************************************************************/
-uint32 _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
+NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
{
- DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_create_dom_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_create_dom_alias
*********************************************************************/
-uint32 _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
+NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
{
- DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_create_dom_alias: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_query_groupinfo
*********************************************************************/
-uint32 _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
+NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
{
- DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_query_groupinfo: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_set_groupinfo
*********************************************************************/
-uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
+NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
{
- DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_set_groupinfo: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_get_dom_pwinfo
*********************************************************************/
-uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
+NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
{
/* Actually, returning zeros here works quite well :-). */
return NT_STATUS_OK;
@@ -2748,18 +2739,18 @@ uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_
_samr_open_group
*********************************************************************/
-uint32 _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
+NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
{
- DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_open_group: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*********************************************************************
_samr_unknown_2d
*********************************************************************/
-uint32 _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
+NTSTATUS _samr_unknown_2d(pipes_struct *p, SAMR_Q_UNKNOWN_2D *q_u, SAMR_R_UNKNOWN_2D *r_u)
{
- DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
- return False;
+ DEBUG(0,("_samr_unknown_2d: Not yet implemented.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index 011efb1bace..e71bcd36a9a 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -24,8 +24,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/********************************************************************
* api_spoolss_open_printer_ex
********************************************************************/
@@ -305,12 +303,12 @@ static BOOL api_spoolss_rfnpcnex(pipes_struct *p)
r_u.status = _spoolss_rfnpcnex(p, &q_u, &r_u);
if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) {
- safe_free(r_u.info.data);
+ SAFE_FREE(r_u.info.data);
DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n"));
return False;
}
- safe_free(r_u.info.data);
+ SAFE_FREE(r_u.info.data);
return True;
}
@@ -1110,7 +1108,7 @@ static BOOL api_spoolss_addprintprocessor(pipes_struct *p)
automatically set the winprint processor for printer
entries later. Used to debug the LexMark Optra S 1855 PCL
driver --jerry */
- r_u.status = NT_STATUS_OK;
+ r_u.status = WERR_OK;
if(!spoolss_io_r_addprintprocessor("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_addprintprocessor: unable to marshall SPOOL_R_ADDPRINTPROCESSOR.\n"));
@@ -1201,6 +1199,158 @@ static BOOL api_spoolss_getjob(pipes_struct *p)
return True;
}
+/********************************************************************
+ * api_spoolss_getprinterdataex
+ *
+ * called from the spoolss dispatcher
+ ********************************************************************/
+
+static BOOL api_spoolss_getprinterdataex(pipes_struct *p)
+{
+ SPOOL_Q_GETPRINTERDATAEX q_u;
+ SPOOL_R_GETPRINTERDATAEX r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* read the stream and fill the struct */
+ if (!spoolss_io_q_getprinterdataex("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_getprinterdataex: unable to unmarshall SPOOL_Q_GETPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_getprinterdataex( p, &q_u, &r_u);
+
+ if (!spoolss_io_r_getprinterdataex("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_getprinterdataex: unable to marshall SPOOL_R_GETPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL api_spoolss_setprinterdataex(pipes_struct *p)
+{
+ SPOOL_Q_SETPRINTERDATAEX q_u;
+ SPOOL_R_SETPRINTERDATAEX r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!spoolss_io_q_setprinterdataex("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_setprinterdataex: unable to unmarshall SPOOL_Q_SETPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_setprinterdataex(p, &q_u, &r_u);
+
+ if(!spoolss_io_r_setprinterdataex("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_setprinterdataex: unable to marshall SPOOL_R_SETPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL api_spoolss_enumprinterkey(pipes_struct *p)
+{
+ SPOOL_Q_ENUMPRINTERKEY q_u;
+ SPOOL_R_ENUMPRINTERKEY r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!spoolss_io_q_enumprinterkey("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_setprinterkey: unable to unmarshall SPOOL_Q_ENUMPRINTERKEY.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_enumprinterkey(p, &q_u, &r_u);
+
+ if(!spoolss_io_r_enumprinterkey("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_enumprinterkey: unable to marshall SPOOL_R_ENUMPRINTERKEY.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL api_spoolss_enumprinterdataex(pipes_struct *p)
+{
+ SPOOL_Q_ENUMPRINTERDATAEX q_u;
+ SPOOL_R_ENUMPRINTERDATAEX r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!spoolss_io_q_enumprinterdataex("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_enumprinterdataex: unable to unmarshall SPOOL_Q_ENUMPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_enumprinterdataex(p, &q_u, &r_u);
+
+ if(!spoolss_io_r_enumprinterdataex("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_enumprinterdataex: unable to marshall SPOOL_R_ENUMPRINTERDATAEX.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+/* Disabled because it doesn't fix the bug I am looking at but it would be
+ a shame to throw away the code. -tpot */
+
+#if 0
+
+static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p)
+{
+ SPOOL_Q_GETPRINTPROCESSORDIRECTORY q_u;
+ SPOOL_R_GETPRINTPROCESSORDIRECTORY r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!spoolss_io_q_getprintprocessordirectory("", &q_u, data, 0)) {
+ DEBUG(0,("spoolss_io_q_getprintprocessordirectory: unable to unmarshall SPOOL_Q_GETPRINTPROCESSORDIRECTORY.\n"));
+ return False;
+ }
+
+ r_u.status = _spoolss_getprintprocessordirectory(p, &q_u, &r_u);
+
+ if(!spoolss_io_r_getprintprocessordirectory("", &r_u, rdata, 0)) {
+ DEBUG(0,("spoolss_io_r_getprintprocessordirectory: unable to marshall SPOOL_R_GETPRINTPROCESSORDIRECTORY.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+#endif
+
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
@@ -1247,6 +1397,15 @@ struct api_struct api_spoolss_cmds[] =
{"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors },
{"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob },
{"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes },
+ {"SPOOLSS_GETPRINTERDATAEX", SPOOLSS_GETPRINTERDATAEX, api_spoolss_getprinterdataex },
+ {"SPOOLSS_SETPRINTERDATAEX", SPOOLSS_SETPRINTERDATAEX, api_spoolss_setprinterdataex },
+ {"SPOOLSS_ENUMPRINTERKEY", SPOOLSS_ENUMPRINTERKEY, api_spoolss_enumprinterkey },
+ {"SPOOLSS_ENUMPRINTERDATAEX", SPOOLSS_ENUMPRINTERDATAEX, api_spoolss_enumprinterdataex },
+#if 0
+ /* Disabled because it doesn't fix the bug I am looking at but it would be
+ a shame to throw away the code. -tpot */
+ {"SPOOLSS_GETPRINTPROCESSORDIRECTORY",SPOOLSS_GETPRINTPROCESSORDIRECTORY,api_spoolss_getprintprocessordirectory},
+#endif
{ NULL, 0, NULL }
};
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 86f4fe77ac3..521fbbe306e 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -5,7 +5,8 @@
* 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.
+ * Copyright (C) Gerald Carter 2000-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,13 +28,11 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-extern pstring global_myname;
-
#ifndef MAX_OPEN_PRINTER_EXS
#define MAX_OPEN_PRINTER_EXS 50
#endif
+#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
#define PRINTER_HANDLE_IS_PRINTER 0
#define PRINTER_HANDLE_IS_PRINTSERVER 1
@@ -50,9 +49,10 @@ struct table_node {
/* and the notify info asked about */
/* that's the central struct */
typedef struct _Printer{
+ struct _Printer *prev, *next;
BOOL document_started;
BOOL page_started;
- int jobid; /* jobid in printing backend */
+ int jobid; /* jobid in printing backend */
BOOL printer_type;
union {
fstring handlename;
@@ -75,6 +75,8 @@ typedef struct _Printer{
} client;
} Printer_entry;
+static Printer_entry *printers_list;
+
typedef struct _counter_printer_0 {
ubi_dlNode Next;
ubi_dlNode Prev;
@@ -88,7 +90,8 @@ static ubi_dlList counter_list;
static struct cli_state cli;
static uint32 smb_connections=0;
-#define OUR_HANDLE(hnd) ((hnd==NULL)?"NULL":(IVAL(hnd->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER"))
+#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
+((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
/* translate between internal status numbers and NT status numbers */
static int nt_printj_status(int v)
@@ -141,17 +144,11 @@ static int nt_printq_status(int v)
static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
{
- SPOOL_NOTIFY_OPTION *sp = *pp;
-
- *pp = NULL;
-
- if (!sp)
+ if (*pp == NULL)
return;
- if (sp->ctr.type)
- safe_free(sp->ctr.type);
-
- free(sp);
+ SAFE_FREE((*pp)->ctr.type);
+ SAFE_FREE(*pp);
}
/***************************************************************************
@@ -160,7 +157,7 @@ static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
static void srv_spoolss_replycloseprinter(POLICY_HND *handle)
{
- uint32 status;
+ WERROR status;
/* weird if the test succeds !!! */
if (smb_connections==0) {
@@ -201,7 +198,10 @@ static void free_printer_entry(void *ptr)
Printer->notify.option=NULL;
Printer->notify.client_connected=False;
- safe_free(Printer);
+ /* Remove from the internal list. */
+ DLIST_REMOVE(printers_list, Printer);
+
+ SAFE_FREE(Printer);
}
/****************************************************************************
@@ -225,7 +225,7 @@ SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
if (!new_sp->ctr.type) {
- safe_free(new_sp);
+ SAFE_FREE(new_sp);
return NULL;
}
}
@@ -242,7 +242,7 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
Printer_entry *find_printer = NULL;
if(!find_policy_by_hnd(p,hnd,(void **)&find_printer)) {
- DEBUG(3,("find_printer_index_by_hnd: Printer handle not found: "));
+ DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
return NULL;
}
@@ -250,7 +250,7 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
}
/****************************************************************************
- close printer index by handle
+ Close printer index by handle.
****************************************************************************/
static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
@@ -258,7 +258,7 @@ static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
- DEBUG(0,("close_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
+ DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
return False;
}
@@ -268,20 +268,21 @@ static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
}
/****************************************************************************
- delete a printer given a handle
+ Delete a printer given a handle.
****************************************************************************/
-static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
+
+static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
{
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
- DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
- return ERRbadfid;
+ DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
+ return WERR_BADFID;
}
if (del_a_printer(Printer->dev.handlename) != 0) {
DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
- return ERRbadfid;
+ return WERR_BADFID;
}
/* Check calling user has permission to delete printer. Note that
@@ -291,7 +292,7 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("printer delete denied by security descriptor\n"));
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
if (*lp_deleteprinter_cmd()) {
@@ -309,7 +310,7 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, NULL);
if (ret != 0) {
- return ERRbadfid; /* What to return here? */
+ return WERR_BADFID; /* What to return here? */
}
DEBUGADD(10,("returned [%d]\n", ret));
@@ -318,13 +319,13 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
lp_killservice( i );
- return ERRsuccess;
+ return WERR_OK;
} else
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
- return ERRsuccess;
-}
+ return WERR_OK;
+}
/****************************************************************************
return the snum of a printer corresponding to an handle
@@ -334,7 +335,7 @@ static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
- DEBUG(0,("get_printer_snum: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
+ DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
return False;
}
@@ -358,7 +359,7 @@ static BOOL set_printer_hnd_accesstype(pipes_struct *p, POLICY_HND *hnd, uint32
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
if (!Printer) {
- DEBUG(0,("set_printer_hnd_accesstype: Invalid handle (%s)", OUR_HANDLE(hnd)));
+ DEBUG(2,("set_printer_hnd_accesstype: Invalid handle (%s:%u:%u)", OUR_HANDLE(hnd)));
return False;
}
@@ -444,7 +445,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
continue;
printername=strchr(printer->info_2->printername+2, '\\');
@@ -487,7 +488,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
DEBUGADD(5,("set_printer_hnd_name: share:%s\n",lp_servicename(snum)));
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
continue;
DEBUG(10,("set_printer_hnd_name: printername [%s], aprinter [%s]\n",
@@ -541,8 +542,11 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name)
new_printer->notify.option=NULL;
+ /* Add to the internal list. */
+ DLIST_ADD(printers_list, new_printer);
+
if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) {
- safe_free(new_printer);
+ SAFE_FREE(new_printer);
return False;
}
@@ -562,7 +566,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name)
}
/********************************************************************
- Return True is the handle is a print server.
+ Return True if the handle is a print server.
********************************************************************/
static BOOL handle_is_printserver(pipes_struct *p, POLICY_HND *handle)
@@ -613,91 +617,62 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
}
/***************************************************************************
- receive the notify message
+ Receive the notify message.
****************************************************************************/
static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len)
{
- fstring printer;
- uint32 status;
- struct pipes_struct *p;
- struct policy *pol;
- struct handle_list *hl;
-
- *printer = '\0';
- fstrcpy(printer,buf);
+ Printer_entry *find_printer;
+ WERROR status;
+ char msg[8];
+ uint32 low, high;
- if (len == 0) {
- DEBUG(0,("srv_spoolss_receive_message: got null message !\n"));
+ if (len != sizeof(msg)) {
+ DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len));
return;
}
- DEBUG(10,("srv_spoolss_receive_message: Got message about printer %s\n", printer ));
+ memcpy(msg, buf, len);
+ low = IVAL(msg,0);
+ high = IVAL(msg,4);
- /*
- * We need to enumerate all printers. The handle list is shared
- * across pipes of the same name, so just find the first open
- * spoolss pipe.
- */
+ DEBUG(10,("srv_spoolss_receive_message: Got message printer change low=0x%x high=0x%x\n", (unsigned int)low,
+ (unsigned int)high ));
- hl = NULL;
- for ( p = get_first_pipe(); p; get_next_pipe(p)) {
- if (strequal(p->name, "spoolss")) {
- hl = p->pipe_handles;
- break;
- }
- }
+ find_printer = printers_list;
- if (!hl) {
- DEBUG(0,("srv_spoolss_receive_message: no handle list on spoolss pipe !\n"));
- return;
- }
-
- /* Iterate the printer list on this pipe. */
- for (pol = hl->Policy; pol; pol = pol->next ) {
- Printer_entry *find_printer = (Printer_entry *)pol->data_ptr;
-
- if (!find_printer)
- continue;
+ /* Iterate the printer list */
+ for(; find_printer; find_printer = find_printer->next) {
/*
- * if the entry is the given printer or if it's a printerserver
- * we send the message
+ * If the entry has a connected client we send the message.
*/
- if (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
- if (strcmp(find_printer->dev.handlename, printer))
- continue;
- if (find_printer->notify.client_connected==True)
- cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status);
+ if (find_printer->notify.client_connected==True) {
+ DEBUG(10,("srv_spoolss_receive_message: printerserver [%s]\n", find_printer->dev.printerservername ));
+ if (cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, low, high, &status))
+ DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn status = 0x%x\n",
+ (unsigned int)W_ERROR_V(status)));
+ else
+ DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn failed\n"));
+ }
}
}
/***************************************************************************
- send a notify event
+ Send a notify event.
****************************************************************************/
-static BOOL srv_spoolss_sendnotify(pipes_struct *p, POLICY_HND *handle)
-{
- fstring printer;
- Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
-
- if (!Printer) {
- DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return False;
- }
-
- if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
- fstrcpy(printer, Printer->dev.handlename);
- else
- fstrcpy(printer, "");
-
- /*srv_spoolss_receive_message(printer);*/
- DEBUG(10,("srv_spoolss_sendnotify: Sending message about printer %s\n", printer ));
+static BOOL srv_spoolss_sendnotify(uint32 high, uint32 low)
+{
+ char msg[8];
- message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer, strlen(printer) + 1, False); /* Null terminate... */
+ SIVAL(msg,0,low);
+ SIVAL(msg,4,high);
+ DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x\n", low, high));
+ message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(msg), False);
return True;
}
@@ -707,10 +682,10 @@ static BOOL srv_spoolss_sendnotify(pipes_struct *p, POLICY_HND *handle)
* called from the spoolss dispatcher
********************************************************************/
-uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
+WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
{
#if 0
- uint32 result = ERRsuccess;
+ WERROR result = WERR_OK;
#endif
UNISTR2 *printername = NULL;
@@ -727,7 +702,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
printername = &q_u->printername;
if (printername == NULL)
- return ERRinvalidprintername;
+ return WERR_INVALID_PRINTER_NAME;
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
@@ -736,7 +711,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
DEBUGADD(3,("checking name: %s\n",name));
if (!open_printer_hnd(p, handle, name))
- return ERRinvalidprintername;
+ return WERR_INVALID_PRINTER_NAME;
/*
if (printer_default->datatype_ptr != NULL)
@@ -750,7 +725,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (!set_printer_hnd_accesstype(p, handle, printer_default->access_required)) {
close_printer_handle(p, handle);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
/*
@@ -780,7 +755,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (handle_is_printserver(p, handle)) {
if (printer_default->access_required == 0) {
- return ERRsuccess;
+ return WERR_OK;
}
else if ((printer_default->access_required & SERVER_ACCESS_ADMINISTER ) == SERVER_ACCESS_ADMINISTER) {
@@ -789,14 +764,14 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (!lp_ms_add_printer_wizard()) {
close_printer_handle(p, handle);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
else if (user.uid == 0 || user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) {
- return ERRsuccess;
+ return WERR_OK;
}
else {
close_printer_handle(p, handle);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
}
}
@@ -806,7 +781,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
doesn't have print permission. */
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
/* map an empty access mask to the minimum access mask */
if (printer_default->access_required == 0x0)
@@ -828,7 +803,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (!print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
/*
@@ -907,7 +882,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
#endif
}
- return ERRsuccess;
+ return WERR_OK;
}
/****************************************************************************
@@ -915,34 +890,40 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
+ BOOL ret = True;
+
switch (level) {
case 2:
- uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
+ ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
break;
default:
break;
}
- return True;
+ return ret;
}
static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
{
+ BOOL result = True;
+
switch (level) {
case 3:
printer->info_3=NULL;
- uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3);
+ if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
+ result = False;
break;
case 6:
printer->info_6=NULL;
- uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6);
+ if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
+ result = False;
break;
default:
break;
}
- return True;
+ return result;
}
BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
@@ -1003,7 +984,7 @@ BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
*/
if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
- safe_free(nt_devmode->private);
+ SAFE_FREE(nt_devmode->private);
nt_devmode->driverextra=devmode->driverextra;
if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
return False;
@@ -1019,27 +1000,27 @@ BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
* _spoolss_enddocprinter_internal.
********************************************************************/
-static uint32 _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
+static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
{
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
Printer->document_started=False;
print_job_end(Printer->jobid,True);
/* error codes unhandled so far ... */
- return 0x0;
+ return WERR_OK;
}
/********************************************************************
* api_spoolss_closeprinter
********************************************************************/
-uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
+WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
@@ -1048,12 +1029,17 @@ uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R
if (Printer && Printer->document_started)
_spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
- memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
-
if (!close_printer_handle(p, handle))
- return ERRbadfid;
+ return WERR_BADFID;
- return ERRsuccess;
+ /* clear the returned printer handle. Observed behavior
+ from Win2k server. Don't think this really matters.
+ Previous code just copied the value of the closed
+ handle. --jerry */
+
+ memset(&r_u->handle, '\0', sizeof(r_u->handle));
+
+ return WERR_OK;
}
/********************************************************************
@@ -1061,12 +1047,11 @@ uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R
********************************************************************/
-uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
+WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
-
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- uint32 result;
+ WERROR result;
if (Printer && Printer->document_started)
_spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
@@ -1075,8 +1060,10 @@ uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL
result = delete_printer_handle(p, handle);
- if (result == ERRsuccess) {
- srv_spoolss_sendnotify(p, handle);
+ update_c_setprinter(FALSE);
+
+ if (W_ERROR_IS_OK(result)) {
+ srv_spoolss_sendnotify(0, PRINTER_CHANGE_DELETE_PRINTER);
}
return result;
@@ -1123,7 +1110,7 @@ static int get_version_id (char * arch)
* --jerry
********************************************************************/
-uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
+WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u,
SPOOL_R_DELETEPRINTERDRIVER *r_u)
{
fstring driver;
@@ -1137,20 +1124,18 @@ uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* check that we have a valid driver name first */
if ((version=get_version_id(arch)) == -1) {
/* this is what NT returns */
- return ERRinvalidenvironment;
+ return WERR_INVALID_ENVIRONMENT;
}
ZERO_STRUCT(info);
- if (get_a_printer_driver (&info, 3, driver, arch, version) != 0) {
- /* this is what NT returns */
- return ERRunknownprinterdriver;
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
}
if (printer_driver_in_use(arch, driver))
{
- /* this is what NT returns */
- return ERRprinterdriverinuse;
+ return WERR_PRINTER_DRIVER_IN_USE;
}
return delete_printer_driver(info.info_3);
@@ -1166,6 +1151,14 @@ static BOOL getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32
DEBUG(8,("getprinterdata_printer_server:%s\n", value));
+ if (!strcmp(value, "W3SvcInstalled")) {
+ *type = 0x4;
+ if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
+ return False;
+ *needed = 0x4;
+ return True;
+ }
+
if (!strcmp(value, "BeepEnabled")) {
*type = 0x4;
if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
@@ -1251,14 +1244,14 @@ static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND
DEBUG(5,("getprinterdata_printer\n"));
if (!Printer) {
- DEBUG(0,("getprinterdata_printer: Invalid handle (%s).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("getprinterdata_printer: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return False;
}
if(!get_printer_snum(p, handle, &snum))
return False;
- if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
if (!get_specific_param(*printer, 2, value, &idata, type, &len)) {
@@ -1286,7 +1279,7 @@ static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND
DEBUG(5,("getprinterdata_printer:copy done\n"));
- safe_free(idata);
+ SAFE_FREE(idata);
return True;
}
@@ -1295,7 +1288,7 @@ static BOOL getprinterdata_printer(pipes_struct *p, TALLOC_CTX *ctx, POLICY_HND
* spoolss_getprinterdata
********************************************************************/
-uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
+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;
@@ -1325,10 +1318,10 @@ uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
DEBUG(4,("_spoolss_getprinterdata\n"));
if (!Printer) {
- if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
- return ERRnomem;
- DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ 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;
}
unistr2_to_ascii(value, valuename, sizeof(value)-1);
@@ -1343,19 +1336,18 @@ uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
/* reply this param doesn't exist */
if (*out_size) {
if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
} else {
*data = NULL;
}
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
if (*needed > *out_size)
- return ERRmoredata;
- else {
- return ERRsuccess;
- }
+ return WERR_STATUS_MORE_ENTRIES;
+ else
+ return WERR_OK;
}
/***************************************************************************
@@ -1363,7 +1355,7 @@ uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
****************************************************************************/
static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
{
- uint32 status;
+ WERROR status;
/*
* If it's the first connection, contact the client
@@ -1401,7 +1393,7 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin
* called from api_spoolss_rffpcnex
********************************************************************/
-uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
+WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 flags = q_u->flags;
@@ -1415,8 +1407,8 @@ uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
Printer->notify.flags=flags;
@@ -1436,7 +1428,7 @@ uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
&Printer->notify.client_hnd))
Printer->notify.client_connected=True;
- return ERRsuccess;
+ return WERR_OK;
}
/*******************************************************************
@@ -1452,7 +1444,7 @@ static void spoolss_notify_server_name(int snum,
pstring temp_name, temp;
uint32 len;
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
+ slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
len = (uint32)dos_PutUniCode(temp, temp_name, sizeof(temp) - 2, True);
@@ -1788,6 +1780,7 @@ static void spoolss_notify_attributes(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0] = printer->info_2->attributes;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1800,6 +1793,7 @@ static void spoolss_notify_priority(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0] = printer->info_2->priority;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1812,6 +1806,7 @@ static void spoolss_notify_default_priority(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0] = printer->info_2->default_priority;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1824,6 +1819,7 @@ static void spoolss_notify_start_time(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0] = printer->info_2->starttime;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1836,6 +1832,7 @@ static void spoolss_notify_until_time(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0] = printer->info_2->untiltime;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1847,13 +1844,11 @@ static void spoolss_notify_status(int snum,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- print_queue_struct *q=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
- print_queue_status(snum, &q, &status);
+ print_queue_length(snum, &status);
data->notify_data.value[0]=(uint32) status.status;
- safe_free(q);
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1865,12 +1860,8 @@ static void spoolss_notify_cjobs(int snum,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
- print_queue_struct *q=NULL;
- print_status_struct status;
-
- memset(&status, 0, sizeof(status));
- data->notify_data.value[0] = print_queue_status(snum, &q, &status);
- safe_free(q);
+ data->notify_data.value[0] = print_queue_length(snum, NULL);
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1885,6 +1876,7 @@ static void spoolss_notify_average_ppm(int snum,
/* always respond 8 pages per minutes */
/* a little hard ! */
data->notify_data.value[0] = printer->info_2->averageppm;
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -1923,6 +1915,7 @@ static void spoolss_notify_job_status(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0]=nt_printj_status(queue->status);
+ data->notify_data.value[1] = 0;
}
/*******************************************************************
@@ -2010,6 +2003,7 @@ static void spoolss_notify_job_time(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0]=0x0;
+ data->notify_data.value[1]=0;
}
/*******************************************************************
@@ -2022,11 +2016,13 @@ static void spoolss_notify_job_size(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0]=queue->size;
+ data->notify_data.value[1]=0;
}
/*******************************************************************
- * fill a notify_info_data with job position
+ Fill a notify_info_data with job position.
********************************************************************/
+
static void spoolss_notify_job_position(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
@@ -2034,11 +2030,13 @@ static void spoolss_notify_job_position(int snum,
TALLOC_CTX *mem_ctx)
{
data->notify_data.value[0]=queue->job;
+ data->notify_data.value[1]=0;
}
/*******************************************************************
- * fill a notify_info_data with submitted time
+ Fill a notify_info_data with submitted time.
********************************************************************/
+
static void spoolss_notify_submitted_time(int snum,
SPOOL_NOTIFY_INFO_DATA *data,
print_queue_struct *queue,
@@ -2048,12 +2046,13 @@ static void spoolss_notify_submitted_time(int snum,
struct tm *t;
uint32 len;
SYSTEMTIME st;
+ char *p;
t=gmtime(&queue->time);
len = sizeof(SYSTEMTIME);
- data->notify_data.data.length = len/2 - 1;
+ data->notify_data.data.length = len;
data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
if (!data->notify_data.data.string) {
@@ -2062,7 +2061,21 @@ static void spoolss_notify_submitted_time(int snum,
}
make_systemtime(&st, t);
- memcpy(data->notify_data.data.string,&st,len);
+
+ /*
+ * Systemtime must be linearized as a set of UINT16's.
+ * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
+ */
+
+ p = (char *)data->notify_data.data.string;
+ SSVAL(p, 0, st.year);
+ SSVAL(p, 2, st.month);
+ SSVAL(p, 4, st.dayofweek);
+ SSVAL(p, 6, st.day);
+ SSVAL(p, 8, st.hour);
+ SSVAL(p, 10, st.minute);
+ SSVAL(p, 12, st.second);
+ SSVAL(p, 14, st.milliseconds);
}
#define END 65535
@@ -2236,7 +2249,7 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
(option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
option_type->count, lp_servicename(snum)));
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
return False;
for(field_num=0; field_num<option_type->count; field_num++) {
@@ -2247,7 +2260,7 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
continue;
if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
- DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
+ DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
return False;
}
else info->data = tid;
@@ -2302,10 +2315,10 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue,
continue;
if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
- DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
+ DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
return False;
- } else
- info->data = tid;
+ }
+ else info->data = tid;
current_data=&(info->data[info->count]);
@@ -2348,7 +2361,7 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue,
*
********************************************************************/
-static uint32 printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
+static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
SPOOL_NOTIFY_INFO *info,
TALLOC_CTX *mem_ctx)
{
@@ -2362,6 +2375,9 @@ static uint32 printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
DEBUG(4,("printserver_notify_info\n"));
+ if (!Printer)
+ return WERR_BADFID;
+
option=Printer->notify.option;
id=1;
info->version=2;
@@ -2396,7 +2412,7 @@ static uint32 printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
}
*/
- return ERRsuccess;
+ return WERR_OK;
}
/*******************************************************************
@@ -2404,7 +2420,7 @@ static uint32 printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
* fill a notify_info struct with info asked
*
********************************************************************/
-static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
+static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
TALLOC_CTX *mem_ctx)
{
int snum;
@@ -2419,6 +2435,9 @@ static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
DEBUG(4,("printer_notify_info\n"));
+ if (!Printer)
+ return WERR_BADFID;
+
option=Printer->notify.option;
id=0xffffffff;
info->version=2;
@@ -2441,11 +2460,10 @@ static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
case JOB_NOTIFY_TYPE: {
NT_PRINTER_INFO_LEVEL *printer = NULL;
- memset(&status, 0, sizeof(status));
count = print_queue_status(snum, &queue, &status);
- if (get_a_printer(&printer, 2,
- lp_servicename(snum)) != 0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2,
+ lp_servicename(snum))))
goto done;
for (j=0; j<count; j++) {
@@ -2459,7 +2477,7 @@ static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
free_a_printer(&printer, 2);
done:
- safe_free(queue);
+ SAFE_FREE(queue);
break;
}
}
@@ -2479,14 +2497,14 @@ static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
info->data[i].id, info->data[i].size, info->data[i].enc_type));
}
*/
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
* spoolss_rfnpcnex
********************************************************************/
-uint32 _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
+WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
{
POLICY_HND *handle = &q_u->handle;
/* uint32 change = q_u->change; - notused. */
@@ -2494,13 +2512,13 @@ uint32 _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
SPOOL_NOTIFY_INFO *info = &r_u->info;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- uint32 result = ERRbadfid;
+ WERROR result = WERR_BADFID;
/* we always have a NOTIFY_INFO struct */
r_u->info_ptr=0x1;
if (!Printer) {
- DEBUG(0,("_spoolss_rfnpcnex: Invalid handle (%s).\n",
+ DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
OUR_HANDLE(handle)));
goto done;
}
@@ -2547,16 +2565,12 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
uint32 global_counter;
struct tm *t;
time_t setuptime;
-
- print_queue_struct *queue=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
-
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
- count = print_queue_status(snum, &queue, &status);
+ count = print_queue_length(snum, &status);
/* check if we already have a counter for this printer */
session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
@@ -2591,7 +2605,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
init_unistr(&printer->printername, chaine);
- slprintf(chaine,sizeof(chaine)-1,"\\\\%s", global_myname);
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name());
init_unistr(&printer->servername, chaine);
printer->cjobs = count;
@@ -2628,7 +2642,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
printer->unknown18 = 0x0;
printer->status = nt_printq_status(status.status);
printer->unknown20 = 0x0;
- printer->c_setprinter = ntprinter->info_2->c_setprinter; /* how many times setprinter has been called */
+ printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
printer->unknown22 = 0x0;
printer->unknown23 = 0x6; /* 6 ???*/
printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
@@ -2638,7 +2652,6 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum)
printer->unknown28 = 0;
printer->unknown29 = 0;
- safe_free(queue);
free_a_printer(&ntprinter,2);
return (True);
}
@@ -2653,19 +2666,19 @@ static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int
pstring chaine2;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
printer->flags=flags;
if (*ntprinter->info_2->comment == '\0') {
init_unistr(&printer->comment, lp_comment(snum));
- slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",global_myname, ntprinter->info_2->printername,
+ slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",get_called_name(), ntprinter->info_2->printername,
ntprinter->info_2->drivername, lp_comment(snum));
}
else {
init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
- slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",global_myname, ntprinter->info_2->printername,
+ slprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",get_called_name(), ntprinter->info_2->printername,
ntprinter->info_2->drivername, ntprinter->info_2->comment);
}
@@ -2688,10 +2701,8 @@ static void free_dev_mode(DEVICEMODE *dev)
if (dev == NULL)
return;
- if (dev->private)
- safe_free(dev->private);
-
- safe_free(dev);
+ SAFE_FREE(dev->private);
+ SAFE_FREE(dev);
}
/****************************************************************************
@@ -2711,13 +2722,13 @@ static DEVICEMODE *construct_dev_mode(int snum)
DEBUGADD(8,("getting printer characteristics\n"));
if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
- DEBUG(0,("construct_dev_mode: malloc fail.\n"));
+ DEBUG(2,("construct_dev_mode: malloc fail.\n"));
return NULL;
}
ZERO_STRUCTP(devmode);
- if(get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
goto fail;
if (printer->info_2->devmode)
@@ -2789,15 +2800,12 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum)
int count;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
- print_queue_struct *queue=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
- memset(&status, 0, sizeof(status));
- count = print_queue_status(snum, &queue, &status);
+ count = print_queue_length(snum, &status);
init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
@@ -2842,7 +2850,6 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum)
}
free_a_printer(&ntprinter, 2);
- safe_free(queue);
return True;
}
@@ -2855,12 +2862,12 @@ static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
PRINTER_INFO_3 *printer = NULL;
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
return False;
*pp_printer = NULL;
if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
- DEBUG(0,("construct_printer_info_3: malloc fail.\n"));
+ DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
return False;
}
@@ -2901,9 +2908,52 @@ static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum)
}
/********************************************************************
+ * construct_printer_info_4
+ * fill a printer_info_4 struct
+ ********************************************************************/
+
+static BOOL construct_printer_info_4(PRINTER_INFO_4 *printer, int snum)
+{
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
+ return False;
+
+ init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
+ init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
+ printer->attributes = ntprinter->info_2->attributes;
+
+ free_a_printer(&ntprinter, 2);
+ return True;
+}
+
+/********************************************************************
+ * construct_printer_info_5
+ * fill a printer_info_5 struct
+ ********************************************************************/
+
+static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum)
+{
+ NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+
+ if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum))))
+ return False;
+
+ init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
+ init_unistr(&printer->portname, ntprinter->info_2->portname); /* portname */
+ printer->attributes = ntprinter->info_2->attributes;
+ printer->device_not_selected_timeout = 0x3a98;
+ printer->transmission_retry_timeout = 0xafc8;
+
+ free_a_printer(&ntprinter, 2);
+ return True;
+}
+
+
+/********************************************************************
Spoolss_enumprinters.
********************************************************************/
-static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
@@ -2919,12 +2969,12 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
if (construct_printer_info_1(flags, &current_prt, snum)) {
if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
- DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
- safe_free(printers);
+ DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
+ SAFE_FREE(printers);
*returned=0;
- return ERRnomem;
- } else
- printers = tp;
+ return WERR_NOMEM;
+ }
+ else printers = tp;
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
(*returned)++;
@@ -2937,27 +2987,27 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
(*needed) += spoolss_size_printer_info_1(&printers[i]);
if (!alloc_buffer_size(buffer, *needed))
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_printer_info_1("", buffer, &printers[i], 0);
/* clear memory */
- safe_free(printers);
+ SAFE_FREE(printers);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
else
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
enum_all_printers_info_1_local.
*********************************************************************/
-static BOOL enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
DEBUG(4,("enum_all_printers_info_1_local\n"));
@@ -2967,25 +3017,26 @@ static BOOL enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, u
/********************************************************************
enum_all_printers_info_1_name.
*********************************************************************/
-static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
- fstring temp;
+ char *s = name;
+
DEBUG(4,("enum_all_printers_info_1_name\n"));
- fstrcpy(temp, "\\\\");
- fstrcat(temp, global_myname);
-
- if (strequal(name, temp)) {
+ if ((name[0] == '\\') && (name[1] == '\\'))
+ s = name + 2;
+
+ if (is_myname_or_ipaddr(s)) {
return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
}
else
- return ERRinvalidname;
+ return WERR_INVALID_NAME;
}
/********************************************************************
enum_all_printers_info_1_remote.
*********************************************************************/
-static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTER_INFO_1 *printer;
fstring printername;
@@ -3001,12 +3052,12 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
*/
if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
*returned=1;
- slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname);
- slprintf(desc, sizeof(desc)-1,"%s", global_myname);
+ slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
+ slprintf(desc, sizeof(desc)-1,"%s", get_called_name());
slprintf(comment, sizeof(comment)-1, "Logged on Domain");
init_unistr(&printer->description, desc);
@@ -3018,29 +3069,29 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
*needed += spoolss_size_printer_info_1(printer);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(printer);
- return ERRinsufficientbuffer;
+ SAFE_FREE(printer);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
/* clear memory */
- safe_free(printer);
+ SAFE_FREE(printer);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
else
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
enum_all_printers_info_1_network.
*********************************************************************/
-static BOOL enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
DEBUG(4,("enum_all_printers_info_1_network\n"));
@@ -3053,7 +3104,7 @@ static BOOL enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered,
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
@@ -3067,12 +3118,12 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
if (construct_printer_info_2(&current_prt, snum)) {
if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
- DEBUG(0,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
- safe_free(printers);
+ DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
+ SAFE_FREE(printers);
*returned = 0;
- return ERRnomem;
- } else
- printers = tp;
+ return WERR_NOMEM;
+ }
+ else printers = tp;
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
(*returned)++;
@@ -3088,8 +3139,8 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
for (i=0; i<*returned; i++) {
free_devmode(printers[i].devmode);
}
- safe_free(printers);
- return ERRinsufficientbuffer;
+ SAFE_FREE(printers);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -3100,20 +3151,20 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
for (i=0; i<*returned; i++) {
free_devmode(printers[i].devmode);
}
- safe_free(printers);
+ SAFE_FREE(printers);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
else
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
* handle enumeration of printers at level 1
********************************************************************/
-static uint32 enumprinters_level1( uint32 flags, fstring name,
+static WERROR enumprinters_level1( uint32 flags, fstring name,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
@@ -3131,50 +3182,46 @@ static uint32 enumprinters_level1( uint32 flags, fstring name,
if (flags & PRINTER_ENUM_NETWORK)
return enum_all_printers_info_1_network(buffer, offered, needed, returned);
- return ERRsuccess; /* NT4sp5 does that */
+ return WERR_OK; /* NT4sp5 does that */
}
/********************************************************************
* handle enumeration of printers at level 2
********************************************************************/
-static uint32 enumprinters_level2( uint32 flags, fstring servername,
+static WERROR enumprinters_level2( uint32 flags, fstring servername,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
- fstring temp;
-
- fstrcpy(temp, "\\\\");
- fstrcat(temp, global_myname);
+ char *s = servername;
if (flags & PRINTER_ENUM_LOCAL) {
- if (strequal(servername, temp))
- return enum_all_printers_info_2(buffer, offered, needed, returned);
- else
return enum_all_printers_info_2(buffer, offered, needed, returned);
}
if (flags & PRINTER_ENUM_NAME) {
- if (strequal(servername, temp))
+ if ((servername[0] == '\\') && (servername[1] == '\\'))
+ s = servername + 2;
+ if (is_myname_or_ipaddr(s))
return enum_all_printers_info_2(buffer, offered, needed, returned);
else
- return ERRinvalidname;
+ return WERR_INVALID_NAME;
}
if (flags & PRINTER_ENUM_REMOTE)
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
* handle enumeration of printers at level 5
********************************************************************/
-static uint32 enumprinters_level5( uint32 flags, fstring servername,
+static WERROR enumprinters_level5( uint32 flags, fstring servername,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
@@ -3183,7 +3230,7 @@ static uint32 enumprinters_level5( uint32 flags, fstring servername,
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-uint32 _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
+WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
{
uint32 flags = q_u->flags;
UNISTR2 *servername = &q_u->servername;
@@ -3229,19 +3276,19 @@ uint32 _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
return enumprinters_level5(flags, name, buffer, offered, needed, returned);
case 3:
case 4:
- default:
- return ERRunknownlevel;
+ break;
}
+ return WERR_UNKNOWN_LEVEL;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_0 *printer=NULL;
if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
construct_printer_info_0(printer, snum);
@@ -3249,31 +3296,31 @@ static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, u
*needed += spoolss_size_printer_info_0(printer);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(printer);
- return ERRinsufficientbuffer;
+ SAFE_FREE(printer);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
smb_io_printer_info_0("", buffer, printer, 0);
/* clear memory */
- safe_free(printer);
+ SAFE_FREE(printer);
if (*needed > offered) {
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_1 *printer=NULL;
if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
@@ -3281,31 +3328,31 @@ static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, u
*needed += spoolss_size_printer_info_1(printer);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(printer);
- return ERRinsufficientbuffer;
+ SAFE_FREE(printer);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
/* clear memory */
- safe_free(printer);
+ SAFE_FREE(printer);
if (*needed > offered) {
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_2 *printer=NULL;
if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
- return ERRnomem;
+ return WERR_NOMEM;
construct_printer_info_2(printer, snum);
@@ -3314,40 +3361,40 @@ static uint32 getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_info_2(printer);
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
if (!smb_io_printer_info_2("", buffer, printer, 0)) {
free_printer_info_2(printer);
- return ERRnomem;
+ return WERR_NOMEM;
}
/* clear memory */
free_printer_info_2(printer);
if (*needed > offered) {
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_3 *printer=NULL;
if (!construct_printer_info_3(&printer, snum))
- return ERRnomem;
+ return WERR_NOMEM;
/* check the required size. */
*needed += spoolss_size_printer_info_3(printer);
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_info_3(printer);
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -3357,16 +3404,82 @@ static uint32 getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, u
free_printer_info_3(printer);
if (*needed > offered) {
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+static WERROR getprinter_level_4(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+ PRINTER_INFO_4 *printer=NULL;
+
+ if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL)
+ return WERR_NOMEM;
+
+ if (!construct_printer_info_4(printer, snum))
+ return WERR_NOMEM;
+
+ /* check the required size. */
+ *needed += spoolss_size_printer_info_4(printer);
+
+ if (!alloc_buffer_size(buffer, *needed)) {
+ free_printer_info_4(printer);
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+
+ /* fill the buffer with the structures */
+ smb_io_printer_info_4("", buffer, printer, 0);
+
+ /* clear memory */
+ free_printer_info_4(printer);
+
+ if (*needed > offered) {
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
+static WERROR getprinter_level_5(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+{
+ PRINTER_INFO_5 *printer=NULL;
-uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
+ if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL)
+ return WERR_NOMEM;
+
+ if (!construct_printer_info_5(printer, snum))
+ return WERR_NOMEM;
+
+ /* check the required size. */
+ *needed += spoolss_size_printer_info_5(printer);
+
+ if (!alloc_buffer_size(buffer, *needed)) {
+ free_printer_info_5(printer);
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+
+ /* fill the buffer with the structures */
+ smb_io_printer_info_5("", buffer, printer, 0);
+
+ /* clear memory */
+ free_printer_info_5(printer);
+
+ if (*needed > offered) {
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
@@ -3383,7 +3496,7 @@ uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
*needed=0;
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
switch (level) {
case 0:
@@ -3394,9 +3507,12 @@ uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
return getprinter_level_2(snum, buffer, offered, needed);
case 3:
return getprinter_level_3(snum, buffer, offered, needed);
- default:
- return ERRunknownlevel;
+ case 4:
+ return getprinter_level_4(snum, buffer, offered, needed);
+ case 5:
+ return getprinter_level_5(snum, buffer, offered, needed);
}
+ return WERR_UNKNOWN_LEVEL;
}
/********************************************************************
@@ -3410,24 +3526,24 @@ static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_IN
/********************************************************************
* construct_printer_driver_info_1
********************************************************************/
-static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
ZERO_STRUCT(driver);
- if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERRinvalidprintername;
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ return WERR_INVALID_PRINTER_NAME;
- if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
- return ERRunknownprinterdriver;
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
+ return WERR_UNKNOWN_PRINTER_DRIVER;
fill_printer_driver_info_1(info, driver, servername, architecture);
free_a_printer(&printer,2);
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
@@ -3467,7 +3583,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN
* construct_printer_driver_info_2
* fill a printer_info_2 struct
********************************************************************/
-static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -3475,17 +3591,17 @@ static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst
ZERO_STRUCT(printer);
ZERO_STRUCT(driver);
- if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERRinvalidprintername;
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ return WERR_INVALID_PRINTER_NAME;
- if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
- return ERRunknownprinterdriver;
+ if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
+ return WERR_UNKNOWN_PRINTER_DRIVER;
fill_printer_driver_info_2(info, driver, servername);
free_a_printer(&printer,2);
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
@@ -3515,7 +3631,7 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser
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) {
- DEBUG(0,("init_unistr_array: Realloc error\n" ));
+ DEBUG(2,("init_unistr_array: Realloc error\n" ));
return;
} else
*uni_array = tuary;
@@ -3580,30 +3696,58 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
* construct_printer_info_3
* fill a printer_info_3 struct
********************************************************************/
-static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- uint32 status=0;
+ WERROR status;
ZERO_STRUCT(driver);
status=get_a_printer(&printer, 2, lp_servicename(snum) );
- DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
- if (status != 0)
- return ERRinvalidprintername;
+ DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
+ if (!W_ERROR_IS_OK(status))
+ return WERR_INVALID_PRINTER_NAME;
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
- DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
- if (status != 0) {
- free_a_printer(&printer,2);
- return ERRunknownprinterdriver;
+ DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
+
+#if 0 /* JERRY */
+
+ /*
+ * I put this code in during testing. Helpful when commenting out the
+ * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
+ * as win2k always queries the driver using an infor level of 6.
+ * I've left it in (but ifdef'd out) because I'll probably
+ * use it in experimentation again in the future. --jerry 22/01/2002
+ */
+
+ if (!W_ERROR_IS_OK(status)) {
+ /*
+ * Is this a W2k client ?
+ */
+ if (version == 3) {
+ /* Yes - try again with a WinNT driver. */
+ version = 2;
+ status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
+ DEBUG(8,("construct_printer_driver_info_3: status: %s\n", werror_str(status)));
+ }
+#endif
+
+ if (!W_ERROR_IS_OK(status)) {
+ free_a_printer(&printer,2);
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+
+#if 0 /* JERRY */
}
+#endif
+
fill_printer_driver_info_3(info, driver, servername);
free_a_printer(&printer,2);
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
@@ -3674,37 +3818,37 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
* construct_printer_info_6
* fill a printer_info_6 struct
********************************************************************/
-static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fstring servername, fstring architecture, uint32 version)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- uint32 status=0;
+ WERROR status;
ZERO_STRUCT(driver);
status=get_a_printer(&printer, 2, lp_servicename(snum) );
- DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
- if (status != 0)
- return ERRinvalidprintername;
+ DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
+ if (!W_ERROR_IS_OK(status))
+ return WERR_INVALID_PRINTER_NAME;
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
- DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
- if (status != 0) {
+ DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
+ if (!W_ERROR_IS_OK(status)) {
/*
* Is this a W2k client ?
*/
if (version < 3) {
free_a_printer(&printer,2);
- return ERRunknownprinterdriver;
+ return WERR_UNKNOWN_PRINTER_DRIVER;
}
/* Yes - try again with a WinNT driver. */
version = 2;
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
- DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
- if (status != 0) {
+ DEBUG(8,("construct_printer_driver_info_6: status: %s\n", werror_str(status)));
+ if (!W_ERROR_IS_OK(status)) {
free_a_printer(&printer,2);
- return ERRunknownprinterdriver;
+ return WERR_UNKNOWN_PRINTER_DRIVER;
}
}
@@ -3712,7 +3856,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
free_a_printer(&printer,2);
- return ERRsuccess;
+ return WERR_OK;
}
/****************************************************************************
@@ -3720,7 +3864,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
{
- safe_free(info->dependentfiles);
+ SAFE_FREE(info->dependentfiles);
}
/****************************************************************************
@@ -3728,23 +3872,23 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
{
- safe_free(info->dependentfiles);
+ SAFE_FREE(info->dependentfiles);
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_1 *info=NULL;
- uint32 status;
+ WERROR status;
if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
- if (status != ERRsuccess) {
- safe_free(info);
+ if (!W_ERROR_IS_OK(status)) {
+ SAFE_FREE(info);
return status;
}
@@ -3752,35 +3896,35 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture,
*needed += spoolss_size_printer_driver_info_1(info);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_1("", buffer, info, 0);
/* clear memory */
- safe_free(info);
+ SAFE_FREE(info);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_2 *info=NULL;
- uint32 status;
+ WERROR status;
if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
- if (status != ERRsuccess) {
- safe_free(info);
+ if (!W_ERROR_IS_OK(status)) {
+ SAFE_FREE(info);
return status;
}
@@ -3788,33 +3932,33 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture,
*needed += spoolss_size_printer_driver_info_2(info);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_2("", buffer, info, 0);
/* clear memory */
- safe_free(info);
+ SAFE_FREE(info);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_3 info;
- uint32 status;
+ WERROR status;
ZERO_STRUCT(info);
status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
- if (status != ERRsuccess) {
+ if (!W_ERROR_IS_OK(status)) {
return status;
}
@@ -3823,7 +3967,7 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_driver_info_3(&info);
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -3832,22 +3976,22 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
free_printer_driver_info_3(&info);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_6 info;
- uint32 status;
+ WERROR status;
ZERO_STRUCT(info);
status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
- if (status != ERRsuccess) {
+ if (!W_ERROR_IS_OK(status)) {
return status;
}
@@ -3856,7 +4000,7 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_driver_info_6(&info);
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -3865,15 +4009,15 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
free_printer_driver_info_6(&info);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
+WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
{
POLICY_HND *handle = &q_u->handle;
UNISTR2 *uni_arch = &q_u->architecture;
@@ -3900,11 +4044,11 @@ uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
*servermajorversion=0;
*serverminorversion=0;
- pstrcpy(servername, global_myname);
+ pstrcpy(servername, get_called_name());
unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
switch (level) {
case 1:
@@ -3915,46 +4059,46 @@ uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
case 6:
return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
- default:
- return ERRunknownlevel;
}
+
+ return WERR_UNKNOWN_LEVEL;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
+WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- if (Printer) {
- Printer->page_started=True;
- return 0x0;
+ if (!Printer) {
+ DEBUG(3,("Error in startpageprinter printer handle\n"));
+ return WERR_BADFID;
}
- DEBUG(3,("Error in startpageprinter printer handle\n"));
- return ERRbadfid;
+ Printer->page_started=True;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
+WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
Printer->page_started=False;
- return ERRsuccess;
+ return WERR_OK;
}
/********************************************************************
@@ -3963,7 +4107,7 @@ uint32 _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO
*
********************************************************************/
-uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
+WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
/* uint32 level = q_u->doc_info_container.level; - notused. */
@@ -3978,8 +4122,8 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
struct current_user user;
if (!Printer) {
- DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
get_current_user(&user, p);
@@ -4000,13 +4144,13 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
if (strcmp(datatype, "RAW") != 0) {
(*jobid)=0;
- return ERRinvaliddatatype;
+ return WERR_INVALID_DATATYPE;
}
}
/* get the share number of the printer */
if (!get_printer_snum(p, handle, &snum)) {
- return ERRbadfid;
+ return WERR_BADFID;
}
unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
@@ -4017,13 +4161,13 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
NT error code. */
if (Printer->jobid == -1) {
- return map_nt_error_from_unix(errno);
+ return map_werror_from_unix(errno);
}
Printer->document_started=True;
(*jobid) = Printer->jobid;
- return 0x0;
+ return WERR_OK;
}
/********************************************************************
@@ -4032,7 +4176,7 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
*
********************************************************************/
-uint32 _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
+WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
@@ -4042,7 +4186,7 @@ uint32 _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
+WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 buffer_size = q_u->buffer_size;
@@ -4052,9 +4196,9 @@ uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle)));
r_u->buffer_written = q_u->buffer_size2;
- return ERRbadfid;
+ return WERR_BADFID;
}
(*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
@@ -4062,7 +4206,7 @@ uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
r_u->buffer_written = q_u->buffer_size2;
- return 0x0;
+ return WERR_OK;
}
/********************************************************************
@@ -4070,42 +4214,43 @@ uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
* called from the spoolss dispatcher
*
********************************************************************/
-static uint32 control_printer(POLICY_HND *handle, uint32 command,
+static WERROR control_printer(POLICY_HND *handle, uint32 command,
pipes_struct *p)
{
struct current_user user;
- int snum, errcode = ERRbadfunc;
+ int snum;
+ WERROR errcode = WERR_BADFUNC;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
get_current_user(&user, p);
if (!Printer) {
- DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
switch (command) {
case PRINTER_CONTROL_PAUSE:
if (print_queue_pause(&user, snum, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
if (print_queue_resume(&user, snum, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
case PRINTER_CONTROL_PURGE:
if (print_queue_purge(&user, snum, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
return errcode;
@@ -4115,7 +4260,7 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command,
* api_spoolss_abortprinter
********************************************************************/
-uint32 _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
+WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
@@ -4126,22 +4271,22 @@ uint32 _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
* called by spoolss_api_setprinter
* when updating a printer description
********************************************************************/
-static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
+static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
const SPOOL_PRINTER_INFO_LEVEL *info,
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
struct current_user user;
- uint32 result;
+ WERROR result;
int snum;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer || !get_printer_snum(p, handle, &snum)) {
- DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
+ DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
OUR_HANDLE(handle)));
- result = ERRbadfid;
+ result = WERR_BADFID;
goto done;
}
@@ -4163,7 +4308,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
for (i = 0; i < the_acl->num_aces; i++) {
fstring sid_str;
- sid_to_string(sid_str, &the_acl->ace[i].sid);
+ sid_to_string(sid_str, &the_acl->ace[i].trustee);
DEBUG(10, ("%s 0x%08x\n", sid_str,
the_acl->ace[i].info.mask));
@@ -4178,7 +4323,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
for (i = 0; i < the_acl->num_aces; i++) {
fstring sid_str;
- sid_to_string(sid_str, &the_acl->ace[i].sid);
+ sid_to_string(sid_str, &the_acl->ace[i].trustee);
DEBUG(10, ("%s 0x%08x\n", sid_str,
the_acl->ace[i].info.mask));
@@ -4191,7 +4336,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
- result = ERRsuccess;
+ result = WERR_OK;
goto done;
}
@@ -4205,7 +4350,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
information. */
if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
- result = ERRnoaccess;
+ result = WERR_ACCESS_DENIED;
goto done;
}
@@ -4228,14 +4373,11 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
/* we force some elements to "correct" values */
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname);
+ slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- global_myname, lp_servicename(snum));
+ get_called_name(), lp_servicename(snum));
fstrcpy(info->sharename, lp_servicename(snum));
- info->attributes = PRINTER_ATTRIBUTE_SHARED \
- | PRINTER_ATTRIBUTE_LOCAL \
- | PRINTER_ATTRIBUTE_RAW_ONLY \
- | PRINTER_ATTRIBUTE_QUEUED ;
+ info->attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;
return True;
}
@@ -4251,17 +4393,18 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
int numlines;
int ret;
int fd;
+ fstring remote_machine = "%m";
/* build driver path... only 9X architecture is needed for legacy reasons */
slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
- global_myname);
+ get_called_name());
/* change \ to \\ for the shell */
all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
- slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
cmd, printer->info_2->printername, printer->info_2->sharename,
printer->info_2->portname, printer->info_2->drivername,
- printer->info_2->location, driverlocation);
+ printer->info_2->location, driverlocation, remote_machine);
/* Convert script args to unix-codepage */
dos_to_unix(command, True);
@@ -4499,7 +4642,7 @@ static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
PI_CHECK_INT(averageppm);
/* Yuck - don't check the printername or servername as the
- add_a_printer() code plays games with them. You can't
+ mod_a_printer() code plays games with them. You can't
change the printername or the sharename through this interface
in Samba. */
@@ -4536,43 +4679,43 @@ static BOOL nt_printer_info_level_equal(NT_PRINTER_INFO_LEVEL *p1,
}
/********************************************************************
- * called by spoolss_api_setprinter
- * when updating a printer description
+ * Called by spoolss_api_setprinter
+ * when updating a printer description.
********************************************************************/
-static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
+static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
const SPOOL_PRINTER_INFO_LEVEL *info,
DEVICEMODE *devmode)
{
int snum;
NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- uint32 result;
+ WERROR result;
DEBUG(8,("update_printer\n"));
- result = ERRsuccess;
+ result = WERR_OK;
if (level!=2) {
- DEBUG(0,("Send a mail to samba@samba.org\n"));
+ DEBUG(0,("update_printer: Send a mail to samba@samba.org\n"));
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
- result = ERRunknownlevel;
+ result = WERR_UNKNOWN_LEVEL;
goto done;
}
if (!Printer) {
- result = ERRbadfid;
+ result = WERR_BADFID;
goto done;
}
if (!get_printer_snum(p, handle, &snum)) {
- result = ERRbadfid;
+ result = WERR_BADFID;
goto done;
}
- if((get_a_printer(&printer, 2, lp_servicename(snum)) != 0) ||
- (get_a_printer(&old_printer, 2, lp_servicename(snum)) != 0)) {
- result = ERRbadfid;
+ if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) ||
+ (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) {
+ result = WERR_BADFID;
goto done;
}
@@ -4584,16 +4727,19 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
* just read from the tdb in the pointer 'printer'.
*/
- convert_printer_info(info, printer, level);
+ if (!convert_printer_info(info, printer, level)) {
+ result = WERR_NOMEM;
+ goto done;
+ }
if (info->info_2->devmode_ptr != 0) {
/* we have a valid devmode
convert it and link it*/
- DEBUGADD(8,("Converting the devicemode struct\n"));
+ DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
if (!convert_devicemode(printer->info_2->printername, devmode,
&printer->info_2->devmode)) {
- result = ERRnomem;
+ result = WERR_NOMEM;
goto done;
}
}
@@ -4601,7 +4747,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
/* Do sanity check on the requested changes for Samba */
if (!check_printer_ok(printer->info_2, snum)) {
- result = ERRinvalidparam;
+ result = WERR_INVALID_PARAM;
goto done;
}
@@ -4610,41 +4756,62 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
annoying permission denied dialog box. */
if (nt_printer_info_level_equal(printer, old_printer)) {
- DEBUG(3, ("printer info has not changed\n"));
- result = ERRsuccess;
+ DEBUG(3, ("update_printer: printer info has not changed\n"));
+ result = WERR_OK;
goto done;
}
/* Check calling user has permission to update printer description */
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
- DEBUG(3, ("printer property change denied by security "
- "descriptor\n"));
- result = ERRnoaccess;
+ DEBUG(3, ("update_printer: printer property change denied by security descriptor\n"));
+ result = WERR_ACCESS_DENIED;
goto done;
}
/* Call addprinter hook */
- if (*lp_addprinter_cmd() )
+ if (*lp_addprinter_cmd()) {
if ( !add_printer_hook(printer) ) {
- result = ERRnoaccess;
+ result = WERR_ACCESS_DENIED;
goto done;
}
+ }
- /* Update printer info */
-
- if (add_a_printer(*printer, 2)!=0) {
- /* I don't really know what to return here !!! */
- result = ERRnoaccess;
- goto done;
+ /*
+ * 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).
+ */
+ if (printer->info_2->devmode &&
+ printer->info_2->devmode->displayfrequency == MAGIC_DISPLAY_FREQUENCY) {
+
+ 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;
+ }
+ } 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))
+ set_driver_init(printer, 2);
}
+ /* Update printer info */
+ result = mod_a_printer(*printer, 2);
+
done:
free_a_printer(&printer, 2);
free_a_printer(&old_printer, 2);
- srv_spoolss_sendnotify(p, handle);
+ srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER);
return result;
}
@@ -4652,7 +4819,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
+WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
@@ -4664,8 +4831,8 @@ uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
/* check the level */
@@ -4678,22 +4845,22 @@ uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
return update_printer_sec(handle, level, info, p,
secdesc_ctr);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
+WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
{
POLICY_HND *handle = &q_u->handle;
Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
if (!Printer) {
- DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
if (Printer->notify.client_connected==True)
@@ -4707,19 +4874,19 @@ uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
free_spool_notify_option(&Printer->notify.option);
Printer->notify.client_connected=False;
- return ERRsuccess;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
+WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
{
/* that's an [in out] buffer (despite appearences to the contrary) */
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
r_u->needed = 0;
- return ERRinvalidparam; /* this is what a NT server
+ return WERR_INVALID_PARAM; /* this is what a NT server
returns for AddJob. AddJob
must fail on non-local
printers */
@@ -4735,7 +4902,7 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
struct tm *t;
t=gmtime(&queue->time);
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
+ slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
job_info->jobid=queue->job;
init_unistr(&job_info->printername, lp_servicename(snum));
@@ -4764,11 +4931,11 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
struct tm *t;
t=gmtime(&queue->time);
- slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", global_myname);
+ slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
job_info->jobid=queue->job;
- slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter->info_2->printername);
+ slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", get_called_name(), ntprinter->info_2->printername);
init_unistr(&job_info->printername, chaine);
@@ -4805,7 +4972,7 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
/****************************************************************************
Enumjobs at level 1.
****************************************************************************/
-static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
+static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
@@ -4814,23 +4981,23 @@ static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
if (info==NULL) {
- safe_free(queue);
+ SAFE_FREE(queue);
*returned=0;
- return ERRnomem;
+ return WERR_NOMEM;
}
for (i=0; i<*returned; i++)
fill_job_info_1(&info[i], &queue[i], i, snum);
- safe_free(queue);
+ SAFE_FREE(queue);
/* check the required size. */
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_job_info_1(&info[i]);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -4838,51 +5005,53 @@ static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
smb_io_job_info_1("", buffer, &info[i], 0);
/* clear memory */
- safe_free(info);
+ SAFE_FREE(info);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
Enumjobs at level 2.
****************************************************************************/
-static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
+static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
NEW_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
JOB_INFO_2 *info;
int i;
+ WERROR result;
info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
if (info==NULL) {
*returned=0;
- return ERRnomem;
+ return WERR_NOMEM;
}
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0) {
+ result = get_a_printer(&ntprinter, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result)) {
*returned = 0;
- return ERRnomem;
+ return result;
}
for (i=0; i<*returned; i++)
fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter);
free_a_printer(&ntprinter, 2);
- safe_free(queue);
+ SAFE_FREE(queue);
/* check the required size. */
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_job_info_2(&info[i]);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the structures */
@@ -4893,21 +5062,21 @@ static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
for (i = 0; i < *returned; i++)
free_job_info_2(&info[i]);
- free(info);
+ SAFE_FREE(info);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
Enumjobs.
****************************************************************************/
-uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
+WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
{
POLICY_HND *handle = &q_u->handle;
/* uint32 firstjob = q_u->firstjob; - notused. */
@@ -4919,8 +5088,8 @@ uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
uint32 *returned = &r_u->returned;
int snum;
- print_queue_struct *queue=NULL;
print_status_struct prt_status;
+ print_queue_struct *queue=NULL;
/* that's an [in out] buffer */
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
@@ -4928,20 +5097,18 @@ uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
DEBUG(4,("_spoolss_enumjobs\n"));
- ZERO_STRUCT(prt_status);
-
*needed=0;
*returned=0;
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
*returned = print_queue_status(snum, &queue, &prt_status);
DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
if (*returned == 0) {
- safe_free(queue);
- return ERRsuccess;
+ SAFE_FREE(queue);
+ return WERR_OK;
}
switch (level) {
@@ -4950,24 +5117,24 @@ uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
case 2:
return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
default:
- safe_free(queue);
+ SAFE_FREE(queue);
*returned=0;
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
+WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
{
- return 0x0;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
+WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
@@ -4976,17 +5143,15 @@ uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
uint32 command = q_u->command;
struct current_user user;
- print_status_struct prt_status;
- int snum, errcode = ERRbadfunc;
+ int snum;
+ WERROR errcode = WERR_BADFUNC;
- memset(&prt_status, 0, sizeof(prt_status));
-
if (!get_printer_snum(p, handle, &snum)) {
- return ERRbadfid;
+ return WERR_BADFID;
}
if (!print_job_exists(jobid)) {
- return ERRinvalidprintername;
+ return WERR_INVALID_PRINTER_NAME;
}
get_current_user(&user, p);
@@ -4995,22 +5160,22 @@ uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
case JOB_CONTROL_CANCEL:
case JOB_CONTROL_DELETE:
if (print_job_delete(&user, jobid, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
case JOB_CONTROL_PAUSE:
if (print_job_pause(&user, jobid, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
case JOB_CONTROL_RESTART:
case JOB_CONTROL_RESUME:
if (print_job_resume(&user, jobid, &errcode)) {
- errcode = 0;
+ errcode = WERR_OK;
}
break;
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
return errcode;
@@ -5019,7 +5184,7 @@ uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
/****************************************************************************
Enumerates all printer drivers at level 1.
****************************************************************************/
-static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
@@ -5039,24 +5204,26 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERRnomem;
+ return WERR_NOMEM;
if(ndrivers != 0) {
if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
- safe_free(driver_info_1);
- safe_free(list);
- return ERRnomem;
- } else
- driver_info_1 = tdi1;
+ SAFE_FREE(driver_info_1);
+ SAFE_FREE(list);
+ return WERR_NOMEM;
+ }
+ else driver_info_1 = tdi1;
}
for (i=0; i<ndrivers; i++) {
- uint32 status;
+ WERROR status;
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
- safe_free(list);
+ status = get_a_printer_driver(&driver, 3, list[i],
+ architecture, version);
+ if (!W_ERROR_IS_OK(status)) {
+ SAFE_FREE(list);
return status;
}
fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
@@ -5064,7 +5231,7 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
}
*returned+=ndrivers;
- safe_free(list);
+ SAFE_FREE(list);
}
/* check the required size. */
@@ -5074,8 +5241,8 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
}
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(driver_info_1);
- return ERRinsufficientbuffer;
+ SAFE_FREE(driver_info_1);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the driver structures */
@@ -5084,20 +5251,20 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
}
- safe_free(driver_info_1);
+ SAFE_FREE(driver_info_1);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
Enumerates all printer drivers at level 2.
****************************************************************************/
-static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
@@ -5117,25 +5284,27 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERRnomem;
+ return WERR_NOMEM;
if(ndrivers != 0) {
if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
- safe_free(driver_info_2);
- safe_free(list);
- return ERRnomem;
- } else
- driver_info_2 = tdi2;
+ SAFE_FREE(driver_info_2);
+ SAFE_FREE(list);
+ return WERR_NOMEM;
+ }
+ else driver_info_2 = tdi2;
}
for (i=0; i<ndrivers; i++) {
- uint32 status;
+ WERROR status;
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
- safe_free(list);
+ status = get_a_printer_driver(&driver, 3, list[i],
+ architecture, version);
+ if (!W_ERROR_IS_OK(status)) {
+ SAFE_FREE(list);
return status;
}
fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
@@ -5143,7 +5312,7 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
}
*returned+=ndrivers;
- safe_free(list);
+ SAFE_FREE(list);
}
/* check the required size. */
@@ -5153,8 +5322,8 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
}
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(driver_info_2);
- return ERRinsufficientbuffer;
+ SAFE_FREE(driver_info_2);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the form structures */
@@ -5163,20 +5332,20 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
}
- safe_free(driver_info_2);
+ SAFE_FREE(driver_info_2);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
Enumerates all printer drivers at level 3.
****************************************************************************/
-static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
@@ -5196,25 +5365,27 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERRnomem;
+ return WERR_NOMEM;
if(ndrivers != 0) {
if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
- safe_free(driver_info_3);
- safe_free(list);
- return ERRnomem;
- } else
- driver_info_3 = tdi3;
+ SAFE_FREE(driver_info_3);
+ SAFE_FREE(list);
+ return WERR_NOMEM;
+ }
+ else driver_info_3 = tdi3;
}
for (i=0; i<ndrivers; i++) {
- uint32 status;
+ WERROR status;
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- if ((status = get_a_printer_driver(&driver, 3, list[i], architecture, version)) != 0) {
- safe_free(list);
+ status = get_a_printer_driver(&driver, 3, list[i],
+ architecture, version);
+ if (!W_ERROR_IS_OK(status)) {
+ SAFE_FREE(list);
return status;
}
fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
@@ -5222,7 +5393,7 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
}
*returned+=ndrivers;
- safe_free(list);
+ SAFE_FREE(list);
}
/* check the required size. */
@@ -5232,8 +5403,8 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
}
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(driver_info_3);
- return ERRinsufficientbuffer;
+ SAFE_FREE(driver_info_3);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the driver structures */
@@ -5243,23 +5414,23 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
}
for (i=0; i<*returned; i++)
- safe_free(driver_info_3[i].dependentfiles);
+ SAFE_FREE(driver_info_3[i].dependentfiles);
- safe_free(driver_info_3);
+ SAFE_FREE(driver_info_3);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
Enumerates all printer drivers.
****************************************************************************/
-uint32 _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
+WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
{
/* UNISTR2 *name = &q_u->name; - notused. */
UNISTR2 *environment = &q_u->environment;
@@ -5278,7 +5449,7 @@ uint32 _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
buffer = r_u->buffer;
DEBUG(4,("_spoolss_enumprinterdrivers\n"));
- fstrcpy(servername, global_myname);
+ fstrcpy(servername, get_called_name());
*needed=0;
*returned=0;
@@ -5293,8 +5464,8 @@ uint32 _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
default:
*returned=0;
- safe_free(list);
- return ERRunknownlevel;
+ SAFE_FREE(list);
+ return WERR_UNKNOWN_LEVEL;
}
}
@@ -5316,7 +5487,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
+WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
{
/* POLICY_HND *handle = &q_u->handle; - notused. */
uint32 level = q_u->level;
@@ -5346,13 +5517,13 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
*numofforms += numbuiltinforms;
- if (*numofforms == 0) return ERRnomoreitems;
+ if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
switch (level) {
case 1:
if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
*numofforms=0;
- return ERRnomem;
+ return WERR_NOMEM;
}
/* construct the list of form structures */
@@ -5361,14 +5532,14 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
fill_form_1(&forms_1[i], &builtinlist[i]);
}
- safe_free(builtinlist);
+ SAFE_FREE(builtinlist);
for (; i<*numofforms; i++) {
DEBUGADD(6,("Filling form number [%d]\n",i));
fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
}
- safe_free(list);
+ SAFE_FREE(list);
/* check the required size. */
for (i=0; i<numbuiltinforms; i++) {
@@ -5383,8 +5554,8 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
*needed=buffer_size;
if (!alloc_buffer_size(buffer, buffer_size)){
- safe_free(forms_1);
- return ERRinsufficientbuffer;
+ SAFE_FREE(forms_1);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the form structures */
@@ -5397,19 +5568,19 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
smb_io_form_1("", buffer, &forms_1[i], 0);
}
- safe_free(forms_1);
+ SAFE_FREE(forms_1);
if (*needed > offered) {
*numofforms=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
else
- return ERRsuccess;
+ return WERR_OK;
default:
- safe_free(list);
- safe_free(builtinlist);
- return ERRunknownlevel;
+ SAFE_FREE(list);
+ SAFE_FREE(builtinlist);
+ return WERR_UNKNOWN_LEVEL;
}
}
@@ -5417,7 +5588,7 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
+WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
{
/* POLICY_HND *handle = &q_u->handle; - notused. */
uint32 level = q_u->level;
@@ -5450,7 +5621,7 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
DEBUGADD(5,("Number of forms [%d]\n", numofforms));
if (numofforms == 0)
- return ERRbadfid;
+ return WERR_BADFID;
}
switch (level) {
@@ -5471,9 +5642,9 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
}
}
- safe_free(list);
+ SAFE_FREE(list);
if (i == numofforms) {
- return ERRbadfid;
+ return WERR_BADFID;
}
}
/* check the required size. */
@@ -5481,22 +5652,22 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
*needed=spoolss_size_form_1(&form_1);
if (!alloc_buffer_size(buffer, buffer_size)){
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
if (*needed > offered) {
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the form structures */
DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
smb_io_form_1("", buffer, &form_1, 0);
- return ERRsuccess;
+ return WERR_OK;
default:
- safe_free(list);
- return ERRunknownlevel;
+ SAFE_FREE(list);
+ return WERR_UNKNOWN_LEVEL;
}
}
@@ -5522,7 +5693,7 @@ static void fill_port_2(PORT_INFO_2 *port, char *name)
/****************************************************************************
enumports level 1.
****************************************************************************/
-static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PORT_INFO_1 *ports=NULL;
int i=0;
@@ -5544,7 +5715,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (fd != -1)
close(fd);
/* Is this the best error to return here? */
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
numlines = 0;
@@ -5554,9 +5725,10 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if(numlines) {
if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
- DEBUG(10,("Returning ERRnomem [%x]\n", ERRnomem));
+ DEBUG(10,("Returning WERR_NOMEM [%s]\n",
+ werror_str(WERR_NOMEM)));
file_lines_free(qlines);
- return ERRnomem;
+ return WERR_NOMEM;
}
for (i=0; i<numlines; i++) {
@@ -5573,7 +5745,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*returned = 1; /* Sole Samba port returned. */
if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
@@ -5587,8 +5759,8 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
}
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(ports);
- return ERRinsufficientbuffer;
+ SAFE_FREE(ports);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the ports structures */
@@ -5597,21 +5769,21 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
smb_io_port_1("", buffer, &ports[i], 0);
}
- safe_free(ports);
+ SAFE_FREE(ports);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
enumports level 2.
****************************************************************************/
-static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PORT_INFO_2 *ports=NULL;
int i=0;
@@ -5642,7 +5814,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (fd != -1)
close(fd);
/* Is this the best error to return here? */
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
numlines = 0;
@@ -5652,9 +5824,8 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if(numlines) {
if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
- DEBUG(10,("Returning ERRnomem [%x]\n", ERRnomem));
file_lines_free(qlines);
- return ERRnomem;
+ return WERR_NOMEM;
}
for (i=0; i<numlines; i++) {
@@ -5672,7 +5843,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*returned = 1;
if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
@@ -5686,8 +5857,8 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
}
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(ports);
- return ERRinsufficientbuffer;
+ SAFE_FREE(ports);
+ return WERR_INSUFFICIENT_BUFFER;
}
/* fill the buffer with the ports structures */
@@ -5696,21 +5867,21 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
smb_io_port_2("", buffer, &ports[i], 0);
}
- safe_free(ports);
+ SAFE_FREE(ports);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
enumports.
****************************************************************************/
-uint32 _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
+WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
{
/* UNISTR2 *name = &q_u->name; - notused. */
uint32 level = q_u->level;
@@ -5734,50 +5905,63 @@ uint32 _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUM
case 2:
return enumports_level_2(buffer, offered, needed, returned);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
+static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
const SPOOL_PRINTER_INFO_LEVEL *info,
- uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
+ DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
uint32 user_switch, const SPOOL_USER_CTR *user,
POLICY_HND *handle)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- fstring name;
- int snum;
+ fstring name;
+ int snum;
+ WERROR err = WERR_OK;
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
- return ERRnomem;
+ return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
- convert_printer_info(info, printer, 2);
+ if (!convert_printer_info(info, printer, 2)) {
+ free_a_printer(&printer, 2);
+ return WERR_NOMEM;
+ }
+
+ /* check to see if the printer already exists */
+
+ if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
+ DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
+ printer->info_2->sharename));
+ free_a_printer(&printer, 2);
+ return WERR_PRINTER_ALREADY_EXISTS;
+ }
if (*lp_addprinter_cmd() )
if ( !add_printer_hook(printer) ) {
free_a_printer(&printer,2);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
- slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
+ slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(),
printer->info_2->sharename);
if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
free_a_printer(&printer,2);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
/* you must be a printer admin to add a new printer */
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
free_a_printer(&printer,2);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
/*
@@ -5786,48 +5970,62 @@ static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
if (!check_printer_ok(printer->info_2, snum)) {
free_a_printer(&printer,2);
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
- /*
+ /*
* When a printer is created, the drivername bound to the printer is used
* to lookup previously saved driver initialization info, which is then
* bound to the new printer, simulating what happens in the Windows arch.
*/
+
+ if (!devmode)
+ set_driver_init(printer, 2);
+ else {
+ /* A valid devmode was included, convert and link it
+ */
+ DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
+
+ if (!convert_devicemode(printer->info_2->printername, devmode,
+ &printer->info_2->devmode))
+ return WERR_NOMEM;
+ }
+
set_driver_init(printer, 2);
/* write the ASCII on disk */
- if (add_a_printer(*printer, 2) != 0) {
+ err = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(err)) {
free_a_printer(&printer,2);
- return ERRnoaccess;
+ return err;
}
if (!open_printer_hnd(p, handle, name)) {
/* Handle open failed - remove addition. */
del_a_printer(printer->info_2->sharename);
free_a_printer(&printer,2);
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
free_a_printer(&printer,2);
- srv_spoolss_sendnotify(p, handle);
+ update_c_setprinter(False);
- return ERRsuccess;
+ srv_spoolss_sendnotify(0, PRINTER_CHANGE_ADD_PRINTER);
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
+WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
{
UNISTR2 *uni_srv_name = &q_u->server_name;
uint32 level = q_u->level;
SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
- uint32 unk0 = q_u->unk0;
- uint32 unk1 = q_u->unk1;
- uint32 unk2 = q_u->unk2;
- uint32 unk3 = q_u->unk3;
+ DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
+ SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
uint32 user_switch = q_u->user_switch;
SPOOL_USER_CTR *user = &q_u->user_ctr;
POLICY_HND *handle = &r_u->handle;
@@ -5836,26 +6034,25 @@ uint32 _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_
case 1:
/* we don't handle yet */
/* but I know what to do ... */
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
case 2:
return spoolss_addprinterex_level_2(p, uni_srv_name, info,
- unk0, unk1, unk2, unk3,
+ devmode, sdb,
user_switch, user, handle);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
+WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
{
/* UNISTR2 *server_name = &q_u->server_name; - notused. */
uint32 level = q_u->level;
SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
-
- uint32 err = ERRsuccess;
+ WERROR err = WERR_OK;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
struct current_user user;
@@ -5863,21 +6060,25 @@ uint32 _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
get_current_user(&user, p);
- convert_printer_driver_info(info, &driver, level);
+ if (!convert_printer_driver_info(info, &driver, level)) {
+ err = WERR_NOMEM;
+ goto done;
+ }
DEBUG(5,("Cleaning driver's information\n"));
- if ((err = clean_up_driver_struct(driver, level, &user)) != ERRsuccess )
+ err = clean_up_driver_struct(driver, level, &user);
+ if (!W_ERROR_IS_OK(err))
goto done;
DEBUG(5,("Moving driver to final destination\n"));
if(!move_driver_to_download_area(driver, level, &user, &err)) {
- if (err == 0)
- err = ERRnoaccess;
+ if (W_ERROR_IS_OK(err))
+ err = WERR_ACCESS_DENIED;
goto done;
}
if (add_a_printer_driver(driver, level)!=0) {
- err = ERRnoaccess;
+ err = WERR_ACCESS_DENIED;
goto done;
}
@@ -5895,22 +6096,38 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
pstring path;
pstring long_archi;
pstring short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
-
+#if 0
+ fstring asc_name, servername;
+#endif
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
if (get_short_archi(short_archi, long_archi)==False)
- return ERRinvalidenvironment;
+ return WERR_INVALID_ENVIRONMENT;
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
+
+#if 0 /* JERRY */
+ /* use the name the client sent us */
+
+ unistr2_to_ascii(asc_name, name, sizeof(asc_name)-1);
+ if (asc_name[0] == '\\' && asc_name[1] == '\\')
+ fstrcpy(servername, asc_name);
+ else {
+ fstrcpy(servername, "\\\\");
+ fstrcat(servername, asc_name);
+ }
+
+ slprintf(path, sizeof(path)-1, "%s\\print$\\%s", servername, short_archi);
+#endif
- slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
+ slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
DEBUG(4,("printer driver directory: [%s]\n", path));
@@ -5919,24 +6136,24 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
*needed += spoolss_size_driverdir_info_1(info);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info);
+ return WERR_INSUFFICIENT_BUFFER;
}
smb_io_driverdir_1("", buffer, info, 0);
- safe_free(info);
+ SAFE_FREE(info);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
+WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
{
UNISTR2 *name = &q_u->name;
UNISTR2 *uni_environment = &q_u->environment;
@@ -5957,14 +6174,14 @@ uint32 _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
case 1:
return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
+WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 idx = q_u->index;
@@ -5990,13 +6207,10 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
int snum;
uint8 *data=NULL;
uint32 type;
+ WERROR result;
ZERO_STRUCT(printer);
- *out_max_value_len=0;
- *out_value=NULL;
- *out_value_len=0;
-
*out_type=0;
*out_max_data_len=0;
@@ -6006,15 +6220,16 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
DEBUG(5,("spoolss_enumprinterdata\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
if (!get_printer_snum(p,handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
- if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERRbadfid;
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result))
+ return result;
/*
* The NT machine wants to know the biggest size of value and data
@@ -6035,14 +6250,13 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*/
if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
- safe_free(data);
+ SAFE_FREE(data);
free_a_printer(&printer, 2);
- return ERRnomoreitems;
+ return WERR_NO_MORE_ITEMS;
}
#endif
- safe_free(data);
- data = NULL;
+ SAFE_FREE(data);
param_index=0;
biggest_valuesize=0;
@@ -6054,23 +6268,10 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
- safe_free(data);
- data = NULL;
+ SAFE_FREE(data);
param_index++;
}
- /*
- * I think this is correct, it doesn't break APW and
- * allows Gerald's Win32 test programs to work correctly,
- * but may need altering.... JRA.
- */
-
- if (param_index == 0) {
- /* No parameters found. */
- free_a_printer(&printer, 2);
- return ERRnomoreitems;
- }
-
/* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
*out_value_len=2*(1+biggest_valuesize);
*out_data_len=biggest_datasize;
@@ -6078,7 +6279,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
free_a_printer(&printer, 2);
- return ERRsuccess;
+ return WERR_OK;
}
/*
@@ -6087,9 +6288,26 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*/
if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
- safe_free(data);
+
+ SAFE_FREE(data);
free_a_printer(&printer, 2);
- return ERRnomoreitems;
+
+ /* out_value should default to "" or else NT4 has
+ problems unmarshalling the response */
+
+ *out_max_value_len=(in_value_len/sizeof(uint16));
+ if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
+
+ *out_value_len = (uint32)dos_PutUniCode((char *)*out_value, "", in_value_len, True);
+
+ /* the data is counted in bytes */
+ *out_max_data_len = in_data_len;
+ *out_data_len = in_data_len;
+ if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
+ return WERR_NOMEM;
+
+ return WERR_NO_MORE_ITEMS;
}
free_a_printer(&printer, 2);
@@ -6105,8 +6323,8 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*out_max_value_len=(in_value_len/sizeof(uint16));
if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
- safe_free(data);
- return ERRnomem;
+ SAFE_FREE(data);
+ return WERR_NOMEM;
}
*out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
@@ -6116,22 +6334,22 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
/* the data is counted in bytes */
*out_max_data_len=in_data_len;
if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
- safe_free(data);
- return ERRnomem;
+ SAFE_FREE(data);
+ return WERR_NOMEM;
}
memcpy(*data_out, data, (size_t)data_len);
*out_data_len=data_len;
- safe_free(data);
+ SAFE_FREE(data);
- return ERRsuccess;
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
+WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
UNISTR2 *value = &q_u->value;
@@ -6144,18 +6362,18 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_PARAM *param = NULL, old_param;
int snum=0;
- uint32 status = 0x0;
+ WERROR status = WERR_OK;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
DEBUG(5,("spoolss_setprinterdata\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
if (!get_printer_snum(p,handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
ZERO_STRUCT(old_param);
@@ -6170,22 +6388,23 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("security descriptor change denied by existing "
"security descriptor\n"));
- status = ERRnoaccess;
+ status = WERR_ACCESS_DENIED;
goto done;
}
-
/* Check if we are making any changes or not. Return true if
nothing is actually changing. This is not needed anymore but
has been left in as an optimization to keep from from
writing to disk as often --jerry */
status = get_a_printer(&printer, 2, lp_servicename(snum));
- if (status != 0x0)
- return ERRinvalidname;
+ if (!W_ERROR_IS_OK(status))
+ return status;
convert_specific_param(&param, value , type, data, real_len);
+#if 0
+ /* JRA. W2K always changes changeid. */
if (get_specific_param(*printer, 2, param->value, &old_param.data,
&old_param.type, (uint32 *)&old_param.data_len)) {
@@ -6196,10 +6415,11 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
old_param.data_len) == 0) {
DEBUG(3, ("setprinterdata hasn't changed\n"));
- status = ERRsuccess;
+ status = WERR_OK;
goto done;
}
}
+#endif
unlink_specific_param_if_exist(printer->info_2, param);
@@ -6223,7 +6443,12 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
free_a_printer(&printer, 2);
if (param)
free_nt_printer_param(&param);
- safe_free(old_param.data);
+ SAFE_FREE(old_param.data);
+
+#if 0
+ /* Is this correct. JRA ? */
+ srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER);
+#endif
return status;
}
@@ -6231,7 +6456,7 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
+WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
{
POLICY_HND *handle = &q_u->handle;
UNISTR2 *value = &q_u->valuename;
@@ -6239,34 +6464,34 @@ uint32 _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
NT_PRINTER_INFO_LEVEL *printer = NULL;
NT_PRINTER_PARAM param;
int snum=0;
- uint32 status = 0x0;
+ WERROR status = WERR_OK;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
DEBUG(5,("spoolss_deleteprinterdata\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
"change denied by existing security descriptor\n"));
- return ERRnoaccess;
+ return WERR_ACCESS_DENIED;
}
status = get_a_printer(&printer, 2, lp_servicename(snum));
- if (status != 0x0)
- return ERRinvalidname;
+ if (!W_ERROR_IS_OK(status))
+ return status;
ZERO_STRUCTP(&param);
unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
if(!unlink_specific_param_if_exist(printer->info_2, &param))
- status = ERRinvalidparam;
+ status = WERR_INVALID_PARAM;
else
status = mod_a_printer(*printer, 2);
@@ -6277,12 +6502,15 @@ uint32 _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
+WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
+ int snum;
+ WERROR status = WERR_OK;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
int count=0;
nt_forms_struct *list=NULL;
@@ -6291,55 +6519,101 @@ uint32 _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
DEBUG(5,("spoolss_addform\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
+ /*
+ * FIXME!! Feels like there should be an access check here, but haven't
+ * had time to verify. --jerry
+ */
+
+
+ if (!get_printer_snum(p,handle, &snum))
+ return WERR_BADFID;
+
/* can't add if builtin */
if (get_a_builtin_ntform(&form->name,&tmpForm)) {
- return ERRinvalidparam;
+ return WERR_ALREADY_EXISTS;
}
count=get_ntforms(&list);
if(!add_a_form(&list, form, &count))
- return ERRnomem;
+ return WERR_NOMEM;
write_ntforms(&list, count);
+
+ /*
+ * ChangeID must always be set
+ */
+
+ if (!get_printer_snum(p,handle, &snum))
+ return WERR_BADFID;
- safe_free(list);
+ 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;
+
+done:
+ free_a_printer(&printer, 2);
+ SAFE_FREE(list);
- return 0x0;
+ return status;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
+WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
UNISTR2 *form_name = &q_u->name;
nt_forms_struct tmpForm;
int count=0;
- uint32 ret = 0;
+ WERROR ret = WERR_OK;
nt_forms_struct *list=NULL;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum;
+ WERROR status = WERR_OK;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
DEBUG(5,("spoolss_deleteform\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
/* can't delete if builtin */
if (get_a_builtin_ntform(form_name,&tmpForm)) {
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
count = get_ntforms(&list);
if(!delete_a_form(&list, form_name, &count, &ret))
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
- safe_free(list);
+ /*
+ * ChangeID must always be set
+ */
+
+ 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;
+
+ status = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(status))
+ goto done;
+
+done:
+ free_a_printer(&printer, 2);
+ SAFE_FREE(list);
return ret;
}
@@ -6347,13 +6621,16 @@ uint32 _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
+WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
{
POLICY_HND *handle = &q_u->handle;
/* UNISTR2 *uni_name = &q_u->name; - notused. */
/* uint32 level = q_u->level; - notused. */
FORM *form = &q_u->form;
nt_forms_struct tmpForm;
+ int snum;
+ WERROR status = WERR_OK;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
int count=0;
nt_forms_struct *list=NULL;
@@ -6362,32 +6639,49 @@ uint32 _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *
DEBUG(5,("spoolss_setform\n"));
if (!Printer) {
- DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERRbadfid;
+ DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
}
/* can't set if builtin */
if (get_a_builtin_ntform(&form->name,&tmpForm)) {
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
count=get_ntforms(&list);
update_a_form(&list, form, count);
write_ntforms(&list, count);
- safe_free(list);
+ /*
+ * ChangeID must always be set
+ */
+
+ 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;
+
+ status = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(status))
+ goto done;
+
+done:
+ free_a_printer(&printer, 2);
+ SAFE_FREE(list);
- return 0x0;
+ return WERR_OK;
}
/****************************************************************************
enumprintprocessors level 1.
****************************************************************************/
-static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCESSOR_1 *info_1=NULL;
if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
(*returned) = 0x1;
@@ -6396,24 +6690,24 @@ static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
*needed += spoolss_size_printprocessor_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
smb_io_printprocessor_info_1("", buffer, info_1, 0);
- safe_free(info_1);
+ SAFE_FREE(info_1);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
+WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
{
/* UNISTR2 *name = &q_u->name; - notused. */
/* UNISTR2 *environment = &q_u->environment; - notused. */
@@ -6443,19 +6737,19 @@ uint32 _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
case 1:
return enumprintprocessors_level_1(buffer, offered, needed, returned);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
enumprintprocdatatypes level 1.
****************************************************************************/
-static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCDATATYPE_1 *info_1=NULL;
if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
(*returned) = 0x1;
@@ -6464,24 +6758,24 @@ static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
*needed += spoolss_size_printprocdatatype_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
- safe_free(info_1);
+ SAFE_FREE(info_1);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
+WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
{
/* UNISTR2 *name = &q_u->name; - notused. */
/* UNISTR2 *processor = &q_u->processor; - notused. */
@@ -6504,7 +6798,7 @@ uint32 _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
case 1:
return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
@@ -6512,12 +6806,12 @@ uint32 _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
enumprintmonitors level 1.
****************************************************************************/
-static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_1 *info_1=NULL;
if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
(*returned) = 0x1;
@@ -6526,29 +6820,29 @@ static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
smb_io_printmonitor_info_1("", buffer, info_1, 0);
- safe_free(info_1);
+ SAFE_FREE(info_1);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
enumprintmonitors level 2.
****************************************************************************/
-static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_2 *info_2=NULL;
if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
- return ERRnomem;
+ return WERR_NOMEM;
(*returned) = 0x1;
@@ -6559,24 +6853,24 @@ static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_2(info_2);
if (!alloc_buffer_size(buffer, *needed))
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
smb_io_printmonitor_info_2("", buffer, info_2, 0);
- safe_free(info_2);
+ SAFE_FREE(info_2);
if (*needed > offered) {
*returned=0;
- return ERRinsufficientbuffer;
+ return WERR_INSUFFICIENT_BUFFER;
}
- else
- return ERRsuccess;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
+WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
{
/* UNISTR2 *name = &q_u->name; - notused. */
uint32 level = q_u->level;
@@ -6607,13 +6901,13 @@ uint32 _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
case 2:
return enumprintmonitors_level_2(buffer, offered, needed, returned);
default:
- return ERRunknownlevel;
+ return WERR_UNKNOWN_LEVEL;
}
}
/****************************************************************************
****************************************************************************/
-static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
int i=0;
BOOL found=False;
@@ -6622,8 +6916,8 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
if (info_1 == NULL) {
- safe_free(queue);
- return ERRnomem;
+ SAFE_FREE(queue);
+ return WERR_NOMEM;
}
for (i=0; i<count && found==False; i++) {
@@ -6632,50 +6926,51 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
}
if (found==False) {
- safe_free(queue);
- safe_free(info_1);
+ SAFE_FREE(queue);
+ SAFE_FREE(info_1);
/* NT treats not found as bad param... yet another bad choice */
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
fill_job_info_1(info_1, &(queue[i-1]), i, snum);
- safe_free(queue);
+ SAFE_FREE(queue);
*needed += spoolss_size_job_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info_1);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info_1);
+ return WERR_INSUFFICIENT_BUFFER;
}
smb_io_job_info_1("", buffer, info_1, 0);
- safe_free(info_1);
+ SAFE_FREE(info_1);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
{
int i=0;
BOOL found=False;
JOB_INFO_2 *info_2;
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+ WERROR ret;
info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
ZERO_STRUCTP(info_2);
if (info_2 == NULL) {
- safe_free(queue);
- return ERRnomem;
+ SAFE_FREE(queue);
+ return WERR_NOMEM;
}
for (i=0; i<count && found==False; i++) {
@@ -6684,44 +6979,45 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
}
if (found==False) {
- safe_free(queue);
- safe_free(info_2);
+ SAFE_FREE(queue);
+ SAFE_FREE(info_2);
/* NT treats not found as bad param... yet another bad choice */
- return ERRinvalidparam;
+ return WERR_INVALID_PARAM;
}
- if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0) {
- safe_free(queue);
- return ERRnomem;
+ ret = get_a_printer(&ntprinter, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(ret)) {
+ SAFE_FREE(queue);
+ return ret;
}
fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter);
free_a_printer(&ntprinter, 2);
- safe_free(queue);
+ SAFE_FREE(queue);
*needed += spoolss_size_job_info_2(info_2);
if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info_2);
- return ERRinsufficientbuffer;
+ SAFE_FREE(info_2);
+ return WERR_INSUFFICIENT_BUFFER;
}
smb_io_job_info_2("", buffer, info_2, 0);
free_job_info_2(info_2);
- free(info_2);
+ SAFE_FREE(info_2);
if (*needed > offered)
- return ERRinsufficientbuffer;
- else
- return ERRsuccess;
+ return WERR_INSUFFICIENT_BUFFER;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
+WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
{
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
@@ -6741,12 +7037,10 @@ uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
DEBUG(5,("spoolss_getjob\n"));
- memset(&prt_status, 0, sizeof(prt_status));
-
*needed=0;
if (!get_printer_snum(p, handle, &snum))
- return ERRbadfid;
+ return WERR_BADFID;
count = print_queue_status(snum, &queue, &prt_status);
@@ -6759,7 +7053,415 @@ uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
case 2:
return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
default:
- safe_free(queue);
- return ERRunknownlevel;
+ SAFE_FREE(queue);
+ return WERR_UNKNOWN_LEVEL;
}
}
+
+/********************************************************************
+ * spoolss_getprinterdataex
+ ********************************************************************/
+
+WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
+{
+ POLICY_HND *handle = &q_u->handle;
+ 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 key, value;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ BOOL found = False;
+
+ 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);
+
+ /* in case of problem, return some default values */
+ *needed=0;
+ *type=0;
+ *out_size=0;
+
+
+ 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;
+ }
+
+
+ /* Is the handle to a printer or to the server? */
+
+ if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
+ {
+ DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
+ return WERR_INVALID_PARAM;
+ }
+ 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
+ */
+
+ if (strcmp(key, "PrinterDriverData") != 0)
+ return WERR_INVALID_PARAM;
+
+ DEBUG(10, ("_spoolss_getprinterdataex: pass me to getprinterdata\n"));
+ found = getprinterdata_printer(p, p->mem_ctx, handle, value,
+ type, data, needed, in_size);
+
+ }
+
+ if (!found) {
+ DEBUG(5, ("value not found, 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 {
+ *data = NULL;
+ }
+
+ return WERR_INVALID_PARAM;
+ }
+
+ if (*needed > *out_size)
+ return WERR_MORE_DATA;
+ else
+ return WERR_OK;
+}
+
+/********************************************************************
+ * spoolss_setprinterdata
+ ********************************************************************/
+
+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;
+
+ 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 (strcmp(key, "PrinterDriverData") == 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;
+
+ return _spoolss_setprinterdata(p, &q_u_local, &r_u_local);
+}
+
+/********************************************************************
+ * spoolss_enumprinterkey
+ ********************************************************************/
+
+/* constants for EnumPrinterKey() */
+#define ENUMERATED_KEY_SIZE 19
+
+WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
+{
+ fstring key;
+ uint16 enumkeys[ENUMERATED_KEY_SIZE+1];
+ char* ptr = NULL;
+ int i;
+ char *PrinterKey = "PrinterDriverData";
+
+ DEBUG(4,("_spoolss_enumprinterkey\n"));
+
+ unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
+
+ /*
+ * we only support enumating all keys (key == "")
+ * Of course, the only key we support is the "PrinterDriverData"
+ * key
+ */
+ if (strlen(key) == 0)
+ {
+ r_u->needed = ENUMERATED_KEY_SIZE *2;
+ if (q_u->size < r_u->needed)
+ return WERR_MORE_DATA;
+
+ ptr = PrinterKey;
+ for (i=0; i<ENUMERATED_KEY_SIZE-2; i++)
+ {
+ enumkeys[i] = (uint16)(*ptr);
+ ptr++;
+ }
+
+ /* tag of with 2 '\0's */
+ enumkeys[i++] = '\0';
+ enumkeys[i] = '\0';
+
+ if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, ENUMERATED_KEY_SIZE, enumkeys))
+ return WERR_BADFILE;
+
+ return WERR_OK;
+ }
+
+ /* The "PrinterDriverData" key should have no subkeys */
+ if (strcmp(key, PrinterKey) == 0)
+ {
+ r_u-> needed = 2;
+ if (q_u->size < r_u->needed)
+ return WERR_MORE_DATA;
+ enumkeys[0] = 0x0;
+ if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, 1, enumkeys))
+ return WERR_BADFILE;
+
+ return WERR_OK;
+ }
+
+
+ /* The return value for an unknown key is documented in MSDN
+ EnumPrinterKey description */
+ return WERR_BADFILE;
+}
+
+/********************************************************************
+ * spoolss_enumprinterdataex
+ ********************************************************************/
+
+WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
+{
+ POLICY_HND *handle = &q_u->handle;
+ uint32 in_size = q_u->size;
+ uint32 num_entries,
+ needed;
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ PRINTER_ENUM_VALUES *enum_values = NULL;
+ fstring key, value;
+ Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+ int snum;
+ uint32 param_index,
+ data_len,
+ type;
+ WERROR result;
+ uint8 *data=NULL;
+
+
+ DEBUG(4,("_spoolss_enumprinterdataex\n"));
+
+ if (!Printer) {
+ DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
+ return WERR_BADFID;
+ }
+
+
+ /*
+ * The only key we support is "PrinterDriverData". This should return
+ > an array of all the key/value pairs returned by EnumPrinterDataSee
+ * _spoolss_getprinterdataex() for details --jerry
+ */
+
+ unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
+ if (strcmp(key, "PrinterDriverData") != 0)
+ {
+ DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
+ return WERR_INVALID_PARAM;
+ }
+
+
+ if (!get_printer_snum(p,handle, &snum))
+ return WERR_BADFID;
+
+ ZERO_STRUCT(printer);
+ result = get_a_printer(&printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(result))
+ return result;
+
+
+ /*
+ * loop through all params and build the array to pass
+ * back to the client
+ */
+ result = WERR_OK;
+ param_index = 0;
+ needed = 0;
+ num_entries = 0;
+
+ while (get_specific_param_by_index(*printer, 2, param_index, value, &data, &type, &data_len))
+ {
+ PRINTER_ENUM_VALUES *ptr;
+ uint32 add_len = 0;
+
+ DEBUG(10,("retrieved value number [%d] [%s]\n", num_entries, value));
+
+ if ((ptr=talloc_realloc(p->mem_ctx, enum_values, (num_entries+1) * sizeof(PRINTER_ENUM_VALUES))) == NULL)
+ {
+ DEBUG(0,("talloc_realloc failed to allocate more memory!\n"));
+ result = WERR_NOMEM;
+ goto done;
+ }
+ enum_values = ptr;
+
+ /* copy the data */
+ init_unistr(&enum_values[num_entries].valuename, value);
+ enum_values[num_entries].value_len = (strlen(value)+1) * 2;
+ enum_values[num_entries].type = type;
+
+ /*
+ * NULL terminate REG_SZ
+ * FIXME!!! We should not be correctly problems in the way
+ * we store PrinterData here. Need to investogate
+ * SetPrinterData[Ex] --jerry
+ */
+
+ if (type == REG_SZ) {
+ /* fix alignment if the string was stored
+ in a bizarre fashion */
+ if ((data_len % 2) == 0)
+ add_len = 2;
+ else
+ add_len = data_len % 2;
+ }
+
+ if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) {
+ DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n"));
+ result = WERR_NOMEM;
+ goto done;
+ }
+ memcpy(enum_values[num_entries].data, data, data_len);
+ enum_values[num_entries].data_len = data_len + add_len;
+
+ /* keep track of the size of the array in bytes */
+
+ needed += spoolss_size_printer_enum_values(&enum_values[num_entries]);
+
+ num_entries++;
+ param_index++;
+ }
+
+ r_u->needed = needed;
+ r_u->returned = num_entries;
+
+ if (needed > in_size) {
+ result = WERR_MORE_DATA;
+ goto done;
+ }
+
+ /* copy data into the reply */
+
+ r_u->ctr.size = r_u->needed;
+ r_u->ctr.size_of_array = r_u->returned;
+ r_u->ctr.values = enum_values;
+
+
+
+done:
+ free_a_printer(&printer, 2);
+
+ return result;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+/* Disabled because it doesn't fix the bug I am looking at but it would be
+ a shame to throw away the code. -tpot */
+
+#if 0
+
+static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
+{
+ init_unistr(&info->name, name);
+}
+
+static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
+ UNISTR2 *environment,
+ NEW_BUFFER *buffer,
+ uint32 offered,
+ uint32 *needed)
+{
+ pstring path;
+ pstring long_archi;
+ pstring short_archi;
+ PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+
+ unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
+
+ if (get_short_archi(short_archi, long_archi)==FALSE)
+ return WERR_INVALID_ENVIRONMENT;
+
+ if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
+ return WERR_NOMEM;
+
+ /* Not sure what to return here - are UNC names valid here?.
+ Windows returns the string: C:\WINNT\System32\spool\PRTPROCS\W32X86
+ which is pretty bogus for a RPC. */
+
+ slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
+
+ DEBUG(4,("print processor directory: [%s]\n", path));
+
+ fill_printprocessordirectory_1(info, path);
+
+ *needed += spoolss_size_printprocessordirectory_info_1(info);
+
+ if (!alloc_buffer_size(buffer, *needed)) {
+ safe_free(info);
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+
+ smb_io_printprocessordirectory_1("", buffer, info, 0);
+
+ safe_free(info);
+
+ if (*needed > offered)
+ return WERR_INSUFFICIENT_BUFFER;
+ else
+ return WERR_OK;
+}
+
+WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
+{
+ uint32 level = q_u->level;
+ NEW_BUFFER *buffer = NULL;
+ uint32 offered = q_u->offered;
+ uint32 *needed = &r_u->needed;
+
+ /* that's an [in out] buffer */
+ spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+
+ DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
+
+ *needed=0;
+
+ switch(level) {
+ case 1:
+ return getprintprocessordirectory_level_1
+ (&q_u->name, &q_u->environment, buffer, offered, needed);
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ return WERR_ACCESS_DENIED;
+}
+
+#endif
diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c
index fe008d0dde8..35bacc3458d 100644
--- a/source/rpc_server/srv_srvsvc.c
+++ b/source/rpc_server/srv_srvsvc.c
@@ -26,8 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
api_srv_net_srv_get_info
********************************************************************/
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index b50cdf3dc4d..d1fa83ce437 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -26,7 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
/*******************************************************************
@@ -117,34 +116,46 @@ static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
********************************************************************/
static TDB_CONTEXT *share_tdb; /* used for share security descriptors */
-#define SHARE_DATABASE_VERSION 1
+#define SHARE_DATABASE_VERSION_V1 1
+#define SHARE_DATABASE_VERSION_V2 2 /* version id in little endian. */
BOOL share_info_db_init(void)
{
- static pid_t local_pid;
- char *vstring = "INFO/version";
+ static pid_t local_pid;
+ char *vstring = "INFO/version";
+ int32 vers_id;
- if (share_tdb && local_pid == sys_getpid()) return True;
- share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!share_tdb) {
- DEBUG(0,("Failed to open share info database %s (%s)\n",
- lock_path("share_info.tdb"), strerror(errno) ));
- return False;
- }
+ if (share_tdb && local_pid == sys_getpid())
+ return True;
+ share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!share_tdb) {
+ DEBUG(0,("Failed to open share info database %s (%s)\n",
+ lock_path("share_info.tdb"), strerror(errno) ));
+ return False;
+ }
- local_pid = sys_getpid();
+ local_pid = sys_getpid();
- /* handle a Samba upgrade */
- tdb_lock_bystring(share_tdb, vstring);
- if (tdb_fetch_int(share_tdb, vstring) != SHARE_DATABASE_VERSION) {
- tdb_traverse(share_tdb, (tdb_traverse_func)tdb_delete, NULL);
- tdb_store_int(share_tdb, vstring, SHARE_DATABASE_VERSION);
- }
- tdb_unlock_bystring(share_tdb, vstring);
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(share_tdb, vstring);
+
+ /* Cope with byte-reversed older versions of the db. */
+ vers_id = tdb_fetch_int32(share_tdb, vstring);
+ if ((vers_id == SHARE_DATABASE_VERSION_V1) || (IREV(vers_id) == SHARE_DATABASE_VERSION_V1)) {
+ /* Written on a bigendian machine with old fetch_int code. Save as le. */
+ tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
+ vers_id = SHARE_DATABASE_VERSION_V2;
+ }
+
+ if (vers_id != SHARE_DATABASE_VERSION_V2) {
+ tdb_traverse(share_tdb, tdb_traverse_delete_fn, NULL);
+ tdb_store_int32(share_tdb, vstring, SHARE_DATABASE_VERSION_V2);
+ }
+ tdb_unlock_bystring(share_tdb, vstring);
message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated);
- return True;
+ return True;
}
/*******************************************************************
@@ -303,7 +314,8 @@ void map_generic_share_sd_bits(SEC_DESC *psd)
BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 desired_access)
{
- uint32 granted, status;
+ uint32 granted;
+ NTSTATUS status;
TALLOC_CTX *mem_ctx = NULL;
SEC_DESC *psd = NULL;
size_t sd_size;
@@ -530,7 +542,7 @@ static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n
static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
char *share_name, uint32 info_level)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
int snum;
DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
@@ -562,7 +574,7 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I
status = NT_STATUS_BAD_NETWORK_NAME;
}
- r_n->info.ptr_share_ctr = (status == NT_STATUS_OK) ? 1 : 0;
+ r_n->info.ptr_share_ctr = NT_STATUS_IS_OK(status) ? 1 : 0;
r_n->status = status;
}
@@ -679,10 +691,10 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
makes a SRV_R_NET_SESS_ENUM structure.
********************************************************************/
-static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
+static NTSTATUS init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -724,7 +736,7 @@ static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
else
r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- if (r_n->status != NT_STATUS_OK)
+ if (NT_STATUS_IS_ERR(r_n->status))
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -835,10 +847,10 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
makes a SRV_R_NET_CONN_ENUM structure.
********************************************************************/
-static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
+static NTSTATUS init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -879,7 +891,7 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
else
r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- if (r_n->status != NT_STATUS_OK)
+ if (NT_STATUS_IS_ERR(r_n->status))
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -935,10 +947,10 @@ static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+static NTSTATUS init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -975,7 +987,7 @@ static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
else
r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
- if (r_n->status != NT_STATUS_OK)
+ if (NT_STATUS_IS_ERR(r_n->status))
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -985,9 +997,9 @@ static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
net server get info
********************************************************************/
-uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
+NTSTATUS _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
{
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
if (!ctr)
@@ -1039,12 +1051,12 @@ uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R
net server set info
********************************************************************/
-uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
+NTSTATUS _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u)
{
/* NT gives "Windows NT error 0xc00000022" if we return
NT_STATUS_ACCESS_DENIED here so just pretend everything is OK. */
- uint32 status = NT_STATUS_OK;
+ NTSTATUS status = NT_STATUS_OK;
DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
@@ -1061,7 +1073,7 @@ uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R
net file enum
********************************************************************/
-uint32 _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
+NTSTATUS _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u)
{
r_u->ctr = (SRV_FILE_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_FILE_INFO_CTR));
if (!r_u->ctr)
@@ -1086,7 +1098,7 @@ uint32 _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_F
net conn enum
********************************************************************/
-uint32 _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
+NTSTATUS _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u)
{
DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
@@ -1111,7 +1123,7 @@ uint32 _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_C
net sess enum
********************************************************************/
-uint32 _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
+NTSTATUS _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u)
{
DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
@@ -1136,7 +1148,7 @@ uint32 _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_S
Net share enum all.
********************************************************************/
-uint32 _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
+NTSTATUS _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
{
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
@@ -1154,7 +1166,7 @@ uint32 _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R
Net share enum.
********************************************************************/
-uint32 _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
+NTSTATUS _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u)
{
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
@@ -1172,7 +1184,7 @@ uint32 _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET
Net share get info.
********************************************************************/
-uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
+NTSTATUS _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u)
{
fstring share_name;
@@ -1232,7 +1244,7 @@ static char *valid_share_pathname(char *dos_pathname)
Net share set info. Modify share details.
********************************************************************/
-uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
+NTSTATUS _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u)
{
struct current_user user;
pstring command;
@@ -1252,27 +1264,27 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
r_u->switch_value = 0;
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
snum = find_service(share_name);
/* Does this share exist ? */
if (snum < 0)
- return ERRnosuchshare;
+ return NT_STATUS_BAD_NETWORK_NAME;
/* No change to printer shares. */
if (lp_print_ok(snum))
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
get_current_user(&user,p);
if (user.uid != 0)
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
switch (q_u->info_level) {
case 1:
/* Not enough info in a level 1 to do anything. */
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
case 2:
unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
@@ -1287,7 +1299,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
map_generic_share_sd_bits(psd);
break;
case 1005:
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
case 1501:
fstrcpy(pathname, lp_pathname(snum));
fstrcpy(comment, lp_comment(snum));
@@ -1302,11 +1314,11 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* We can only modify disk shares. */
if (type != STYPE_DISKTREE)
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
/* Check if the pathname is valid. */
if (!(ptr = valid_share_pathname( pathname )))
- return ERRbadpath;
+ return NT_STATUS_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
@@ -1320,7 +1332,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
if (!lp_change_share_cmd() || !*lp_change_share_cmd())
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
lp_change_share_cmd(), CONFIGFILE, share_name, ptr, comment);
@@ -1328,7 +1340,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
}
/* Tell everyone we updated smb.conf. */
@@ -1361,7 +1373,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
Net share add. Call 'add_share_command "sharename" "pathname" "comment" "read only = xxx"'
********************************************************************/
-uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
+NTSTATUS _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u)
{
struct current_user user;
pstring command;
@@ -1382,18 +1394,18 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
if (user.uid != 0) {
DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
}
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
DEBUG(10,("_srv_net_share_add: No add share command\n"));
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
}
switch (q_u->info_level) {
case 1:
/* Not enough info in a level 1 to do anything. */
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
case 2:
unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
@@ -1410,28 +1422,28 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
break;
case 1005:
/* DFS only level. */
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
default:
DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
return NT_STATUS_INVALID_INFO_CLASS;
}
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
snum = find_service(share_name);
/* Share already exists. */
if (snum >= 0)
- return ERRfilexists;
+ return NT_STATUS_OBJECT_NAME_COLLISION;
/* We can only add disk shares. */
if (type != STYPE_DISKTREE)
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
/* Check if the pathname is valid. */
if (!(ptr = valid_share_pathname( pathname )))
- return ERRbadpath;
+ return NT_STATUS_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
@@ -1444,7 +1456,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
}
if (psd) {
@@ -1472,7 +1484,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
a parameter.
********************************************************************/
-uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
+NTSTATUS _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u)
{
struct current_user user;
pstring command;
@@ -1485,24 +1497,24 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
snum = find_service(share_name);
if (snum < 0)
- return ERRnosuchshare;
+ return NT_STATUS_BAD_NETWORK_NAME;
/* No change to printer shares. */
if (lp_print_ok(snum))
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
get_current_user(&user,p);
if (user.uid != 0)
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
lp_delete_share_cmd(), CONFIGFILE, lp_servicename(snum));
@@ -1510,7 +1522,7 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
- return ERRnoaccess;
+ return NT_STATUS_ACCESS_DENIED;
}
/* Delete the SD in the database. */
@@ -1528,7 +1540,7 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
time of day
********************************************************************/
-uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
+NTSTATUS _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u)
{
TIME_OF_DAY_INFO *tod;
struct tm *t;
@@ -1572,7 +1584,7 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
Win9x NT tools get security descriptor.
***********************************************************************************/
-uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
+NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u,
SRV_R_NET_FILE_QUERY_SECDESC *r_u)
{
SEC_DESC *psd = NULL;
@@ -1585,10 +1597,11 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
BOOL bad_path;
int access_mode;
int action;
- int ecode;
+ uint32 ecode;
struct current_user user;
fstring user_name;
connection_struct *conn = NULL;
+ BOOL became_user = False;
ZERO_STRUCT(st);
@@ -1602,14 +1615,23 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
get_current_user(&user, p);
fstrcpy(user_name, uidtoname(user.uid));
+ become_root();
conn = make_connection(qualname, user_name, null_pw, 0, "A:", user.vuid, &ecode);
+ unbecome_root();
if (conn == NULL) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
- r_u->status = (uint32)ecode;
+ r_u->status = NT_STATUS(ecode);
goto error_exit;
}
+ if (!become_user(conn, conn->vuid)) {
+ DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
+ r_u->status = NT_STATUS_ACCESS_DENIED;
+ goto error_exit;
+ }
+ became_user = True;
+
unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
unix_convert(filename, conn, NULL, &bad_path, &st);
fsp = open_file_shared(conn, filename, &st, SET_OPEN_MODE(DOS_OPEN_RDONLY),
@@ -1618,12 +1640,12 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
if (!fsp) {
/* Perhaps it is a directory */
if (errno == EISDIR)
- fsp = open_directory(conn, filename, &st,
+ fsp = open_directory(conn, filename, &st,0,
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
if (!fsp) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
- r_u->status = ERRnoaccess;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
goto error_exit;
}
}
@@ -1632,7 +1654,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
if (sd_size == 0) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
- r_u->status = ERRnoaccess;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
goto error_exit;
}
@@ -1645,7 +1667,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
psd->dacl->revision = (uint16) NT4_ACL_REVISION;
close_file(fsp, True);
-
+ unbecome_user();
close_cnum(conn, user.vuid);
return r_u->status;
@@ -1655,6 +1677,9 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
close_file(fsp, True);
}
+ if (became_user)
+ unbecome_user();
+
if (conn)
close_cnum(conn, user.vuid);
@@ -1665,7 +1690,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
Win9x NT tools set security descriptor.
***********************************************************************************/
-uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
+NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u,
SRV_R_NET_FILE_SET_SECDESC *r_u)
{
BOOL ret;
@@ -1695,17 +1720,19 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
get_current_user(&user, p);
fstrcpy(user_name, uidtoname(user.uid));
+ become_root();
conn = make_connection(qualname, user_name, null_pw, 0, "A:", user.vuid, &ecode);
+ unbecome_root();
if (conn == NULL) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
- r_u->status = (uint32)ecode;
+ r_u->status = NT_STATUS(ecode);
goto error_exit;
}
if (!become_user(conn, conn->vuid)) {
DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
- r_u->status = ERRnoaccess;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
goto error_exit;
}
became_user = True;
@@ -1719,12 +1746,12 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
if (!fsp) {
/* Perhaps it is a directory */
if (errno == EISDIR)
- fsp = open_directory(conn, filename, &st,
+ fsp = open_directory(conn, filename, &st,0,
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, &action);
if (!fsp) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
- r_u->status = ERRnoaccess;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
goto error_exit;
}
}
@@ -1733,7 +1760,7 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
if (ret == False) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
- r_u->status = ERRnoaccess;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
goto error_exit;
}
@@ -1803,7 +1830,7 @@ static const char *next_server_disk_enum(uint32 *resume)
return disk;
}
-uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
+NTSTATUS _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u)
{
uint32 i;
const char *disk_name;
@@ -1815,7 +1842,7 @@ uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
r_u->disk_enum_ctr.unknown = 0;
- r_u->disk_enum_ctr.disk_info_ptr = (uint32) r_u->disk_enum_ctr.disk_info;
+ r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
/*allow one DISK_INFO for null terminator*/
@@ -1839,7 +1866,7 @@ uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
return r_u->status;
}
-uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
+NTSTATUS _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
{
int snum;
fstring share_name;
@@ -1863,7 +1890,7 @@ uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
default:
/*unsupported type*/
- r_u->status = ERRunknownlevel;
+ r_u->status = NT_STATUS_INVALID_LEVEL;
break;
}
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 22e573402e9..a1e85d80f45 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -39,8 +39,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
* A list of the rids of well known BUILTIN and Domain users
* and groups.
@@ -197,7 +195,7 @@ void get_domain_user_groups(char *domain_groups, char *user)
/*******************************************************************
Look up a local (domain) rid and return a name and type.
********************************************************************/
-uint32 local_lookup_group_name(uint32 rid, char *group_name, uint32 *type)
+NTSTATUS local_lookup_group_name(uint32 rid, char *group_name, uint32 *type)
{
int i = 0;
(*type) = SID_NAME_DOM_GRP;
@@ -213,7 +211,7 @@ uint32 local_lookup_group_name(uint32 rid, char *group_name, uint32 *type)
{
fstrcpy(group_name, domain_group_rids[i].name);
DEBUG(5,(" = %s\n", group_name));
- return 0x0;
+ return NT_STATUS_OK;
}
DEBUG(5,(" none mapped\n"));
@@ -223,7 +221,7 @@ uint32 local_lookup_group_name(uint32 rid, char *group_name, uint32 *type)
/*******************************************************************
Look up a local alias rid and return a name and type.
********************************************************************/
-uint32 local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
+NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
{
int i = 0;
(*type) = SID_NAME_WKN_GRP;
@@ -239,7 +237,7 @@ uint32 local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
{
fstrcpy(alias_name, builtin_alias_rids[i].name);
DEBUG(5,(" = %s\n", alias_name));
- return 0x0;
+ return NT_STATUS_OK;
}
DEBUG(5,(" none mapped\n"));
@@ -249,7 +247,7 @@ uint32 local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
/*******************************************************************
Look up a local user rid and return a name and type.
********************************************************************/
-uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
+NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
{
SAM_ACCOUNT *sampwd=NULL;
int i = 0;
@@ -268,7 +266,7 @@ uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
if (domain_user_rids[i].rid != 0) {
fstrcpy(user_name, domain_user_rids[i].name);
DEBUG(5,(" = %s\n", user_name));
- return 0x0;
+ return NT_STATUS_OK;
}
pdb_init_sam(&sampwd);
@@ -282,7 +280,7 @@ uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
fstrcpy(user_name, pdb_get_username(sampwd) );
DEBUG(5,(" = %s\n", user_name));
pdb_free_sam(sampwd);
- return 0x0;
+ return NT_STATUS_OK;
}
DEBUG(5,(" none mapped\n"));
@@ -293,7 +291,7 @@ uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
/*******************************************************************
Look up a local (domain) group name and return a rid
********************************************************************/
-uint32 local_lookup_group_rid(char *group_name, uint32 *rid)
+NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid)
{
char *grp_name;
int i = -1; /* start do loop at -1 */
@@ -306,13 +304,13 @@ uint32 local_lookup_group_rid(char *group_name, uint32 *rid)
} while (grp_name != NULL && !strequal(grp_name, group_name));
- return (grp_name != NULL) ? 0 : NT_STATUS_NONE_MAPPED;
+ return (grp_name != NULL) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
Look up a local (BUILTIN) alias name and return a rid
********************************************************************/
-uint32 local_lookup_alias_rid(char *alias_name, uint32 *rid)
+NTSTATUS local_lookup_alias_rid(char *alias_name, uint32 *rid)
{
char *als_name;
int i = -1; /* start do loop at -1 */
@@ -325,13 +323,13 @@ uint32 local_lookup_alias_rid(char *alias_name, uint32 *rid)
} while (als_name != NULL && !strequal(als_name, alias_name));
- return (als_name != NULL) ? 0 : NT_STATUS_NONE_MAPPED;
+ return (als_name != NULL) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
Look up a local user name and return a rid
********************************************************************/
-uint32 local_lookup_user_rid(char *user_name, uint32 *rid)
+NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid)
{
SAM_ACCOUNT *sampass=NULL;
BOOL ret;
@@ -348,7 +346,7 @@ uint32 local_lookup_user_rid(char *user_name, uint32 *rid)
if (ret == True) {
(*rid) = pdb_get_user_rid(sampass);
pdb_free_sam(sampass);
- return 0x0;
+ return NT_STATUS_OK;
}
pdb_free_sam(sampass);
diff --git a/source/rpc_server/srv_wkssvc.c b/source/rpc_server/srv_wkssvc.c
index 12e4a8f3359..3661824da17 100644
--- a/source/rpc_server/srv_wkssvc.c
+++ b/source/rpc_server/srv_wkssvc.c
@@ -25,8 +25,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*******************************************************************
api_wks_query_info
********************************************************************/
diff --git a/source/rpc_server/srv_wkssvc_nt.c b/source/rpc_server/srv_wkssvc_nt.c
index c20ebb57067..74753021828 100644
--- a/source/rpc_server/srv_wkssvc_nt.c
+++ b/source/rpc_server/srv_wkssvc_nt.c
@@ -26,7 +26,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern pstring global_myname;
/*******************************************************************
@@ -60,7 +59,7 @@ static void create_wks_info_100(WKS_INFO_100 *inf)
********************************************************************/
-uint32 _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO *r_u)
+NTSTATUS _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO *r_u)
{
WKS_INFO_100 *wks100 = NULL;
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 5fe8509b215..8b3e49051ed 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -21,119 +21,85 @@
*/
#include "includes.h"
-
-extern int DEBUGLEVEL;
-extern pstring server;
+#include "rpcclient.h"
/* Look up domain related information on a remote host */
-static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char **argv)
+
+static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_policy_hnd = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID dom_sid;
fstring sid_str, domain_name;
uint32 info_class = 3;
- TALLOC_CTX *mem_ctx;
if (argc > 2) {
printf("Usage: %s [info_class]\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_lsa_query_info_poicy: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
- if (argc == 2) {
+ if (argc == 2)
info_class = atoi(argv[1]);
- }
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &pol);
- if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_policy_hnd = True;
/* Lookup info policy */
- if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
- domain_name, &dom_sid))
- != NT_STATUS_OK) {
+ result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
+ domain_name, &dom_sid);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
sid_to_string(sid_str, &dom_sid);
- printf("domain %s has sid %s\n", domain_name, sid_str);
-
-done:
-
- if (got_policy_hnd) {
- cli_lsa_close(cli, mem_ctx, &pol);
- }
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
+ if (domain_name[0])
+ printf("domain %s has sid %s\n", domain_name, sid_str);
+ else
+ printf("could not query info for level %d\n", info_class);
+ done:
return result;
}
/* Resolve a list of names to a list of sids */
-static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_policy_hnd = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID *sids;
uint32 *types;
int num_names, i;
- TALLOC_CTX *mem_ctx;
if (argc == 1) {
printf("Usage: %s [name1 [name2 [...]]]\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_lsa_lookup_names: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &pol);
- if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_policy_hnd = True;
/* Lookup the names */
- if ((result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
- &argv[1], &sids, &types, &num_names) !=
- NT_STATUS_OK)) {
+ result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
+ &argv[1], &sids, &types, &num_names);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
/* Print results */
@@ -141,85 +107,57 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv)
fstring sid_str;
sid_to_string(sid_str, &sids[i]);
- printf("%s\t\t%s (%d)\n", argv[i + 1], sid_str,
+ printf("%s %s (%d)\n", argv[i + 1], sid_str,
types[i]);
}
-#if 0 /* JERRY */
- safe_free(sids);
- safe_free(types);
-#endif
-
done:
-
- if (got_policy_hnd) {
- cli_lsa_close(cli, mem_ctx, &pol);
- }
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Resolve a list of SIDs to a list of names */
-static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_policy_hnd = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID *sids;
char **names;
uint32 *types;
int num_names, i;
- TALLOC_CTX *mem_ctx;
if (argc == 1) {
printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]);
- return 0;
+ return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_lsa_lookup_sids: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &pol);
- if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_policy_hnd = True;
/* Convert arguments to sids */
sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * (argc - 1));
if (!sids) {
- printf("out of memory\n");
+ printf("could not allocate memory for %d sids\n", argc - 1);
goto done;
}
- for (i = 0; i < argc - 1; i++) {
+ for (i = 0; i < argc - 1; i++)
string_to_sid(&sids[i], argv[i + 1]);
- }
/* Lookup the SIDs */
- if ((result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
- &names, &types, &num_names) !=
- NT_STATUS_OK)) {
+ result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
+ &names, &types, &num_names);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
/* Print results */
@@ -227,80 +165,48 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv)
fstring sid_str;
sid_to_string(sid_str, &sids[i]);
- printf("%s\t\t%s (%d)\n", sid_str, names[i] ? names[i] :
+ printf("%s %s (%d)\n", sid_str, names[i] ? names[i] :
"*unknown*", types[i]);
}
-#if 0 /* JERRY */
- safe_free(sids);
- safe_free(types);
-
- for (i = 0; i < num_names; i++) {
- safe_free(names[i]);
- }
-
- safe_free(names);
-#endif
-
done:
-
- if (got_policy_hnd) {
- cli_lsa_close(cli, mem_ctx, &pol);
- }
-
- cli_nt_session_close(cli);
- talloc_destroy (mem_ctx);
-
return result;
}
/* Enumerate list of trusted domains */
-static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
POLICY_HND pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_policy_hnd = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID *domain_sids;
char **domain_names;
uint32 enum_ctx = 0;
uint32 num_domains;
int i;
- TALLOC_CTX *mem_ctx;
if (argc != 1) {
printf("Usage: %s\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_lsa_enum_trust_dom: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_LSARPC)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &pol);
- if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_policy_hnd = True;
/* Lookup list of trusted domains */
- if ((result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
- &num_domains, &domain_names,
- &domain_sids)
- != NT_STATUS_OK)) {
+ result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
+ &num_domains, &domain_names,
+ &domain_sids);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
/* Print results */
@@ -308,39 +214,24 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg
fstring sid_str;
sid_to_string(sid_str, &domain_sids[i]);
- printf("%s\t\t%s\n", domain_names[i] ? domain_names[i] :
+ printf("%s %s\n", domain_names[i] ? domain_names[i] :
"*unknown*", sid_str);
}
-#if 0 /* JERRY */
- safe_free(domain_sids);
-
- for (i = 0; i < num_domains; i++) {
- safe_free(domain_names[i]);
- }
-
- safe_free(domain_names);
-#endif
-
done:
-
- if (got_policy_hnd) {
- cli_lsa_close(cli, mem_ctx, &pol);
- }
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* List of commands exported by this module */
struct cmd_set lsarpc_commands[] = {
- { "LSARPC", NULL, "" },
- { "lsaquery", cmd_lsa_query_info_policy, "Query info policy" },
- { "lookupsids", cmd_lsa_lookup_sids, "Convert SIDs to names" },
- { "lookupnames",cmd_lsa_lookup_names, "Convert names to SIDs" },
- { "enumtrust", cmd_lsa_enum_trust_dom, "Enumerate trusted domains" },
- { NULL, NULL, NULL }
+
+ { "LSARPC" },
+
+ { "lsaquery", cmd_lsa_query_info_policy, PIPE_LSARPC, "Query info policy", "" },
+ { "lookupsids", cmd_lsa_lookup_sids, PIPE_LSARPC, "Convert SIDs to names", "" },
+ { "lookupnames", cmd_lsa_lookup_names, PIPE_LSARPC, "Convert names to SIDs", "" },
+ { "enumtrust", cmd_lsa_enum_trust_dom, PIPE_LSARPC, "Enumerate trusted domains", "" },
+
+ { NULL }
};
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 375f6765665..524ff5fb49f 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -21,37 +21,24 @@
*/
#include "includes.h"
+#include "rpcclient.h"
-extern int DEBUGLEVEL;
-
-static uint32 cmd_netlogon_logon_ctrl2(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
uint32 query_level = 1;
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (argc > 1) {
- printf("Usage: %s\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0,("cmd_srvsvc_srv_query_info: talloc_init failed\n"));
- goto done;
+ fprintf(stderr, "Usage: %s\n", argv[0]);
+ return NT_STATUS_OK;
}
- /* Initialise RPC connection */
+ result = cli_netlogon_logon_ctrl2(cli, mem_ctx, query_level);
- if (!cli_nt_session_open (cli, PIPE_NETLOGON)) {
- DEBUG(0, ("Could not initialize srvsvc pipe!\n"));
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- if ((result = cli_netlogon_logon_ctrl2(cli, mem_ctx, query_level))
- != NT_STATUS_OK) {
- goto done;
- }
/* Display results */
@@ -59,50 +46,286 @@ static uint32 cmd_netlogon_logon_ctrl2(struct cli_state *cli, int argc,
return result;
}
-static uint32 cmd_netlogon_logon_ctrl(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_netlogon_logon_ctrl(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
{
#if 0
uint32 query_level = 1;
#endif
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (argc > 1) {
- printf("Usage: %s\n", argv[0]);
- return 0;
+ fprintf(stderr, "Usage: %s\n", argv[0]);
+ return NT_STATUS_OK;
}
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0,("cmd_srvsvc_srv_query_info: talloc_init failed\n"));
+#if 0
+ result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
+#endif
+
+ /* Display results */
+
+ return result;
+}
+
+/* Display sam synchronisation information */
+
+static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas)
+{
+ fstring name;
+ uint32 i, j;
+
+ for (i = 0; i < num_deltas; i++) {
+ switch (hdr_deltas[i].type) {
+ case SAM_DELTA_DOMAIN_INFO:
+ unistr2_to_ascii(name,
+ &deltas[i].domain_info.uni_dom_name,
+ sizeof(name) - 1);
+ printf("Domain: %s\n", name);
+ break;
+ case SAM_DELTA_GROUP_INFO:
+ unistr2_to_ascii(name,
+ &deltas[i].group_info.uni_grp_name,
+ sizeof(name) - 1);
+ printf("Group: %s\n", name);
+ break;
+ case SAM_DELTA_ACCOUNT_INFO:
+ unistr2_to_ascii(name,
+ &deltas[i].account_info.uni_acct_name,
+ sizeof(name) - 1);
+ printf("Account: %s\n", name);
+ break;
+ case SAM_DELTA_ALIAS_INFO:
+ unistr2_to_ascii(name,
+ &deltas[i].alias_info.uni_als_name,
+ sizeof(name) - 1);
+ printf("Alias: %s\n", name);
+ break;
+ case SAM_DELTA_ALIAS_MEM: {
+ SAM_ALIAS_MEM_INFO *alias = &deltas[i].als_mem_info;
+
+ for (j = 0; j < alias->num_members; j++) {
+ fstring sid_str;
+
+ sid_to_string(sid_str, &alias->sids[j].sid);
+
+ printf("%s\n", sid_str);
+ }
+ break;
+ }
+ case SAM_DELTA_GROUP_MEM: {
+ SAM_GROUP_MEM_INFO *group = &deltas[i].grp_mem_info;
- /* Initialise RPC connection */
+ for (j = 0; j < group->num_members; j++)
+ printf("rid 0x%x, attrib 0x%08x\n",
+ group->rids[j], group->attribs[j]);
+ break;
+ }
+ case SAM_DELTA_SAM_STAMP: {
+ SAM_DELTA_STAMP *stamp = &deltas[i].stamp;
- if (!cli_nt_session_open (cli, PIPE_NETLOGON)) {
- DEBUG(0, ("Could not initialize srvsvc pipe!\n"));
+ printf("sam sequence update: 0x%04x\n",
+ stamp->seqnum);
+ break;
+ }
+ default:
+ printf("unknown delta type 0x%02x\n",
+ hdr_deltas[i].type);
+ break;
+ }
+ }
+}
+
+/* Perform sam synchronisation */
+
+static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ unsigned char trust_passwd[16];
+ uint32 database_id = 0, num_deltas;
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+
+ if (argc > 2) {
+ fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if (argc == 2)
+ database_id = atoi(argv[1]);
+
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ return result;
+ }
+
+ /* Initialise session credentials */
+
+ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
+ NULL)) {
+ fprintf(stderr, "could not fetch trust account password\n");
goto done;
- }
+ }
-#if 0
- if ((result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level))
- != NT_STATUS_OK) {
+ result = cli_nt_setup_creds(cli, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
+ }
+
+ /* Synchronise sam database */
+
+ result = cli_netlogon_sam_sync(cli, mem_ctx, database_id,
+ &num_deltas, &hdr_deltas, &deltas);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-#endif
- /* Display results */
+ /* Display results */
+
+ display_sam_sync(num_deltas, hdr_deltas, deltas);
done:
- return result;
+ return result;
+}
+
+/* Perform sam delta synchronisation */
+
+static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ unsigned char trust_passwd[16];
+ uint32 database_id, num_deltas, tmp;
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+ UINT64_S seqnum;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ database_id = atoi(argv[1]);
+ tmp = atoi(argv[2]);
+
+ seqnum.low = tmp & 0xffff;
+ seqnum.high = 0;
+
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ goto done;
+ }
+
+ /* Initialise session credentials */
+
+ 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, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
+ }
+
+ /* Synchronise sam database */
+
+ result = cli_netlogon_sam_deltas(cli, mem_ctx, database_id,
+ seqnum, &num_deltas,
+ &hdr_deltas, &deltas);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Display results */
+
+ display_sam_sync(num_deltas, hdr_deltas, deltas);
+
+ done:
+ return result;
+}
+
+/* Log on a domain user */
+
+static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ char **argv)
+{
+ unsigned char trust_passwd[16];
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ int logon_type = NET_LOGON_TYPE;
+ char *username, *password;
+
+ /* Check arguments */
+
+ if (argc < 3 || argc > 4) {
+ fprintf(stderr, "Usage: samlogon <username> <password> "
+ "[logon_type]\n");
+ return NT_STATUS_OK;
+ }
+
+ username = argv[1];
+ password = argv[2];
+
+ if (argc == 4)
+ sscanf(argv[3], "%i", &logon_type);
+
+ /* Authenticate ourselves with the domain controller */
+
+ if (!secrets_init()) {
+ fprintf(stderr, "Unable to initialise secrets database\n");
+ return result;
+ }
+
+ 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, trust_passwd);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "Error initialising session creds\n");
+ goto done;
+ }
+
+ /* Perform the sam logon */
+
+ result = cli_netlogon_sam_logon(cli, mem_ctx, username, password,
+ logon_type);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ done:
+ return result;
}
/* List of commands exported by this module */
struct cmd_set netlogon_commands[] = {
- { "NETLOGON", NULL, "" },
- { "logonctrl2", cmd_netlogon_logon_ctrl2, "Logon Control 2" },
- { "logonctrl", cmd_netlogon_logon_ctrl, "Logon Control" },
- { NULL, NULL, NULL }
+
+ { "NETLOGON" },
+
+ { "logonctrl2", cmd_netlogon_logon_ctrl2, PIPE_NETLOGON, "Logon Control 2", "" },
+ { "logonctrl", cmd_netlogon_logon_ctrl, PIPE_NETLOGON, "Logon Control", "" },
+ { "samsync", cmd_netlogon_sam_sync, PIPE_NETLOGON, "Sam Synchronisation", "" },
+ { "samdeltas", cmd_netlogon_sam_deltas, PIPE_NETLOGON, "Query Sam Deltas", "" },
+ { "samlogon", cmd_netlogon_sam_logon, PIPE_NETLOGON, "Sam Logon", "" },
+
+ { NULL }
};
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 2ee84f80873..68a75a70c91 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -24,6 +24,7 @@
*/
#include "includes.h"
+#include "rpcclient.h"
extern DOM_SID domain_sid;
@@ -135,91 +136,73 @@ void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
printf("Desc: %s\n", tmp);
}
+void display_sam_info_4(SAM_ENTRY4 *e4, SAM_STR4 *s4)
+{
+ int i;
+
+ printf("index: %d ", e4->user_idx);
+
+ printf("Account: ");
+ for (i=0; i<s4->acct_name.str_str_len; i++)
+ printf("%c", s4->acct_name.buffer[i]);
+ printf("\n");
+
+}
/**********************************************************************
* Query user information
*/
-static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL,
- info_level = 21;
- BOOL got_connect_pol = False,
- got_domain_pol = False,
- got_user_pol = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 info_level = 21;
SAM_USERINFO_CTR *user_ctr;
- fstring server;
- TALLOC_CTX *mem_ctx;
+ fstring server;
uint32 user_rid;
-
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
- return 0;
+ return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &user_rid);
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_samr_query_user: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
- got_connect_pol = True;
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
- got_domain_pol = True;
+ result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ user_rid, &user_pol);
- if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rid, &user_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_user_pol = True;
ZERO_STRUCT(user_ctr);
- if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
- info_level, &user_ctr))
- != NT_STATUS_OK) {
+ result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ info_level, &user_ctr);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
display_sam_user_info_21(user_ctr->info.id21);
done:
- if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
@@ -269,158 +252,110 @@ static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
/***********************************************************************
* Query group information
*/
-static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
- BOOL got_connect_pol = False, got_domain_pol = False,
- got_group_pol = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 info_level = 1;
GROUP_INFO_CTR group_ctr;
fstring server;
- TALLOC_CTX *mem_ctx;
uint32 group_rid;
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
- return 0;
- }
-
- group_rid = atoi(argv[1]);
-
- if (!(mem_ctx=talloc_init())) {
- DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
- fetch_domain_sid(cli);
+ sscanf(argv[1], "%i", &group_rid);
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
- got_connect_pol = True;
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
- got_domain_pol = True;
+ result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ group_rid, &group_pol);
- if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rid, &group_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result))
goto done;
- }
-
- got_group_pol = True;
ZERO_STRUCT(group_ctr);
- if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
- info_level, &group_ctr))
- != NT_STATUS_OK) {
+ result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
+ info_level, &group_ctr);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
display_group_info_ctr(&group_ctr);
done:
- if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Query groups a user is a member of */
-static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol,
domain_pol,
user_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False,
- got_domain_pol = False,
- got_user_pol = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 num_groups,
user_rid;
DOM_GID *user_gids;
int i;
fstring server;
- TALLOC_CTX *mem_ctx;
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_samr_query_usergroups: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &user_rid);
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
- if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rid, &user_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ user_rid, &user_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_user_pol = True;
-
- if ((result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
- &num_groups, &user_gids))
- != NT_STATUS_OK) {
+ result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
+ &num_groups, &user_gids);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -430,84 +365,55 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **
}
done:
- if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Query members of a group */
-static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False,
- got_domain_pol = False,
- got_group_pol = False;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 num_members, *group_rids, *group_attrs, group_rid;
int i;
fstring server;
- TALLOC_CTX *mem_ctx;
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_samr_query_groupmem: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &group_rid);
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
- if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- group_rid, &group_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ group_rid, &group_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_group_pol = True;
-
- if ((result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
- &num_members, &group_rids,
- &group_attrs))
- != NT_STATUS_OK) {
+ result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
+ &num_members, &group_rids,
+ &group_attrs);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -517,69 +423,42 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar
}
done:
- if (got_group_pol) cli_samr_close(cli, mem_ctx, &group_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Enumerate domain groups */
-static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False, got_domain_pol = False;
- TALLOC_CTX *mem_ctx;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx, size, num_dom_groups, i;
struct acct_info *dom_groups;
if (argc != 1) {
printf("Usage: %s\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_enum_dom_groups: talloc_init returned "
- "NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
/* Get domain policy handle */
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Enumerate domain groups */
start_idx = 0;
@@ -594,84 +473,56 @@ static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
dom_groups[i].rid);
done:
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Query alias membership */
-static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, alias_pol;
- BOOL got_connect_pol = False, got_domain_pol = False,
- got_alias_pol = False;
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL, alias_rid, num_members, i;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 alias_rid, num_members, i;
DOM_SID *alias_sids;
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx=talloc_init())) {
- DEBUG(0,("cmd_samr_query_aliasmem: talloc_init() "
- "returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
sscanf(argv[1], "%i", &alias_rid);
- /* Initialise RPC connection */
-
- fetch_domain_sid(cli);
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Open SAMR handle */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
/* Open handle on domain */
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Open handle on alias */
- if ((result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- alias_rid, &alias_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ alias_rid, &alias_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_alias_pol = True;
-
- if ((result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
- &num_members, &alias_sids))
- != NT_STATUS_OK) {
+ result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
+ &num_members, &alias_sids);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -683,76 +534,54 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
}
done:
- if (got_alias_pol) cli_samr_close(cli, mem_ctx, &alias_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Query display info */
-static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False, got_domain_pol = False;
- TALLOC_CTX *mem_ctx;
- uint32 start_idx, max_entries, num_entries, i;
- uint16 info_level = 1;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 start_idx=0, max_entries=250, num_entries, i;
+ int info_level = 1;
SAM_DISPINFO_CTR ctr;
SAM_DISPINFO_1 info1;
- if (argc != 1) {
- printf("Usage: %s\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
- "NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ if (argc > 4) {
+ printf("Usage: %s [info level] [start index] [max entries]\n", argv[0]);
+ return NT_STATUS_OK;
}
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
+ if (argc >= 2)
+ sscanf(argv[1], "%i", &info_level);
+
+ if (argc >= 3)
+ sscanf(argv[2], "%i", &start_idx);
+
+ if (argc >= 4)
+ sscanf(argv[3], "%i", &max_entries);
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
/* Get domain policy handle */
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Query display info */
- start_idx = 0;
- max_entries = 250;
-
ZERO_STRUCT(ctr);
ZERO_STRUCT(info1);
@@ -762,82 +591,65 @@ static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
&start_idx, info_level,
&num_entries, max_entries, &ctr);
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
for (i = 0; i < num_entries; i++) {
- display_sam_info_1(&ctr.sam.info1->sam[i],
- &ctr.sam.info1->str[i]);
+ switch (info_level) {
+ case 1:
+ display_sam_info_1(&ctr.sam.info1->sam[i], &ctr.sam.info1->str[i]);
+ break;
+ case 4:
+ display_sam_info_4(&ctr.sam.info4->sam[i], &ctr.sam.info4->str[i]);
+ break;
+ }
}
done:
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Query domain info */
-static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False, got_domain_pol = False;
- TALLOC_CTX *mem_ctx;
- uint16 switch_value = 2;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ int switch_value = 2;
SAM_UNK_CTR ctr;
if (argc > 2) {
- printf("Usage: %s [infolevel\n", argv[0]);
- return 0;
+ printf("Usage: %s [infolevel]\n", argv[0]);
+ return NT_STATUS_OK;
}
if (argc == 2)
- switch_value = atoi(argv[1]);
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
- "NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
+ sscanf(argv[1], "%i", &switch_value);
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
/* Get domain policy handle */
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Query domain info */
- if ((result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
- switch_value, &ctr))
- != NT_STATUS_OK) {
+ result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
+ switch_value, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -854,149 +666,96 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
}
done:
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Create domain user */
-static uint32 cmd_samr_create_dom_user(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
- BOOL got_connect_pol = False, got_domain_pol = False,
- got_user_pol = False;
- TALLOC_CTX *mem_ctx;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
uint16 acb_info;
uint32 unknown, user_rid;
if (argc != 2) {
printf("Usage: %s username\n", argv[0]);
- return 0;
+ return NT_STATUS_OK;
}
acct_name = argv[1];
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
- "NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
-
/* Get domain policy handle */
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Create domain user */
acb_info = ACB_NORMAL;
unknown = 0xe005000b; /* No idea what this is - a permission mask? */
- if ((result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
- &user_pol, &user_rid))
- != NT_STATUS_OK) {
+ result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ acct_name, acb_info, unknown,
+ &user_pol, &user_rid);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_user_pol = True;
-
done:
- if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Lookup sam names */
-static uint32 cmd_samr_lookup_names(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol;
- BOOL got_connect_pol = False, got_domain_pol = False;
- uint32 flags = 0x000003e8;
+ uint32 flags = 0x000003e8; /* Unknown */
uint32 num_rids, num_names, *name_types, *rids;
char **names;
int i;
if (argc < 2) {
printf("Usage: %s name1 [name2 [name3] [...]]\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_lookup_names: talloc_init failed\n"));
- return result;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
/* Get sam policy and domain handles */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Look up names */
num_names = argc - 1;
@@ -1005,10 +764,11 @@ static uint32 cmd_samr_lookup_names(struct cli_state *cli, int argc,
for (i = 0; i < argc - 1; i++)
names[i] = argv[i + 1];
- if ((result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, num_names, names,
- &num_rids, &rids, &name_types))
- != NT_STATUS_OK) {
+ result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ flags, num_names, names,
+ &num_rids, &rids, &name_types);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -1019,137 +779,97 @@ static uint32 cmd_samr_lookup_names(struct cli_state *cli, int argc,
name_types[i]);
done:
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Lookup sam rids */
-static uint32 cmd_samr_lookup_rids(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol;
- BOOL got_connect_pol = False, got_domain_pol = False;
- uint32 flags = 0x000003e8;
+ uint32 flags = 0x000003e8; /* Unknown */
uint32 num_rids, num_names, *rids, *name_types;
char **names;
int i;
if (argc < 2) {
printf("Usage: %s rid1 [rid2 [rid3] [...]]\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_lookup_rids: talloc_init failed\n"));
- return result;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- fprintf (stderr, "Could not initialize samr pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
/* Get sam policy and domain handles */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_connect_pol = True;
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- got_domain_pol = True;
-
/* Look up rids */
num_rids = argc - 1;
rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
for (i = 0; i < argc - 1; i++)
- rids[i] = atoi(argv[i + 1]);
+ sscanf(argv[i + 1], "%i", &rids[i]);
+
+ result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
+ flags, num_rids, rids,
+ &num_names, &names, &name_types);
- if ((result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
- flags, num_rids, rids,
- &num_names, &names, &name_types))
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Display results */
for (i = 0; i < num_names; i++)
- printf("rid %x: %s (%d)\n", rids[i], names[i], name_types[i]);
+ printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
done:
- if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
- if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
-
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* Delete domain user */
-static uint32 cmd_samr_delete_dom_user(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol, user_pol;
if (argc != 2) {
printf("Usage: %s username\n", argv[0]);
- return 0;
- }
-
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0, ("cmd_samr_delete_dom_user: talloc_init failed\n"));
- return result;
- }
-
- fetch_domain_sid(cli);
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SAMR)) {
- DEBUG(0, ("cmd_samr_delete_dom_user: could not open samr pipe!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_OK;
}
/* Get sam policy and domain handles */
- if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
- &connect_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -1157,58 +877,59 @@ static uint32 cmd_samr_delete_dom_user(struct cli_state *cli, int argc,
{
uint32 *user_rids, num_rids, *name_types;
- uint32 flags = 0x000003e8;
+ uint32 flags = 0x000003e8; /* Unknown */
- if ((result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
- flags, 1, &argv[1],
- &num_rids, &user_rids,
- &name_types))
- != NT_STATUS_OK) {
+ result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ flags, 1, &argv[1],
+ &num_rids, &user_rids,
+ &name_types);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
- MAXIMUM_ALLOWED_ACCESS,
- user_rids[0], &user_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ user_rids[0], &user_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
}
/* Delete user */
- if ((result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol))
- != NT_STATUS_OK) {
+ result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Display results */
done:
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/* List of commands exported by this module */
struct cmd_set samr_commands[] = {
- { "SAMR", NULL, "" },
-
- { "queryuser", cmd_samr_query_user, "Query user info" },
- { "querygroup", cmd_samr_query_group, "Query group info" },
- { "queryusergroups", cmd_samr_query_usergroups, "Query user groups" },
- { "querygroupmem", cmd_samr_query_groupmem, "Query group membership" },
- { "queryaliasmem", cmd_samr_query_aliasmem, "Query alias membership" },
- { "querydispinfo", cmd_samr_query_dispinfo, "Query display info" },
- { "querydominfo", cmd_samr_query_dominfo, "Query domain info" },
- { "enumdomgroups", cmd_samr_enum_dom_groups, "Enumerate domain groups" },
-
- { "createdomuser", cmd_samr_create_dom_user, "Create domain user" },
- { "samlookupnames", cmd_samr_lookup_names, "Look up names", },
- { "samlookuprids", cmd_samr_lookup_rids, "Look up names", },
- { "deletedomuser", cmd_samr_delete_dom_user, "Delete domain user" },
- { NULL, NULL, NULL }
-};
+ { "SAMR" },
+
+ { "queryuser", cmd_samr_query_user, PIPE_SAMR, "Query user info", "" },
+ { "querygroup", cmd_samr_query_group, PIPE_SAMR, "Query group info", "" },
+ { "queryusergroups", cmd_samr_query_usergroups, PIPE_SAMR, "Query user groups", "" },
+ { "querygroupmem", cmd_samr_query_groupmem, PIPE_SAMR, "Query group membership", "" },
+ { "queryaliasmem", cmd_samr_query_aliasmem, PIPE_SAMR, "Query alias membership", "" },
+ { "querydispinfo", cmd_samr_query_dispinfo, PIPE_SAMR, "Query display info", "" },
+ { "querydominfo", cmd_samr_query_dominfo, PIPE_SAMR, "Query domain info", "" },
+ { "enumdomgroups", cmd_samr_enum_dom_groups, PIPE_SAMR, "Enumerate domain groups", "" },
+
+ { "createdomuser", cmd_samr_create_dom_user, PIPE_SAMR, "Create domain user", "" },
+ { "samlookupnames", cmd_samr_lookup_names, PIPE_SAMR, "Look up names", "" },
+ { "samlookuprids", cmd_samr_lookup_rids, PIPE_SAMR, "Look up names", "" },
+ { "deletedomuser", cmd_samr_delete_dom_user, PIPE_SAMR, "Delete domain user", "" },
+
+ { NULL }
+};
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index d8f7cf33ae2..b3bffde2ba0 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/Netbios implementation.
Version 2.2
RPC pipe client
@@ -24,13 +24,7 @@
*/
#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-extern pstring server;
-extern pstring global_myname;
-extern pstring username, password;
-extern pstring workgroup;
+#include "rpcclient.h"
struct table_node {
char *long_archi;
@@ -80,8 +74,9 @@ BOOL get_short_archi(char *short_archi, char *long_archi)
/**********************************************************************
* dummy function -- placeholder
*/
-static uint32 cmd_spoolss_not_implemented (struct cli_state *cli,
- int argc, char **argv)
+static NTSTATUS cmd_spoolss_not_implemented(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
printf ("(*) This command is not currently implemented.\n");
return NT_STATUS_OK;
@@ -94,7 +89,7 @@ static void display_sec_ace(SEC_ACE *ace)
{
fstring sid_str;
- sid_to_string(sid_str, &ace->sid);
+ sid_to_string(sid_str, &ace->trustee);
printf("\t\tSID: %s\n", sid_str);
printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n",
@@ -142,13 +137,14 @@ static void display_sec_desc(SEC_DESC *sec)
/***********************************************************************
* Get printer information
*/
-static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_open_printer_ex(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
pstring printername;
fstring servername, user;
POLICY_HND hnd;
- TALLOC_CTX *mem_ctx;
if (argc != 2) {
printf("Usage: %s <printername>\n", argv[0]);
@@ -158,40 +154,23 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char
if (!cli)
return NT_STATUS_UNSUCCESSFUL;
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_open_printer_ex: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
fstrcpy (user, cli->user_name);
fstrcpy (printername, argv[1]);
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Open the printer handle */
result = cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd);
- if (result == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result)) {
printf ("Printer %s opened successfully\n", printername);
result = cli_spoolss_close_printer (cli, mem_ctx, &hnd);
- if (result != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result)) {
printf ("Error closing printer handle! (%s)\n", get_nt_error_msg(result));
}
}
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
@@ -204,9 +183,9 @@ static void display_print_info_0(PRINTER_INFO_0 *i1)
fstring name;
fstring servername;
- unistr_to_ascii(name, i1->printername.buffer, sizeof(name) - 1);
- unistr_to_ascii(servername, i1->servername.buffer, sizeof(servername) - 1);
-
+ rpcstr_pull(name, i1->printername.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(servername, i1->servername.buffer, sizeof(servername), 0,STR_TERMINATE);
+
printf("\tprintername:[%s]\n", name);
printf("\tservername:[%s]\n", servername);
printf("\tcjobs:[0x%x]\n", i1->cjobs);
@@ -257,9 +236,9 @@ static void display_print_info_1(PRINTER_INFO_1 *i1)
fstring name;
fstring comm;
- unistr_to_ascii(desc, i1->description.buffer, sizeof(desc) - 1);
- unistr_to_ascii(name, i1->name .buffer, sizeof(name) - 1);
- unistr_to_ascii(comm, i1->comment .buffer, sizeof(comm) - 1);
+ rpcstr_pull(desc, i1->description.buffer, sizeof(desc), 0, STR_TERMINATE);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), 0, STR_TERMINATE);
printf("\tflags:[0x%x]\n", i1->flags);
printf("\tname:[%s]\n", name);
@@ -284,23 +263,17 @@ static void display_print_info_2(PRINTER_INFO_2 *i2)
fstring datatype;
fstring parameters;
- unistr_to_ascii(servername, i2->servername.buffer,
- sizeof(servername) - 1);
- unistr_to_ascii(printername, i2->printername.buffer,
- sizeof(printername) - 1);
- unistr_to_ascii(sharename, i2->sharename.buffer,
- sizeof(sharename) - 1);
- unistr_to_ascii(portname, i2->portname.buffer, sizeof(portname) - 1);
- unistr_to_ascii(drivername, i2->drivername.buffer,
- sizeof(drivername) - 1);
- unistr_to_ascii(comment, i2->comment.buffer, sizeof(comment) - 1);
- unistr_to_ascii(location, i2->location.buffer, sizeof(location) - 1);
- unistr_to_ascii(sepfile, i2->sepfile.buffer, sizeof(sepfile) - 1);
- unistr_to_ascii(printprocessor, i2->printprocessor.buffer,
- sizeof(printprocessor) - 1);
- unistr_to_ascii(datatype, i2->datatype.buffer, sizeof(datatype) - 1);
- unistr_to_ascii(parameters, i2->parameters.buffer,
- sizeof(parameters) - 1);
+ rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), 0, STR_TERMINATE);
+ rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), 0, STR_TERMINATE);
+ rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), 0, STR_TERMINATE);
+ rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), 0, STR_TERMINATE);
+ rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), 0, STR_TERMINATE);
+ rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), 0, STR_TERMINATE);
+ rpcstr_pull(location, i2->location.buffer,sizeof(location), 0, STR_TERMINATE);
+ rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), 0, STR_TERMINATE);
+ rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), 0, STR_TERMINATE);
+ rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), 0, STR_TERMINATE);
+ rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), 0, STR_TERMINATE);
printf("\tservername:[%s]\n", servername);
printf("\tprintername:[%s]\n", printername);
@@ -337,14 +310,15 @@ static void display_print_info_3(PRINTER_INFO_3 *i3)
/* Enumerate printers */
-static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result = NT_STATUS_UNSUCCESSFUL,
- info_level = 1;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 info_level = 1;
PRINTER_INFO_CTR ctr;
int returned;
uint32 i = 0;
- TALLOC_CTX *mem_ctx;
if (argc > 2)
{
@@ -352,33 +326,20 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_enum_printers: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
if (argc == 2) {
info_level = atoi(argv[1]);
}
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Enumerate printers -- Should we enumerate types other
than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
ZERO_STRUCT(ctr);
result = cli_spoolss_enum_printers(cli, mem_ctx, PRINTER_ENUM_LOCAL,
info_level, &returned, &ctr);
- if (result == NT_STATUS_OK)
+ if (NT_STATUS_IS_OK(result))
{
if (!returned)
- printf ("No Printers printers returned.\n");
+ printf ("No Printers returned.\n");
switch(info_level) {
case 0:
@@ -407,9 +368,6 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **
}
}
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
@@ -420,7 +378,7 @@ static void display_port_info_1(PORT_INFO_1 *i1)
{
fstring buffer;
- unistr_to_ascii(buffer, i1->port_name.buffer, sizeof(buffer)-1);
+ rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tPort Name:\t[%s]\n", buffer);
}
@@ -431,11 +389,13 @@ static void display_port_info_2(PORT_INFO_2 *i2)
{
fstring buffer;
- unistr_to_ascii(buffer, i2->port_name.buffer, sizeof(buffer) - 1);
+ rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
printf("\tPort Name:\t[%s]\n", buffer);
- unistr_to_ascii(buffer, i2->monitor_name.buffer, sizeof(buffer) - 1);
+ rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
+
printf("\tMonitor Name:\t[%s]\n", buffer);
- unistr_to_ascii(buffer, i2->description.buffer, sizeof(buffer) - 1);
+ rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), 0, STR_TERMINATE);
+
printf("\tDescription:\t[%s]\n", buffer);
printf("\tPort Type:\t[%d]\n", i2->port_type);
printf("\tReserved:\t[%d]\n", i2->reserved);
@@ -444,42 +404,30 @@ static void display_port_info_2(PORT_INFO_2 *i2)
/* Enumerate ports */
-static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_enum_ports(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result = NT_STATUS_UNSUCCESSFUL,
- info_level = 1;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 info_level = 1;
PORT_INFO_CTR ctr;
int returned;
- TALLOC_CTX *mem_ctx;
if (argc > 2) {
printf("Usage: %s [level]\n", argv[0]);
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_enum_ports: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
if (argc == 2) {
info_level = atoi(argv[1]);
}
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Enumerate ports */
ZERO_STRUCT(ctr);
result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
- if (result == NT_STATUS_OK) {
+ if (NT_STATUS_IS_OK(result)) {
int i;
for (i = 0; i < returned; i++) {
@@ -497,43 +445,94 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg
}
}
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
/***********************************************************************
- * Get printer information
+ * Set printer comment - use a level2 set.
*/
-static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_setprinter(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND pol;
- uint32 result,
- info_level = 1;
+ NTSTATUS result;
+ uint32 info_level = 2;
BOOL opened_hnd = False;
PRINTER_INFO_CTR ctr;
fstring printername,
servername,
- user;
- TALLOC_CTX *mem_ctx;
+ user,
+ comment;
if (argc == 1 || argc > 3) {
- printf("Usage: %s <printername> [level]\n", argv[0]);
+ printf("Usage: %s printername comment\n", argv[0]);
+
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ /* Open a printer handle */
+ if (argc == 3) {
+ fstrcpy(comment, argv[2]);
}
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ fstrcpy (printername, argv[1]);
+ fstrcpy (user, cli->user_name);
+
+ /* get a printer handle */
+ result = cli_spoolss_open_printer_ex(
+ cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, servername,
+ user, &pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ opened_hnd = True;
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
+ /* Get printer info */
+ result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Modify the comment. */
+ init_unistr(&ctr.printers_2->comment, comment);
+ ctr.printers_2->devmode = NULL;
+ ctr.printers_2->secdesc = NULL;
+
+ result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ if (NT_STATUS_IS_OK(result))
+ printf("Success in setting comment.\n");
+
+ done:
+ if (opened_hnd)
+ cli_spoolss_close_printer(cli, mem_ctx, &pol);
+
+ return result;
+}
+
+/***********************************************************************
+ * Get printer information
+ */
+static NTSTATUS cmd_spoolss_getprinter(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ POLICY_HND pol;
+ NTSTATUS result;
+ uint32 info_level = 1;
+ BOOL opened_hnd = False;
+ PRINTER_INFO_CTR ctr;
+ fstring printername,
+ servername,
+ user;
+
+ if (argc == 1 || argc > 3) {
+ printf("Usage: %s <printername> [level]\n", argv[0]);
+
+ return NT_STATUS_OK;
}
/* Open a printer handle */
@@ -543,21 +542,22 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
- slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
+ fstrcpy (printername, argv[1]);
fstrcpy (user, cli->user_name);
/* get a printer handle */
- if ((result = cli_spoolss_open_printer_ex(
+ result = cli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, servername,
- user, &pol)) != NT_STATUS_OK) {
+ user, &pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
opened_hnd = True;
/* Get printer info */
- if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr))
- != NT_STATUS_OK) {
+ result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -585,9 +585,6 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg
if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- cli_nt_session_close(cli);
- talloc_destroy(mem_ctx);
-
return result;
}
@@ -600,7 +597,7 @@ static void display_print_driver_1(DRIVER_INFO_1 *i1)
if (i1 == NULL)
return;
- unistr_to_ascii(name, i1->name.buffer, sizeof(name)-1);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
printf ("Printer Driver Info 1:\n");
printf ("\tDriver Name: [%s]\n\n", name);
@@ -621,11 +618,11 @@ static void display_print_driver_2(DRIVER_INFO_2 *i1)
if (i1 == NULL)
return;
- unistr_to_ascii(name, i1->name.buffer, sizeof(name)-1);
- unistr_to_ascii(architecture, i1->architecture.buffer, sizeof(architecture)-1);
- unistr_to_ascii(driverpath, i1->driverpath.buffer, sizeof(driverpath)-1);
- unistr_to_ascii(datafile, i1->datafile.buffer, sizeof(datafile)-1);
- unistr_to_ascii(configfile, i1->configfile.buffer, sizeof(configfile)-1);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
printf ("Printer Driver Info 2:\n");
printf ("\tVersion: [%x]\n", i1->version);
@@ -659,19 +656,18 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
if (i1 == NULL)
return;
- unistr_to_ascii(name, i1->name.buffer, sizeof(name)-1);
- unistr_to_ascii(architecture, i1->architecture.buffer, sizeof(architecture)-1);
- unistr_to_ascii(driverpath, i1->driverpath.buffer, sizeof(driverpath)-1);
- unistr_to_ascii(datafile, i1->datafile.buffer, sizeof(datafile)-1);
- unistr_to_ascii(configfile, i1->configfile.buffer, sizeof(configfile)-1);
- unistr_to_ascii(helpfile, i1->helpfile.buffer, sizeof(helpfile)-1);
-
- unistr_to_ascii(monitorname, i1->monitorname.buffer, sizeof(monitorname)-1);
- unistr_to_ascii(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype)-1);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
+ rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
+ rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
+ rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
+ rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
+ rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), 0, STR_TERMINATE);
+ rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), 0, STR_TERMINATE);
+ rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), 0, STR_TERMINATE);
printf ("Printer Driver Info 3:\n");
printf ("\tVersion: [%x]\n", i1->version);
- printf ("\tDriver Name: [%s]\n",name );
+ printf ("\tDriver Name: [%s]\n",name);
printf ("\tArchitecture: [%s]\n", architecture);
printf ("\tDriver Path: [%s]\n", driverpath);
printf ("\tDatafile: [%s]\n", datafile);
@@ -680,7 +676,8 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
while (valid)
{
- unistr_to_ascii(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles)-1);
+ rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), 0, STR_TERMINATE);
+
length+=strlen(dependentfiles)+1;
if (strlen(dependentfiles) > 0)
@@ -704,18 +701,19 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
/***********************************************************************
* Get printer information
*/
-static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND pol;
- uint32 result,
- info_level = 3;
+ NTSTATUS result;
+ uint32 info_level = 3;
BOOL opened_hnd = False;
PRINTER_DRIVER_CTR ctr;
fstring printername,
servername,
user;
uint32 i;
- TALLOC_CTX *mem_ctx;
if ((argc == 1) || (argc > 3))
{
@@ -723,19 +721,6 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_getdriver: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* get the arguments need to open the printer handle */
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
@@ -745,9 +730,9 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
info_level = atoi(argv[2]);
/* Open a printer handle */
- if ((result=cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS, servername, user, &pol)) != NT_STATUS_OK)
- {
+ result=cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
+ MAXIMUM_ALLOWED_ACCESS, servername, user, &pol);
+ if (!NT_STATUS_IS_OK(result)) {
printf ("Error opening printer handle for %s!\n", printername);
return result;
}
@@ -757,20 +742,9 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
/* loop through and print driver info level for each architecture */
for (i=0; archi_table[i].long_archi!=NULL; i++)
{
- result = cli_spoolss_getprinterdriver (cli, mem_ctx, &pol, info_level,
- archi_table[i].long_archi, &ctr);
-
- switch (result)
- {
- case ERRsuccess:
- break;
-
- case ERRunknownprinterdriver:
- continue;
-
- default:
- printf ("Error getting driver for %s [%s] - %s\n", printername,
- archi_table[i].long_archi, get_nt_error_msg(result));
+ result = cli_spoolss_getprinterdriver(cli, mem_ctx, &pol, info_level,
+ archi_table[i].long_archi, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
continue;
}
@@ -792,36 +766,29 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
printf("unknown info level %d\n", info_level);
break;
}
-
-
}
-
/* cleanup */
if (opened_hnd)
cli_spoolss_close_printer (cli, mem_ctx, &pol);
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
- if (result==ERRunknownprinterdriver)
- return NT_STATUS_OK;
- else
- return result;
+ return result;
}
/***********************************************************************
* Get printer information
*/
-static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_enum_drivers(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result=0,
- info_level = 1;
+ NTSTATUS result = NT_STATUS_OK;
+ uint32 info_level = 1;
PRINTER_DRIVER_CTR ctr;
fstring servername;
uint32 i, j,
returned;
- TALLOC_CTX *mem_ctx;
if (argc > 2)
{
@@ -829,19 +796,6 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_enum_drivers: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* get the arguments need to open the printer handle */
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
@@ -860,7 +814,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
continue;
- if (result != NT_STATUS_OK)
+ if (!NT_STATUS_IS_OK(result))
{
printf ("Error getting driver for environment [%s] - %s\n",
archi_table[i].long_archi, get_nt_error_msg(result));
@@ -892,16 +846,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
}
}
-
- /* cleanup */
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
-
- if (result==ERRunknownprinterdriver)
- return NT_STATUS_OK;
- else
- return result;
-
+ return result;
}
/****************************************************************************
@@ -913,7 +858,7 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
if (i1 == NULL)
return;
- unistr_to_ascii(name, i1->name.buffer, sizeof(name)-1);
+ rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
printf ("\tDirectory Name:[%s]\n", name);
}
@@ -921,12 +866,13 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
/***********************************************************************
* Get printer driver directory information
*/
-static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result;
+ NTSTATUS result;
fstring env;
DRIVER_DIRECTORY_CTR ctr;
- TALLOC_CTX *mem_ctx;
if (argc > 2)
{
@@ -934,20 +880,6 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a
return NT_STATUS_OK;
}
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_getdriverdir: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
/* get the arguments need to open the printer handle */
if (argc == 2)
fstrcpy (env, argv[1]);
@@ -955,21 +887,15 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a
fstrcpy (env, "Windows NT x86");
/* Get the directory. Only use Info level 1 */
- if ((result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr))
- != NT_STATUS_OK)
- {
+ result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
return result;
}
display_printdriverdir_1 (ctr.info1);
- /* cleanup */
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
-
return result;
-
}
/*******************************************************************************
@@ -1072,7 +998,7 @@ static BOOL init_drv_info_3_members (
}
for (i=0; i<len; i++)
{
- info->dependentfiles[i] = (uint16)str2[i];
+ info->dependentfiles[i] = SSVAL(&info->dependentfiles[i], 0, str2[i]);
}
info->dependentfiles[len] = '\0';
@@ -1080,15 +1006,16 @@ static BOOL init_drv_info_3_members (
}
-static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_addprinterdriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result,
- level = 3;
+ NTSTATUS result;
+ uint32 level = 3;
PRINTER_DRIVER_CTR ctr;
DRIVER_INFO_3 info3;
fstring arch;
fstring driver_name;
- TALLOC_CTX *mem_ctx = NULL;
/* parse the command arguements */
if (argc != 3)
@@ -1100,20 +1027,6 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha
return NT_STATUS_OK;
}
-
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_addprinterdriver: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Fill in the DRIVER_INFO_3 struct */
ZERO_STRUCT(info3);
@@ -1133,32 +1046,27 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha
ctr.info3 = &info3;
- if ((result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr))
- != NT_STATUS_OK)
- {
+ result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
return result;
}
- unistr_to_ascii (driver_name, info3.name.buffer, sizeof(driver_name)-1);
+ rpcstr_pull(driver_name, info3.name.buffer, sizeof(driver_name), 0, STR_TERMINATE);
printf ("Printer Driver %s successfully installed.\n", driver_name);
- /* cleanup */
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
-
return result;
-
}
-static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_addprinterex(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result,
- level = 2;
+ NTSTATUS result;
+ uint32 level = 2;
PRINTER_INFO_CTR ctr;
PRINTER_INFO_2 info2;
fstring servername;
- TALLOC_CTX *mem_ctx = NULL;
/* parse the command arguements */
if (argc != 5)
@@ -1167,24 +1075,9 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_addprinterex: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
/* Fill in the DRIVER_INFO_3 struct */
ZERO_STRUCT(info2);
#if 0 /* JERRY */
@@ -1214,35 +1107,29 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **
*/
ctr.printers_2 = &info2;
- if ((result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr))
- != NT_STATUS_OK)
- {
- cli_nt_session_close (cli);
+ result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
return result;
}
printf ("Printer %s successfully installed.\n", argv[1]);
- /* cleanup */
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
-
return result;
-
}
-static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_setdriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
POLICY_HND pol;
- uint32 result,
- level = 2;
+ NTSTATUS result;
+ uint32 level = 2;
BOOL opened_hnd = False;
PRINTER_INFO_CTR ctr;
PRINTER_INFO_2 info2;
fstring servername,
printername,
user;
- TALLOC_CTX *mem_ctx = NULL;
/* parse the command arguements */
if (argc != 3)
@@ -1251,48 +1138,33 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_setdriver: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
fstrcpy (user, cli->user_name);
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
-
/* get a printer handle */
- if ((result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS, servername, user, &pol))
- != NT_STATUS_OK)
- {
+ result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ MAXIMUM_ALLOWED_ACCESS, servername, user, &pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
-
+
opened_hnd = True;
/* Get printer info */
ZERO_STRUCT (info2);
ctr.printers_2 = &info2;
- if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr)) != NT_STATUS_OK)
- {
+ result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
+ if (!NT_STATUS_IS_OK(result)) {
printf ("Unable to retrieve printer information!\n");
goto done;
}
/* set the printer driver */
init_unistr(&ctr.printers_2->drivername, argv[2]);
- if ((result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0)) != NT_STATUS_OK)
- {
+ result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
+ if (!NT_STATUS_IS_OK(result)) {
printf ("SetPrinter call failed!\n");
goto done;;
}
@@ -1303,18 +1175,17 @@ done:
/* cleanup */
if (opened_hnd)
cli_spoolss_close_printer(cli, mem_ctx, &pol);
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
-
- return result;
+
+ return result;
}
-static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_spoolss_deletedriver(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring servername;
- TALLOC_CTX *mem_ctx = NULL;
int i;
/* parse the command arguements */
@@ -1324,29 +1195,16 @@ static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **
return NT_STATUS_OK;
}
- if (!(mem_ctx=talloc_init()))
- {
- DEBUG(0,("cmd_spoolss_deletedriver: talloc_init returned NULL!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (servername);
- /* Initialise RPC connection */
- if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
- {
- fprintf (stderr, "Could not initialize spoolss pipe!\n");
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* delete the driver for all architectures */
for (i=0; archi_table[i].long_archi; i++)
{
/* make the call to remove the driver */
- if ((result = cli_spoolss_deleteprinterdriver(cli, mem_ctx,
- archi_table[i].long_archi, argv[1])) != NT_STATUS_OK)
- {
+ result = cli_spoolss_deleteprinterdriver(cli, mem_ctx,
+ archi_table[i].long_archi, argv[1]);
+ if (!NT_STATUS_IS_OK(result)) {
printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
argv[1], archi_table[i].long_archi, get_nt_error_msg(result));
}
@@ -1354,32 +1212,133 @@ static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **
printf ("Driver %s removed for arch [%s].\n", argv[1], archi_table[i].long_archi);
}
+ return NT_STATUS_OK;
+}
- /* cleanup */
- cli_nt_session_close (cli);
- talloc_destroy(mem_ctx);
+static NTSTATUS cmd_spoolss_getprintprocdir(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ char *servername = NULL, *environment = NULL;
+ fstring procdir;
- return NT_STATUS_OK;
+ /* parse the command arguements */
+ if (argc < 2 || argc > 3) {
+ printf ("Usage: %s <server> [environment]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
+ return NT_STATUS_NO_MEMORY;
+ strupper(servername);
+
+ if (asprintf(&environment, "%s", (argc == 3) ? argv[2] :
+ PRINTER_DRIVER_ARCHITECTURE) < 0) {
+ SAFE_FREE(servername);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result = cli_spoolss_getprintprocessordirectory(
+ cli, mem_ctx, servername, environment, procdir);
+
+ if (NT_STATUS_IS_OK(result))
+ printf("%s", procdir);
+
+ SAFE_FREE(servername);
+ SAFE_FREE(environment);
+
+ return result;
}
+static NTSTATUS cmd_spoolss_setprinterdata(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ fstring servername, printername, user;
+ POLICY_HND pol;
+ BOOL opened_hnd = False;
+ PRINTER_INFO_CTR ctr;
+ PRINTER_INFO_0 *info = NULL;
+
+ /* parse the command arguements */
+ if (argc != 4) {
+ printf ("Usage: %s <printer> <value> <data>\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ strupper (servername);
+ slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
+ fstrcpy (user, cli->user_name);
+
+ /* get a printer handle */
+ result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ MAXIMUM_ALLOWED_ACCESS, servername, user, &pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ opened_hnd = True;
+
+ printf("%s\n", timestring(True));
+
+ result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
+ info = ctr.printers_0;
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+ printf("\tchange_id (before set)\t:[0x%x]\n", info->change_id);
+
+
+ /* Get printer info */
+ result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, argv[2], argv[3]);
+ if (!NT_STATUS_IS_OK(result)) {
+ printf ("Unable to set [%s=%s]!\n", argv[2], argv[3]);
+ goto done;
+ }
+ printf("\tSetPrinterData succeeded [%s: %s]\n", argv[2], argv[3]);
+
+ result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
+ info = ctr.printers_0;
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+ printf("\tchange_id (after set)\t:[0x%x]\n", info->change_id);
+ printf("%s\n", timestring(True));
+
+
+done:
+ /* cleanup */
+ if (opened_hnd)
+ cli_spoolss_close_printer(cli, mem_ctx, &pol);
+
+ return result;
+}
/* List of commands exported by this module */
struct cmd_set spoolss_commands[] = {
- { "SPOOLSS", NULL, "" },
- { "adddriver", cmd_spoolss_addprinterdriver, "Add a print driver" },
- { "addprinter", cmd_spoolss_addprinterex, "Add a printer" },
- { "deldriver", cmd_spoolss_deletedriver, "Delete a printer driver" },
- { "enumdata", cmd_spoolss_not_implemented, "Enumerate printer data (*)" },
- { "enumjobs", cmd_spoolss_not_implemented, "Enumerate print jobs (*)" },
- { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" },
- { "enumdrivers", cmd_spoolss_enum_drivers, "Enumerate installed printer drivers" },
- { "enumprinters", cmd_spoolss_enum_printers, "Enumerate printers" },
- { "getdata", cmd_spoolss_not_implemented, "Get print driver data (*)" },
- { "getdriver", cmd_spoolss_getdriver, "Get print driver information" },
- { "getdriverdir", cmd_spoolss_getdriverdir, "Get print driver upload directory" },
- { "getprinter", cmd_spoolss_getprinter, "Get printer info" },
- { "openprinter", cmd_spoolss_open_printer_ex, "Open printer handle" },
- { "setdriver", cmd_spoolss_setdriver, "Set printer driver" },
- { NULL, NULL, NULL }
+ { "SPOOLSS" },
+
+ { "adddriver", cmd_spoolss_addprinterdriver, PIPE_SPOOLSS, "Add a print driver", "" },
+ { "addprinter", cmd_spoolss_addprinterex, PIPE_SPOOLSS, "Add a printer", "" },
+ { "deldriver", cmd_spoolss_deletedriver, PIPE_SPOOLSS, "Delete a printer driver", "" },
+ { "enumdata", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Enumerate printer data (*)", "" },
+ { "enumjobs", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Enumerate print jobs (*)", "" },
+ { "enumports", cmd_spoolss_enum_ports, PIPE_SPOOLSS, "Enumerate printer ports", "" },
+ { "enumdrivers", cmd_spoolss_enum_drivers, PIPE_SPOOLSS, "Enumerate installed printer drivers", "" },
+ { "enumprinters", cmd_spoolss_enum_printers, PIPE_SPOOLSS, "Enumerate printers", "" },
+ { "getdata", cmd_spoolss_not_implemented, PIPE_SPOOLSS, "Get print driver data (*)", "" },
+ { "getdriver", cmd_spoolss_getdriver, PIPE_SPOOLSS, "Get print driver information", "" },
+ { "getdriverdir", cmd_spoolss_getdriverdir, PIPE_SPOOLSS, "Get print driver upload directory", "" },
+ { "getprinter", cmd_spoolss_getprinter, PIPE_SPOOLSS, "Get printer info", "" },
+ { "getprintprocdir", cmd_spoolss_getprintprocdir, PIPE_SPOOLSS, "Get print processor directory", "" },
+ { "openprinter", cmd_spoolss_open_printer_ex, PIPE_SPOOLSS, "Open printer handle", "" },
+ { "setdriver", cmd_spoolss_setdriver, PIPE_SPOOLSS, "Set printer driver", "" },
+ { "setprinter", cmd_spoolss_setprinter, PIPE_SPOOLSS, "Set printer comment", "" },
+ { "setprinterdata", cmd_spoolss_setprinterdata, PIPE_SPOOLSS, "Set REG_SZ printer data", "" },
+
+ { NULL }
};
diff --git a/source/rpcclient/cmd_srvsvc.c b/source/rpcclient/cmd_srvsvc.c
index 0f1289f2750..f4ff11adf13 100644
--- a/source/rpcclient/cmd_srvsvc.c
+++ b/source/rpcclient/cmd_srvsvc.c
@@ -23,8 +23,7 @@
*/
#include "includes.h"
-
-extern int DEBUGLEVEL;
+#include "rpcclient.h"
/* Display server query info */
@@ -182,37 +181,26 @@ static void display_srv_info_102(SRV_INFO_102 *sv102)
/* Server query info */
-static uint32 cmd_srvsvc_srv_query_info(struct cli_state *cli, int argc,
- char **argv)
+static NTSTATUS cmd_srvsvc_srv_query_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
uint32 info_level = 101;
SRV_INFO_CTR ctr;
- TALLOC_CTX *mem_ctx;
- uint32 result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (argc > 2) {
printf("Usage: %s [infolevel]\n", argv[0]);
- return 0;
+ return NT_STATUS_OK;
}
if (argc == 2)
info_level = atoi(argv[1]);
- if (!(mem_ctx = talloc_init())) {
- DEBUG(0,("cmd_srvsvc_srv_query_info: talloc_init failed\n"));
- goto done;
- }
-
- /* Initialise RPC connection */
-
- if (!cli_nt_session_open (cli, PIPE_SRVSVC)) {
- DEBUG(0, ("Could not initialize srvsvc pipe!\n"));
- goto done;
- }
+ result = cli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
+ &ctr);
- if ((result = cli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
- &ctr)
- != NT_STATUS_OK)) {
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -237,7 +225,10 @@ static uint32 cmd_srvsvc_srv_query_info(struct cli_state *cli, int argc,
/* List of commands exported by this module */
struct cmd_set srvsvc_commands[] = {
- { "SRVSVC", NULL, "" },
- { "srvinfo", cmd_srvsvc_srv_query_info, "Server query info" },
- { NULL, NULL, NULL }
+
+ { "SRVSVC" },
+
+ { "srvinfo", cmd_srvsvc_srv_query_info, PIPE_SRVSVC, "Server query info", "" },
+
+ { NULL }
};
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 9785b2c309b..c78fae43183 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -3,7 +3,7 @@
Version 2.2
RPC pipe client
- Copyright (C) Tim Potter 2000
+ Copyright (C) Tim Potter 2000-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,9 +21,7 @@
*/
#include "includes.h"
-
-extern int DEBUGLEVEL;
-extern pstring debugf;
+#include "rpcclient.h"
DOM_SID domain_sid;
@@ -37,7 +35,7 @@ static struct cmd_list {
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
+static char **completion_fn(const char *text, int start, int end)
{
#define MAX_COMPLETIONS 100
char **matches;
@@ -84,7 +82,7 @@ static char **completion_fn(char *text, int start, int end)
}
if (count == 2) {
- free(matches[0]);
+ SAFE_FREE(matches[0]);
matches[0] = strdup(matches[1]);
}
matches[count] = NULL;
@@ -132,7 +130,7 @@ static void read_authfile (
/* break up the line into parameter & value.
will need to eat a little whitespace possibly */
param = buf;
- if (!(ptr = strchr (buf, '=')))
+ if (!(ptr = strchr(buf, '=')))
continue;
val = ptr+1;
*ptr = '\0';
@@ -159,16 +157,23 @@ static char* next_command (char** cmdstr)
{
static pstring command;
char *p;
+ BOOL next_cmd = False;
if (!cmdstr || !(*cmdstr))
return NULL;
+ printf("cmd = %s\n", *cmdstr);
+
p = strchr(*cmdstr, ';');
- if (p)
+ if (p) {
+ next_cmd = True;
*p = '\0';
+ }
pstrcpy(command, *cmdstr);
- *cmdstr = p;
-
+ *cmdstr = p;
+ if (next_cmd)
+ p++;
+
return command;
}
@@ -187,11 +192,13 @@ static void get_username (char *username)
return;
}
-/* Fetch the SID for this domain */
-void fetch_domain_sid(struct cli_state *cli)
+/* Fetch the SID for this computer */
+
+void fetch_machine_sid(struct cli_state *cli)
{
POLICY_HND pol;
- uint32 result = 0, info_class = 5;
+ NTSTATUS result = NT_STATUS_OK;
+ uint32 info_class = 5;
fstring domain_name;
static BOOL got_domain_sid;
TALLOC_CTX *mem_ctx;
@@ -210,15 +217,16 @@ void fetch_domain_sid(struct cli_state *cli)
goto error;
}
- if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol) != NT_STATUS_OK)) {
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &pol);
+ if (!NT_STATUS_IS_OK(result)) {
goto error;
}
- if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
- domain_name, &domain_sid))
- != NT_STATUS_OK) {
+ result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
+ domain_name, &domain_sid);
+ if (!NT_STATUS_IS_OK(result)) {
goto error;
}
@@ -233,7 +241,7 @@ void fetch_domain_sid(struct cli_state *cli)
error:
fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
- if (result != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(result)) {
fprintf(stderr, "error: %s\n", get_nt_error_msg(result));
}
@@ -246,7 +254,7 @@ void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
char* domain, char* password)
{
ZERO_STRUCTP(creds);
-
+
if (lp_encrypted_passwords()) {
pwd_make_lm_nt_16(&creds->pwd, password);
} else {
@@ -255,27 +263,77 @@ void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
fstrcpy(creds->user_name, username);
fstrcpy(creds->domain, domain);
+
+ if (! *username) {
+ creds->pwd.null_pwd = True;
+ }
}
-static uint32 cmd_help(struct cli_state *cli, int argc, char **argv)
+/* Display help on commands */
+
+static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
- struct cmd_list *temp_list;
+ struct cmd_list *tmp;
+ struct cmd_set *tmp_set;
- for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) {
- struct cmd_set *temp_set = temp_list->cmd_set;
+ /* Usage */
- while(temp_set->name) {
- printf("%15s\t\t%s\n", temp_set->name,
- temp_set->description);
- temp_set++;
+ if (argc > 2) {
+ printf("Usage: %s [command]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ /* Help on one command */
+
+ if (argc == 2) {
+ for (tmp = cmd_list; tmp; tmp = tmp->next) {
+
+ tmp_set = tmp->cmd_set;
+
+ while(tmp_set->name) {
+ if (strequal(argv[1], tmp_set->name)) {
+ if (tmp_set->usage &&
+ tmp_set->usage[0])
+ printf("%s\n", tmp_set->usage);
+ else
+ printf("No help for %s\n", tmp_set->name);
+
+ return NT_STATUS_OK;
+ }
+
+ tmp_set++;
+ }
+ }
+
+ printf("No such command: %s\n", argv[1]);
+ return NT_STATUS_OK;
+ }
+
+ /* List all commands */
+
+ for (tmp = cmd_list; tmp; tmp = tmp->next) {
+
+ tmp_set = tmp->cmd_set;
+
+ while(tmp_set->name) {
+
+ printf("%15s\t\t%s\n", tmp_set->name,
+ tmp_set->description ? tmp_set->description:
+ "");
+
+ tmp_set++;
}
}
- return 0;
+ return NT_STATUS_OK;
}
-static uint32 cmd_debuglevel(struct cli_state *cli, int argc, char **argv)
+/* Change the debug level */
+
+static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
if (argc > 2) {
printf("Usage: %s [debuglevel]\n", argv[0]);
@@ -291,7 +349,8 @@ static uint32 cmd_debuglevel(struct cli_state *cli, int argc, char **argv)
return NT_STATUS_OK;
}
-static uint32 cmd_quit(struct cli_state *cli, int argc, char **argv)
+static NTSTATUS cmd_quit(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
{
exit(0);
return NT_STATUS_OK; /* NOTREACHED */
@@ -300,19 +359,21 @@ static uint32 cmd_quit(struct cli_state *cli, int argc, char **argv)
/* Build in rpcclient commands */
static struct cmd_set rpcclient_commands[] = {
- { "GENERAL OPTIONS", NULL, "" },
- { "help", cmd_help, "Print list of commands" },
- { "?", cmd_help, "Print list of commands" },
- { "debuglevel", cmd_debuglevel, "Set debug level" },
- { "exit", cmd_quit, "Exit program" },
- { "quit", cmd_quit, "Exit program" },
-
- { NULL, NULL, NULL }
+
+ { "GENERAL OPTIONS" },
+
+ { "help", cmd_help, NULL, "Get help on commands", "[command]" },
+ { "?", cmd_help, NULL, "Get help on commands", "[command]" },
+ { "debuglevel", cmd_debuglevel, NULL, "Set debug level", "level" },
+ { "exit", cmd_quit, NULL, "Exit program", "" },
+ { "quit", cmd_quit, NULL, "Exit program", "" },
+
+ { NULL }
};
static struct cmd_set separator_command[] = {
- { "---------------", NULL, "----------------------" },
- { NULL, NULL, NULL }
+ { "---------------", NULL, NULL, "----------------------" },
+ { NULL }
};
@@ -323,6 +384,8 @@ extern struct cmd_set samr_commands[];
extern struct cmd_set spoolss_commands[];
extern struct cmd_set netlogon_commands[];
extern struct cmd_set srvsvc_commands[];
+extern struct cmd_set dfs_commands[];
+extern struct cmd_set reg_commands[];
static struct cmd_set *rpcclient_command_list[] = {
rpcclient_commands,
@@ -331,10 +394,12 @@ static struct cmd_set *rpcclient_command_list[] = {
spoolss_commands,
netlogon_commands,
srvsvc_commands,
+ dfs_commands,
+ reg_commands,
NULL
};
-void add_command_set(struct cmd_set *cmd_set)
+static void add_command_set(struct cmd_set *cmd_set)
{
struct cmd_list *entry;
@@ -349,20 +414,19 @@ void add_command_set(struct cmd_set *cmd_set)
DLIST_ADD(cmd_list, entry);
}
-static uint32 do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry, char *cmd)
+static NTSTATUS do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry,
+ char *cmd)
{
char *p = cmd, **argv = NULL;
- uint32 result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
pstring buf;
- int argc = 1, i;
-
- next_token(&p, buf, " ", sizeof(buf));
+ int argc = 0, i;
/* Count number of arguments first time through the loop then
allocate memory and strdup them. */
again:
- while(next_token(NULL, buf, " ", sizeof(buf))) {
+ while(next_token(&p, buf, " ", sizeof(buf))) {
if (argv) {
argv[argc] = strdup(buf);
}
@@ -375,56 +439,87 @@ static uint32 do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry, char *cmd
/* Create argument list */
argv = (char **)malloc(sizeof(char *) * argc);
-
if (!argv) {
- fprintf(stderr, "out of memoryx\n");
- return 0;
+ fprintf(stderr, "out of memory\n");
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
+ memset(argv, 0, sizeof(char *) * argc);
+
p = cmd;
- next_token(&p, buf, " ", sizeof(buf));
- argv[0] = strdup(buf);
- argc = 1;
+ argc = 0;
goto again;
}
/* Call the function */
+
if (cmd_entry->fn) {
- result = cmd_entry->fn(cli, argc, argv);
- }
- else {
+ TALLOC_CTX *mem_ctx;
+
+ /* Create mem_ctx */
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("talloc_init() failed\n"));
+ goto done;
+ }
+
+ /* Open pipe */
+
+ if (cmd_entry->pipe)
+ if (!cli_nt_session_open(cli, cmd_entry->pipe)) {
+ DEBUG(0, ("Could not initialise %s\n",
+ cmd_entry->pipe));
+ goto done;
+ }
+
+ /* Run command */
+
+ result = cmd_entry->fn(cli, mem_ctx, argc, argv);
+
+ /* Cleanup */
+
+ if (cmd_entry->pipe)
+ cli_nt_session_close(cli);
+
+ talloc_destroy(mem_ctx);
+
+ } else {
fprintf (stderr, "Invalid command\n");
- result = NT_STATUS_INVALID_PARAMETER;
- }
+ goto done;
+ }
+ done:
/* Cleanup */
- for (i = 0; i < argc; i++) {
- free(argv[i]);
- }
+
+ if (argv) {
+ for (i = 0; i < argc; i++)
+ SAFE_FREE(argv[i]);
- free(argv);
+ SAFE_FREE(argv);
+ }
return result;
}
/* Process a command entered at the prompt or as part of -c */
-static uint32 process_cmd(struct cli_state *cli, char *cmd)
+static NTSTATUS process_cmd(struct cli_state *cli, char *cmd)
{
struct cmd_list *temp_list;
BOOL found = False;
pstring buf;
char *p = cmd;
- uint32 result=0;
+ NTSTATUS result = NT_STATUS_OK;
int len = 0;
if (cmd[strlen(cmd) - 1] == '\n')
cmd[strlen(cmd) - 1] = '\0';
if (!next_token(&p, buf, " ", sizeof(buf))) {
- return 0;
+ return NT_STATUS_OK;
}
/* strip the trainly \n if it exsists */
@@ -439,8 +534,9 @@ static uint32 process_cmd(struct cli_state *cli, char *cmd)
while(temp_set->name) {
if (strequal(buf, temp_set->name)) {
- found = True;
+ found = True;
result = do_cmd(cli, temp_set, cmd);
+
goto done;
}
temp_set++;
@@ -450,10 +546,10 @@ static uint32 process_cmd(struct cli_state *cli, char *cmd)
done:
if (!found && buf[0]) {
printf("command not found: %s\n", buf);
- return 0;
+ return NT_STATUS_OK;
}
- if (result != 0) {
+ if (!NT_STATUS_IS_OK(result)) {
printf("result was %s\n", get_nt_error_msg(result));
}
@@ -485,6 +581,7 @@ struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
/* Establish a SMB connection */
if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
+ fprintf(stderr, "Could not resolve %s\n", dest_host);
return NULL;
}
@@ -493,6 +590,7 @@ struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
&called, "IPC$", "IPC", False, True)) {
+ fprintf(stderr, "Error establishing IPC$ connection\n");
return NULL;
}
@@ -503,7 +601,7 @@ struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
/* Print usage information */
static void usage(void)
{
- printf("Usage: rpcclient server [options]\n");
+ printf("Usage: rpcclient [options] server\n");
printf("\t-A authfile file containing user credentials\n");
printf("\t-c \"command string\" execute semicolon separated cmds\n");
@@ -536,14 +634,14 @@ static void usage(void)
username,
domain,
server;
+ pstring logfile;
struct cmd_set **cmd_set;
- charset_initialise();
setlinebuf(stdout);
DEBUGLEVEL = 1;
- while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:")) != EOF) {
+ while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:h")) != EOF) {
switch (opt) {
case 'A':
/* only get the username, password, and domain from the file */
@@ -561,7 +659,8 @@ static void usage(void)
break;
case 'l':
- slprintf(debugf, sizeof(debugf) - 1, "%s.client", optarg);
+ slprintf(logfile, sizeof(logfile) - 1, "%s.client", optarg);
+ lp_set_logfile(logfile);
interactive = False;
break;
@@ -595,27 +694,30 @@ static void usage(void)
exit(1);
}
}
-
+
argv += optind;
argc -= optind;
-
+
/* Parse options */
if (argc == 0) {
usage();
return 0;
}
-
+
if (strncmp("//", argv[0], 2) == 0 || strncmp("\\\\", argv[0], 2) == 0)
argv[0] += 2;
-
+
pstrcpy(server, argv[0]);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
- setup_logging (argv[0], interactive);
+ setup_logging("rpcclient", interactive);
if (!interactive)
reopen_logs();
+ TimeInit();
+ charset_initialise();
+
/* Load smb.conf file */
/* FIXME! How to get this DEBUGLEVEL to last over lp_load()? */
olddebug = DEBUGLEVEL;
@@ -625,9 +727,8 @@ static void usage(void)
DEBUGLEVEL = olddebug;
codepage_initialise(lp_client_code_page());
- load_interfaces();
- TimeInit();
+ load_interfaces();
get_myname((*global_myname)?NULL:global_myname);
strupper(global_myname);
@@ -636,8 +737,8 @@ static void usage(void)
* initialize the credentials struct. Get password
* from stdin if necessary
*/
- if (!strlen(username))
- get_username (username);
+ if (!strlen(username) && !got_pass)
+ get_username(username);
if (!got_pass) {
init_rpcclient_creds (&creds, username, domain, "");
@@ -668,12 +769,15 @@ static void usage(void)
cmd_set++;
}
- /* Do anything specified with -c */
+ fetch_machine_sid(&cli);
+
+ /* Do anything specified with -c */
if (cmdstr[0]) {
char *cmd;
char *p = cmdstr;
while((cmd=next_command(&p)) != NULL) {
+ printf("%s\n", cmd);
process_cmd(&cli, cmd);
}
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index 13ff399da0d..68720258ec0 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -120,7 +120,7 @@ END {
gotstart = 1;
}
- if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T/ ) {
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^NTSTATUS|^WERROR|^CLI_POLICY_HND/ ) {
gotstart = 1;
}
diff --git a/source/smbd/.cvsignore b/source/smbd/.cvsignore
index e69de29bb2d..5f2a5c4cf75 100644
--- a/source/smbd/.cvsignore
+++ b/source/smbd/.cvsignore
@@ -0,0 +1,2 @@
+*.po
+*.po32
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 6f633c0bc20..0d2a99b3f07 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -20,7 +20,7 @@
*/
#include "includes.h"
-extern int DEBUGLEVEL;
+
extern char *OutBuffer;
/****************************************************************************
@@ -46,8 +46,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu
static void free_blocking_lock_record(blocking_lock_record *blr)
{
- free(blr->inbuf);
- free((char *)blr);
+ SAFE_FREE(blr->inbuf);
+ SAFE_FREE(blr);
}
/****************************************************************************
@@ -103,7 +103,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int
if((blr->inbuf = (char *)malloc(length)) == NULL) {
DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
- free((char *)blr);
+ SAFE_FREE(blr);
return False;
}
@@ -134,7 +134,7 @@ static void send_blocking_reply(char *outbuf, int outsize)
smb_setlen(outbuf,outsize - 4);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_blocking_reply: send_smb failed.\n");
+ exit_server("send_blocking_reply: send_smb failed.");
}
/****************************************************************************
@@ -170,15 +170,15 @@ static void reply_lockingX_success(blocking_lock_record *blr)
Return a generic lock fail error blocking call.
*****************************************************************************/
-static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, int32 ecode)
+static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status)
{
char *outbuf = OutBuffer;
char *inbuf = blr->inbuf;
construct_reply_common(inbuf, outbuf);
- ERROR(eclass,ecode);
+ ERROR_NT(status);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("generic_blocking_lock_error: send_smb failed.\n");
+ exit_server("generic_blocking_lock_error: send_smb failed.");
}
/****************************************************************************
@@ -186,72 +186,68 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i
obtained first.
*****************************************************************************/
-static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ecode)
+static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
{
- char *inbuf = blr->inbuf;
- files_struct *fsp = blr->fsp;
- connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0;
- uint16 lock_pid;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
- BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- char *data;
- int i;
-
- data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
-
- /*
- * Data now points at the beginning of the list
- * of smb_lkrng structs.
- */
-
- /*
- * Ensure we don't do a remove on the lock that just failed,
- * as under POSIX rules, if we have a lock already there, we
- * will delete it (and we shouldn't) .....
- */
-
- for(i = blr->lock_num - 1; i >= 0; i--) {
- int dummy1;
- uint32 dummy2;
- BOOL err;
-
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
-
- /*
- * We know err cannot be set as if it was the lock
- * request would never have been queued. JRA.
- */
-
- do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2);
- }
-
- generic_blocking_lock_error(blr, eclass, ecode);
+ char *inbuf = blr->inbuf;
+ files_struct *fsp = blr->fsp;
+ connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
+ uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
+ SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0;
+ uint16 lock_pid;
+ unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
+ char *data;
+ int i;
+
+ data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
+
+ /*
+ * Data now points at the beginning of the list
+ * of smb_lkrng structs.
+ */
+
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+
+ for(i = blr->lock_num - 1; i >= 0; i--) {
+ BOOL err;
+
+ lock_pid = get_lock_pid( data, i, large_file_format);
+ count = get_lock_count( data, i, large_file_format);
+ offset = get_lock_offset( data, i, large_file_format, &err);
+
+ /*
+ * We know err cannot be set as if it was the lock
+ * request would never have been queued. JRA.
+ */
+
+ do_unlock(fsp,conn,lock_pid,count,offset);
+ }
+
+ generic_blocking_lock_error(blr, status);
}
/****************************************************************************
Return a lock fail error.
*****************************************************************************/
-static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int32 ecode)
+static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status)
{
- switch(blr->com_type) {
- case SMBlock:
- generic_blocking_lock_error(blr, eclass, ecode);
- break;
- case SMBlockread:
- generic_blocking_lock_error(blr, eclass, ecode);
- break;
- case SMBlockingX:
- reply_lockingX_error(blr, eclass, ecode);
- break;
- default:
- DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
- exit_server("PANIC - unknown type on blocking lock queue");
- }
+ switch(blr->com_type) {
+ case SMBlock:
+ case SMBlockread:
+ generic_blocking_lock_error(blr, status);
+ break;
+ case SMBlockingX:
+ reply_lockingX_error(blr, status);
+ break;
+ default:
+ DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
+ exit_server("PANIC - unknown type on blocking lock queue");
+ }
}
/****************************************************************************
@@ -261,65 +257,68 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, int eclass, int
static BOOL process_lockread(blocking_lock_record *blr)
{
- char *outbuf = OutBuffer;
- char *inbuf = blr->inbuf;
- ssize_t nread = -1;
- char *data;
- int outsize = 0;
- SMB_OFF_T startpos;
- size_t numtoread;
- int eclass;
- uint32 ecode;
- connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
- files_struct *fsp = blr->fsp;
-
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
+ char *outbuf = OutBuffer;
+ char *inbuf = blr->inbuf;
+ ssize_t nread = -1;
+ char *data, *p;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t numtoread;
+ NTSTATUS status;
+ connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
+ files_struct *fsp = blr->fsp;
+
+ numtoread = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL(inbuf,smb_vwv2);
+
+ numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
+ data = smb_buf(outbuf) + 3;
- if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, READ_LOCK, &eclass, &ecode)) {
- if((errno != EACCES) && (errno != EAGAIN)) {
- /*
- * We have other than a "can't get lock" POSIX
- * error. Send an error.
- * Return True so we get dequeued.
- */
-
- generic_blocking_lock_error(blr, eclass, ecode);
- return True;
- }
-
- /*
- * Still waiting for lock....
- */
-
- DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n",
- fsp->fsp_name));
- return False;
- }
-
- nread = read_file(fsp,data,startpos,numtoread);
-
- if (nread < 0) {
- generic_blocking_lock_error(blr,ERRDOS,ERRnoaccess);
- return True;
- }
-
- construct_reply_common(inbuf, outbuf);
- outsize = set_message(outbuf,5,3,True);
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
- fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
-
- send_blocking_reply(outbuf,outsize);
- return True;
+ status = do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread,
+ (SMB_BIG_UINT)startpos, READ_LOCK);
+ if (NT_STATUS_V(status)) {
+ if ((errno != EACCES) && (errno != EAGAIN)) {
+ /*
+ * We have other than a "can't get lock" POSIX
+ * error. Send an error.
+ * Return True so we get dequeued.
+ */
+ generic_blocking_lock_error(blr, status);
+ return True;
+ }
+
+ /*
+ * Still waiting for lock....
+ */
+
+ DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n",
+ fsp->fsp_name));
+ return False;
+ }
+
+ nread = read_file(fsp,data,startpos,numtoread);
+
+ if (nread < 0) {
+ generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED);
+ return True;
+ }
+
+ construct_reply_common(inbuf, outbuf);
+ outsize = set_message(outbuf,5,0,True);
+
+ outsize += nread;
+ SSVAL(outbuf,smb_vwv0,nread);
+ SSVAL(outbuf,smb_vwv5,nread+3);
+ p = smb_buf(outbuf);
+ *p++ = 1;
+ SSVAL(p,0,nread); p += 2;
+ set_message_end(outbuf, p+nread);
+
+ DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
+ fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
+
+ send_blocking_reply(outbuf,outsize);
+ return True;
}
/****************************************************************************
@@ -329,52 +328,50 @@ static BOOL process_lockread(blocking_lock_record *blr)
static BOOL process_lock(blocking_lock_record *blr)
{
- char *outbuf = OutBuffer;
- char *inbuf = blr->inbuf;
- int outsize;
- SMB_OFF_T count = 0, offset = 0;
- int eclass;
- uint32 ecode;
- connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
- files_struct *fsp = blr->fsp;
-
- count = IVAL(inbuf,smb_vwv1);
- offset = IVAL(inbuf,smb_vwv3);
-
- errno = 0;
- if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count, (SMB_BIG_UINT)offset, WRITE_LOCK, &eclass, &ecode)) {
- if((errno != EACCES) && (errno != EAGAIN)) {
-
- /*
- * We have other than a "can't get lock" POSIX
- * error. Send an error.
- * Return True so we get dequeued.
- */
-
- blocking_lock_reply_error(blr, eclass, ecode);
- return True;
- }
-
- /*
- * Still can't get the lock - keep waiting.
- */
-
- DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n",
- fsp->fsp_name));
- return False;
- }
-
- /*
- * Success - we got the lock.
- */
-
- DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n",
- fsp->fsp_name, fsp->fnum, (double)offset, (double)count));
-
- construct_reply_common(inbuf, outbuf);
- outsize = set_message(outbuf,0,0,True);
- send_blocking_reply(outbuf,outsize);
- return True;
+ char *outbuf = OutBuffer;
+ char *inbuf = blr->inbuf;
+ int outsize;
+ SMB_OFF_T count = 0, offset = 0;
+ NTSTATUS status;
+ connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
+ files_struct *fsp = blr->fsp;
+
+ count = IVAL(inbuf,smb_vwv1);
+ offset = IVAL(inbuf,smb_vwv3);
+
+ errno = 0;
+ status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count,
+ (SMB_BIG_UINT)offset, WRITE_LOCK);
+ if (NT_STATUS_IS_ERR(status)) {
+ if((errno != EACCES) && (errno != EAGAIN)) {
+ /*
+ * We have other than a "can't get lock" POSIX
+ * error. Send an error.
+ * Return True so we get dequeued.
+ */
+
+ blocking_lock_reply_error(blr, status);
+ return True;
+ }
+ /*
+ * Still can't get the lock - keep waiting.
+ */
+ DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n",
+ fsp->fsp_name));
+ return False;
+ }
+
+ /*
+ * Success - we got the lock.
+ */
+
+ DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n",
+ fsp->fsp_name, fsp->fnum, (double)offset, (double)count));
+
+ construct_reply_common(inbuf, outbuf);
+ outsize = set_message(outbuf,0,0,True);
+ send_blocking_reply(outbuf,outsize);
+ return True;
}
/****************************************************************************
@@ -384,75 +381,72 @@ static BOOL process_lock(blocking_lock_record *blr)
static BOOL process_lockingX(blocking_lock_record *blr)
{
- char *inbuf = blr->inbuf;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
- files_struct *fsp = blr->fsp;
- connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- uint16 num_locks = SVAL(inbuf,smb_vwv7);
- SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0;
- uint16 lock_pid;
- BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- char *data;
- int eclass=0;
- uint32 ecode=0;
-
- data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
-
- /*
- * Data now points at the beginning of the list
- * of smb_lkrng structs.
- */
-
- for(; blr->lock_num < num_locks; blr->lock_num++) {
- BOOL err;
-
- lock_pid = get_lock_pid( data, blr->lock_num, large_file_format);
- count = get_lock_count( data, blr->lock_num, large_file_format);
- offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
-
- /*
- * We know err cannot be set as if it was the lock
- * request would never have been queued. JRA.
- */
- errno = 0;
- if(!do_lock(fsp,conn,lock_pid,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
- &eclass, &ecode))
- break;
- }
-
- if(blr->lock_num == num_locks) {
-
- /*
- * Success - we got all the locks.
- */
-
- DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
- fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
-
- reply_lockingX_success(blr);
- return True;
-
- } else if((errno != EACCES) && (errno != EAGAIN)) {
-
- /*
- * We have other than a "can't get lock" POSIX
- * error. Free any locks we had and return an error.
- * Return True so we get dequeued.
- */
-
- blocking_lock_reply_error(blr, eclass, ecode);
- return True;
- }
-
- /*
- * Still can't get all the locks - keep waiting.
- */
-
- DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
-Waiting....\n", blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
-
- return False;
+ char *inbuf = blr->inbuf;
+ unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ files_struct *fsp = blr->fsp;
+ connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
+ uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
+ uint16 num_locks = SVAL(inbuf,smb_vwv7);
+ SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0;
+ uint16 lock_pid;
+ BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
+ char *data;
+ NTSTATUS status = NT_STATUS_OK;
+
+ data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
+
+ /*
+ * Data now points at the beginning of the list
+ * of smb_lkrng structs.
+ */
+
+ for(; blr->lock_num < num_locks; blr->lock_num++) {
+ BOOL err;
+
+ lock_pid = get_lock_pid( data, blr->lock_num, large_file_format);
+ count = get_lock_count( data, blr->lock_num, large_file_format);
+ offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
+
+ /*
+ * We know err cannot be set as if it was the lock
+ * request would never have been queued. JRA.
+ */
+ errno = 0;
+ status = do_lock(fsp,conn,lock_pid,count,offset,
+ ((locktype & 1) ? READ_LOCK : WRITE_LOCK));
+ if (NT_STATUS_IS_ERR(status)) break;
+ }
+
+ if(blr->lock_num == num_locks) {
+ /*
+ * Success - we got all the locks.
+ */
+
+ DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
+ fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
+
+ reply_lockingX_success(blr);
+ return True;
+ } else if ((errno != EACCES) && (errno != EAGAIN)) {
+ /*
+ * We have other than a "can't get lock" POSIX
+ * error. Free any locks we had and return an error.
+ * Return True so we get dequeued.
+ */
+
+ blocking_lock_reply_error(blr, status);
+ return True;
+ }
+
+ /*
+ * Still can't get all the locks - keep waiting.
+ */
+
+ DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
+Waiting....\n",
+ blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
+
+ return False;
}
/****************************************************************************
@@ -517,7 +511,7 @@ void remove_pending_lock_requests_by_mid(int mid)
DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- blocking_lock_reply_error(blr,0,NT_STATUS_CANCELLED);
+ blocking_lock_reply_error(blr,NT_STATUS_CANCELLED);
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;
@@ -582,33 +576,33 @@ 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,ERRSRV,ERRaccess);
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
continue;
}
- if(!become_user(conn,vuid)) {
+ if(!change_to_user(conn,vuid)) {
DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
vuid ));
/*
* Remove the entry and return an error to the client.
*/
- blocking_lock_reply_error(blr,ERRSRV,ERRaccess);
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
continue;
}
- if(!become_service(conn,True)) {
+ if(!set_current_service(conn,True)) {
DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
/*
* Remove the entry and return an error to the client.
*/
- blocking_lock_reply_error(blr,ERRSRV,ERRaccess);
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
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));
- unbecome_user();
+ change_to_root_user();
continue;
}
@@ -621,11 +615,11 @@ void process_blocking_lock_queue(time_t t)
if(blocking_lock_record_process(blr)) {
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));
- unbecome_user();
+ change_to_root_user();
continue;
}
- unbecome_user();
+ change_to_root_user();
/*
* Move to the next in the list.
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 245c1d1ea9b..bc91d776936 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -49,7 +49,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern struct passdb_ops pdb_ops;
#if ALLOW_CHANGE_PASSWORD
@@ -309,6 +308,12 @@ static int talktochild(int master, char *seq)
pwd_sub(issue);
}
+ if (!strequal(issue, ".")) {
+ /* we have one final issue to send */
+ fstrcpy(expected, ".");
+ if (!expect(master, issue, expected))
+ return False;
+ }
return (count > 0);
}
@@ -754,6 +759,7 @@ BOOL check_oem_password(char *user,
if (ret == False) {
DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n"));
+ pdb_free_sam(sampass);
return False;
}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 7c0672efe0d..ca030ed1404 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
run a file if it is a magic script
****************************************************************************/
@@ -102,10 +100,7 @@ static int close_filestruct(files_struct *fsp)
fsp->stat_open = False;
conn->num_files_open--;
- if(fsp->wbmpx_ptr) {
- free((char *)fsp->wbmpx_ptr);
- fsp->wbmpx_ptr = NULL;
- }
+ SAFE_FREE(fsp->wbmpx_ptr);
return ret;
}
@@ -172,21 +167,21 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* reference to a file.
*/
- if (normal_close && delete_on_close) {
- DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
- fsp->fsp_name));
+ if (normal_close && delete_on_close) {
+ DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
+ fsp->fsp_name));
if(fsp->conn->vfs_ops.unlink(conn,dos_to_unix(fsp->fsp_name, False)) != 0) {
- /*
- * This call can potentially fail as another smbd may have
- * had the file open with delete on close set and deleted
- * it when its last reference to this file went away. Hence
- * we log this but not at debug level zero.
- */
-
- DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
+ /*
+ * This call can potentially fail as another smbd may have
+ * had the file open with delete on close set and deleted
+ * it when its last reference to this file went away. Hence
+ * we log this but not at debug level zero.
+ */
+
+ DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
with error %s\n", fsp->fsp_name, strerror(errno) ));
- }
- }
+ }
+ }
unlock_share_entry_fsp(fsp);
@@ -202,14 +197,22 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
check_magic(fsp,conn);
}
+ /*
+ * Ensure pending modtime is set after close.
+ */
+
+ if(fsp->pending_modtime) {
+ int saved_errno = errno;
+ set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
+ errno = saved_errno;
+ }
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
conn->user,fsp->fsp_name,
conn->num_files_open, err ? strerror(err) : ""));
- if (fsp->fsp_name) {
+ if (fsp->fsp_name)
string_free(&fsp->fsp_name);
- }
file_free(fsp);
@@ -244,7 +247,7 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
if(ok)
remove_pending_change_notify_requests_by_filename(fsp);
- }
+ }
/*
* Do the code common to files and directories.
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index 725ab22dc44..7e8a8383213 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* set these to define the limits of the server. NOTE These are on a
per-client basis. Thus any one machine can't connect to more than
MAX_CONNECTIONS services, but any number of machines may connect at
@@ -177,7 +175,7 @@ void conn_free(connection_struct *conn)
DLIST_REMOVE(Connections, conn);
if (conn->ngroups && conn->groups) {
- free(conn->groups);
+ SAFE_FREE(conn->groups);
conn->groups = NULL;
conn->ngroups = 0;
}
@@ -196,7 +194,7 @@ void conn_free(connection_struct *conn)
num_open--;
ZERO_STRUCTP(conn);
- free(conn);
+ SAFE_FREE(conn);
}
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index 9e074a8e809..3ca4021abe4 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -25,8 +25,6 @@
extern fstring remote_machine;
static TDB_CONTEXT *tdb;
-extern int DEBUGLEVEL;
-
/****************************************************************************
Return the connection tdb context (used for message send all).
****************************************************************************/
@@ -40,7 +38,7 @@ TDB_CONTEXT *conn_tdb_ctx(void)
Delete a connection record.
****************************************************************************/
-BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
+BOOL yield_connection(connection_struct *conn,char *name)
{
struct connections_key key;
TDB_DATA kbuf;
@@ -59,8 +57,9 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
kbuf.dsize = sizeof(key);
if (tdb_delete(tdb, kbuf) != 0) {
- DEBUG(0,("yield_connection: tdb_delete for name %s failed with error %s.\n",
- name, tdb_errorstr(tdb) ));
+ int dbg_lvl = (!conn && (tdb_error(tdb) == TDB_ERR_NOEXIST)) ? 3 : 0;
+ DEBUG(dbg_lvl,("yield_connection: tdb_delete for name %s failed with error %s.\n",
+ name, tdb_errorstr(tdb) ));
return (False);
}
@@ -88,7 +87,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 */
diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c
index 64c6182cd8d..034e1a093d3 100644
--- a/source/smbd/dfree.c
+++ b/source/smbd/dfree.c
@@ -21,9 +21,6 @@
#include "includes.h"
-
-extern int DEBUGLEVEL;
-
/****************************************************************************
normalise for DOS usage
****************************************************************************/
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index fa9cbdc4a2a..789ff919eea 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/*
This module implements directory related functions for Samba.
*/
@@ -246,10 +244,9 @@ static void dptr_close_internal(dptr_struct *dptr)
}
/* Lanman 2 specific code */
- if (dptr->wcard)
- free(dptr->wcard);
+ SAFE_FREE(dptr->wcard);
string_set(&dptr->path,"");
- free((char *)dptr);
+ SAFE_FREE(dptr);
}
/****************************************************************************
@@ -438,7 +435,7 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect
if(dptr->dnum == -1 || dptr->dnum > 254) {
DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
- free((char *)dptr);
+ SAFE_FREE(dptr);
return -1;
}
}
@@ -467,7 +464,7 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect
if(dptr->dnum == -1 || dptr->dnum < 255) {
DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
- free((char *)dptr);
+ SAFE_FREE(dptr);
return -1;
}
}
@@ -669,12 +666,47 @@ 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)
{
+ extern struct current_user current_user;
SMB_STRUCT_STAT ste;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
+ files_struct *fsp;
+ int smb_action;
+ NTSTATUS status;
+ uint32 access_granted;
+
+ ZERO_STRUCT(ste);
/* if we can't stat it does not show it */
- if (vfs_stat(conn, name, &ste) != 0) return False;
+ if (vfs_stat(conn, name, &ste) != 0)
+ return False;
+
+ /* Pseudo-open the file (note - no fd's created). */
+
+ if(S_ISDIR(ste.st_mode))
+ fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), FILE_OPEN,
+ unix_mode(conn,aRONLY|aDIR, name), &smb_action);
+ else
+ fsp = open_file_stat(conn,name,&ste,DOS_OPEN_RDONLY,&smb_action);
+ if (!fsp)
+ return False;
+
+ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
+ sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
+ close_file(fsp, True);
+
+ /* No access if SD get failed. */
+ if (!sd_size)
+ return False;
+
+ return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
+ &access_granted, &status);
+
+#if 0
+ /* Old - crappy check :-). JRA */
if (ste.st_uid == conn->uid) {
return (ste.st_mode & S_IRUSR) == S_IRUSR;
@@ -691,6 +723,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
}
return (ste.st_mode & S_IROTH) == S_IROTH;
+#endif
}
/*******************************************************************
@@ -733,7 +766,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
ret = user_can_read_file(conn, entry);
- free(entry);
+ SAFE_FREE(entry);
}
if (!ret) continue;
}
@@ -768,8 +801,8 @@ void CloseDir(void *p)
{
Dir *dirp = (Dir *)p;
if (!dirp) return;
- if (dirp->data) free(dirp->data);
- free(dirp);
+ SAFE_FREE(dirp->data);
+ SAFE_FREE(dirp);
}
/*******************************************************************
@@ -878,7 +911,7 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum )
/* Free excess cache entries. */
while( DIRCACHESIZE < dir_cache->count )
- free( ubi_dlRemTail( dir_cache ) );
+ safe_free( ubi_dlRemTail( dir_cache ) );
}
@@ -930,7 +963,7 @@ void DirCacheFlush(int snum)
NULL != entry; ) {
next = ubi_dlNext( entry );
if( entry->snum == snum )
- free( ubi_dlRemThis( dir_cache, entry ) );
+ safe_free( ubi_dlRemThis( dir_cache, entry ) );
entry = (dir_cache_entry *)next;
}
}
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 9ec1fa26069..d7b40198771 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
diff --git a/source/smbd/error.c b/source/smbd/error.c
index 164f4e42a56..0a63d520ee6 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -21,50 +21,39 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-extern uint32 global_client_caps;
-
/* these can be set by some functions to override the error codes */
int unix_ERR_class=SMB_SUCCESS;
int unix_ERR_code=0;
-struct {
- int unixerror;
- int smbclass;
- int smbcode;
-} unix_smb_errmap[] = {
- {EPERM,ERRDOS,ERRnoaccess},
- {EACCES,ERRDOS,ERRnoaccess},
- {ENOENT,ERRDOS,ERRbadfile},
- {ENOTDIR,ERRDOS,ERRbadpath},
- {EIO,ERRHRD,ERRgeneral},
- {EBADF,ERRDOS,ERRbadfid},
- {EINVAL,ERRSRV,ERRsrverror},
- {EEXIST,ERRDOS,ERRfilexists},
- {ENFILE,ERRDOS,ERRnofids},
- {EMFILE,ERRDOS,ERRnofids},
- {ENOSPC,ERRHRD,ERRdiskfull},
-#ifdef EDQUOT
- {EDQUOT,ERRHRD,ERRdiskfull},
-#endif
-#ifdef ENOTEMPTY
- {ENOTEMPTY,ERRDOS,ERRnoaccess},
-#endif
-#ifdef EXDEV
- {EXDEV,ERRDOS,ERRdiffdevice},
-#endif
- {EROFS,ERRHRD,ERRnowrite},
- {0,0,0}
-};
+/* From lib/error.c */
+extern struct unix_error_map unix_dos_nt_errmap[];
+
+/****************************************************************************
+ Create an error packet from a cached error.
+****************************************************************************/
+
+int cached_error_packet(char *outbuf,files_struct *fsp,int line,const char *file)
+{
+ write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
+
+ int32 eclass = wbmpx->wr_errclass;
+ int32 err = wbmpx->wr_error;
+
+ /* We can now delete the auxiliary struct */
+ SAFE_FREE(wbmpx);
+ return error_packet(outbuf,NT_STATUS_OK,eclass,err,line,file);
+}
/****************************************************************************
Create an error packet from errno.
****************************************************************************/
-int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line, const char *file)
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
+ int line, const char *file)
{
int eclass=def_class;
int ecode=def_code;
+ NTSTATUS ntstatus = NT_STATUS_OK;
int i=0;
if (unix_ERR_class != SMB_SUCCESS) {
@@ -73,44 +62,62 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line, const
unix_ERR_class = SMB_SUCCESS;
unix_ERR_code = 0;
} else {
- while (unix_smb_errmap[i].smbclass != 0) {
- if (unix_smb_errmap[i].unixerror == errno) {
- eclass = unix_smb_errmap[i].smbclass;
- ecode = unix_smb_errmap[i].smbcode;
+ while (unix_dos_nt_errmap[i].dos_class != 0) {
+ if (unix_dos_nt_errmap[i].unix_error == errno) {
+ eclass = unix_dos_nt_errmap[i].dos_class;
+ ecode = unix_dos_nt_errmap[i].dos_code;
+ ntstatus = unix_dos_nt_errmap[i].nt_error;
break;
}
i++;
}
}
- return(error_packet(outbuf,0,eclass,ecode,line,file));
+ return error_packet(outbuf,ntstatus,eclass,ecode,line,file);
}
+
/****************************************************************************
Create an error packet. Normally called using the ERROR() macro.
****************************************************************************/
-int error_packet(char *outbuf,uint32 nt_err, int error_class,uint32 error_code,int line, const char *file)
+int error_packet(char *outbuf,NTSTATUS ntstatus,
+ uint8 eclass,uint32 ecode,int line, const char *file)
{
int outsize = set_message(outbuf,0,0,True);
- int cmd = CVAL(outbuf,smb_com);
+ extern uint32 global_client_caps;
if (errno != 0)
DEBUG(3,("error string = %s\n",strerror(errno)));
- if ((global_client_caps & CAP_STATUS32) && (nt_err != 0)) {
- SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
- SIVAL(outbuf,smb_rcls,nt_err);
-
- DEBUG( 3, ( "32 bit error packet at %s(%d) cmd=%d (%s) eclass=%08x [%s]\n",
- file, line, cmd, smb_fn_name(cmd), nt_err, smb_errstr(outbuf) ) );
+ if (global_client_caps & CAP_STATUS32) {
+ if (NT_STATUS_V(ntstatus) == 0 && eclass) {
+ ntstatus = dos_to_ntstatus(eclass, ecode);
+ }
+ SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus));
+ SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES);
+ DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n",
+ file, line,
+ (int)CVAL(outbuf,smb_com),
+ smb_fn_name(CVAL(outbuf,smb_com)),
+ get_nt_error_msg(ntstatus)));
+ return outsize;
+ }
- } else {
- CVAL(outbuf,smb_rcls) = error_class;
- SSVAL(outbuf,smb_err,error_code);
- DEBUG( 3, ( "error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
- file, line, cmd, smb_fn_name(cmd), error_class, error_code ) );
+ if (eclass == 0 && NT_STATUS_V(ntstatus)) {
+ ntstatus_to_dos(ntstatus, &eclass, &ecode);
}
-
- return(outsize);
+
+ SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES);
+ SSVAL(outbuf,smb_rcls,eclass);
+ SSVAL(outbuf,smb_err,ecode);
+
+ DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
+ file, line,
+ (int)CVAL(outbuf,smb_com),
+ smb_fn_name(CVAL(outbuf,smb_com)),
+ eclass,
+ ecode));
+
+ return outsize;
}
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index c79f0aa89e0..ba60690383b 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static BOOL setup_write_cache(files_struct *, SMB_OFF_T);
/****************************************************************************
@@ -93,34 +91,50 @@ read from a file
ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
{
- ssize_t ret=0,readret;
+ ssize_t ret=0,readret;
- /* you can't read from print files */
- if (fsp->print_file) {
- return -1;
- }
+ /* you can't read from print files */
+ if (fsp->print_file)
+ return -1;
- /*
- * Serve from write cache if we can.
- */
- if(read_from_write_cache(fsp, data, pos, n))
- return n;
+ /*
+ * Serve from write cache if we can.
+ */
- flush_write_cache(fsp, READ_FLUSH);
+ if(read_from_write_cache(fsp, data, pos, n))
+ return n;
- if (seek_file(fsp,pos) == -1) {
- DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
- return(ret);
- }
+ flush_write_cache(fsp, READ_FLUSH);
+
+ if (seek_file(fsp,pos) == -1) {
+ DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
+ return(ret);
+ }
- if (n > 0) {
- readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
- if (readret == -1)
- return -1;
- if (readret > 0) ret += readret;
- }
+ if (n > 0) {
+#ifdef DMF_FIX
+ int numretries = 3;
+tryagain:
+ readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
+ if (readret == -1) {
+ if ((errno == EAGAIN) && numretries) {
+ DEBUG(3,("read_file EAGAIN retry in 10 seconds\n"));
+ (void)sleep(10);
+ --numretries;
+ goto tryagain;
+ }
+ return -1;
+ }
+#else /* NO DMF fix. */
+ readret = fsp->conn->vfs_ops.read(fsp,fsp->fd,data,n);
+ if (readret == -1)
+ return -1;
+#endif
+ if (readret > 0)
+ ret += readret;
+ }
- return(ret);
+ return(ret);
}
/* how many write cache buffers have been allocated */
@@ -163,6 +177,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
+ fsp->size = st.st_size;
if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
}
@@ -223,11 +238,14 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
if(!wcp) {
DO_PROFILE_INC(writecache_direct_writes);
- return real_write_file(fsp, data, pos, n);
+ total_written = real_write_file(fsp, data, pos, n);
+ if ((total_written != -1) && (pos + total_written > fsp->size))
+ fsp->size = pos + total_written;
+ return total_written;
}
- DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n",
- fsp->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size));
+ DEBUG(9,("write_file(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
+ fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
/*
* If we have active cache and it isn't contiguous then we flush.
@@ -256,6 +274,13 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
wcp->data_size = pos + data_used - wcp->offset;
/*
+ * Update the file size if changed.
+ */
+
+ if (wcp->offset + wcp->data_size > wcp->file_size)
+ fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
+
+ /*
* If we used all the data then
* return here.
*/
@@ -298,6 +323,13 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
wcp->data_size = pos + n - wcp->offset;
/*
+ * Update the file size if changed.
+ */
+
+ if (wcp->offset + wcp->data_size > wcp->file_size)
+ fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
+
+ /*
* We don't need to move the start of data, but we
* cut down the amount left by the amount used.
*/
@@ -316,12 +348,15 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
write_path = 2;
} else if ( (pos >= wcp->file_size) &&
+ (wcp->offset + wcp->data_size == wcp->file_size) &&
(pos > wcp->offset + wcp->data_size) &&
(pos < wcp->offset + wcp->alloc_size) ) {
/*
* Non-contiguous write part of which fits within
- * the cache buffer and is extending the file.
+ * the cache buffer and is extending the file
+ * and the cache contents reflect the current
+ * data up to the current end of the file.
*/
size_t data_used;
@@ -348,10 +383,11 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
wcp->data_size = pos + data_used - wcp->offset;
/*
- * Update the known file length.
+ * Update the file size if changed.
*/
- wcp->file_size = wcp->offset + wcp->data_size;
+ if (wcp->offset + wcp->data_size > wcp->file_size)
+ fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
/*
* If we used all the data then
@@ -392,7 +428,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
*/
if(pos + n > wcp->file_size)
- wcp->file_size = pos + n;
+ fsp->size = wcp->file_size = pos + n;
/*
* If write would fit in the cache, and is larger than
@@ -404,8 +440,16 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
if ( n <= wcp->alloc_size && n > wcp->data_size) {
cache_flush_needed = True;
} else {
- DO_PROFILE_INC(writecache_direct_writes);
- return real_write_file(fsp, data, pos, n);
+ ssize_t ret = real_write_file(fsp, data, pos, n);
+
+ DO_PROFILE_INC(writecache_direct_writes);
+ if (ret == -1)
+ return ret;
+
+ if (pos + ret > wcp->file_size)
+ fsp->size = wcp->file_size = pos + ret;
+
+ return ret;
}
write_path = 4;
@@ -413,7 +457,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
}
if(wcp->data_size > wcp->file_size)
- wcp->file_size = wcp->data_size;
+ fsp->size = wcp->file_size = wcp->data_size;
if (cache_flush_needed) {
DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
@@ -431,8 +475,13 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
*/
if (n > wcp->alloc_size ) {
- if(real_write_file(fsp, data, pos, n) == -1)
+ ssize_t ret = real_write_file(fsp, data, pos, n);
+ if (ret == -1)
return -1;
+
+ if (pos + ret > wcp->file_size)
+ fsp->size = wcp->file_size = pos + n;
+
DO_PROFILE_INC(writecache_direct_writes);
return total_written + n;
}
@@ -455,7 +504,16 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
DO_PROFILE_INC(writecache_num_write_caches);
}
wcp->data_size += n;
- DEBUG(9,("cache return %u\n", (unsigned int)n));
+
+ /*
+ * Update the file size if changed.
+ */
+
+ if (wcp->offset + wcp->data_size > wcp->file_size)
+ fsp->size = wcp->file_size = wcp->offset + wcp->data_size;
+ DEBUG(9,("wcp->offset = %.0f wcp->data_size = %u cache return %u\n",
+ (double)wcp->offset, (unsigned int)wcp->data_size, (unsigned int)n));
+
total_written += n;
return total_written; /* .... that's a write :) */
}
@@ -482,10 +540,8 @@ void delete_write_cache(files_struct *fsp)
SMB_ASSERT(wcp->data_size == 0);
- free(wcp->data);
- free(wcp);
-
- fsp->wcp = NULL;
+ SAFE_FREE(wcp->data);
+ SAFE_FREE(fsp->wcp);
DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name ));
@@ -518,10 +574,12 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
if((wcp->data = malloc(wcp->alloc_size)) == NULL) {
DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n",
(unsigned int)wcp->alloc_size ));
- free(wcp);
+ SAFE_FREE(wcp);
return False;
}
+ memset(wcp->data, '\0', wcp->alloc_size );
+
fsp->wcp = wcp;
DO_PROFILE_INC(writecache_allocated_write_caches);
allocated_write_caches++;
@@ -538,8 +596,15 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
{
+ fsp->size = file_size;
if(fsp->wcp) {
- flush_write_cache(fsp, SIZECHANGE_FLUSH);
+ /* The cache *must* have been flushed before we do this. */
+ if (fsp->wcp->data_size != 0) {
+ pstring msg;
+ slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \
+on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size );
+ smb_panic(msg);
+ }
fsp->wcp->file_size = file_size;
}
}
@@ -552,6 +617,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
{
write_cache *wcp = fsp->wcp;
size_t data_size;
+ ssize_t ret;
if(!wcp || !wcp->data_size)
return 0;
@@ -569,7 +635,16 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
DO_PROFILE_INC(writecache_num_perfect_writes);
#endif
- return real_write_file(fsp, wcp->data, wcp->offset, data_size);
+ ret = real_write_file(fsp, wcp->data, wcp->offset, data_size);
+
+ /*
+ * Ensure file size if kept up to date if write extends file.
+ */
+
+ if ((ret != -1) && (wcp->offset + ret > wcp->file_size))
+ wcp->file_size = wcp->offset + ret;
+
+ return ret;
}
/*******************************************************************
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index bdbcd81b644..601c488fc9c 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -27,7 +27,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
@@ -293,7 +292,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
} else {
pstring rest;
- /* Stat failed - ensure we don't use it. */
+ /* Stat failed - ensure we don't use it. */
ZERO_STRUCT(st);
*rest = 0;
@@ -330,7 +329,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
/*
* Just the last part of the name doesn't exist.
- * We may need to strupper() or strlower() it in case
+ * We may need to strupper() or strlower() it in case
* this conversion is being used for file creation
* purposes. If the filename is of mixed case then
* don't normalise it.
@@ -353,11 +352,14 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
}
/*
- * Restore the rest of the string.
+ * Restore the rest of the string. If the string was mangled the size
+ * may have changed.
*/
if (end) {
- pstrcpy(start+strlen(start)+1,rest);
end = start + strlen(start);
+ pstrcat(start,"/");
+ pstrcat(start,rest);
+ *end = '\0';
}
} /* end else */
@@ -495,11 +497,25 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
continue;
+ /*
+ * dname here is the unmangled name.
+ */
pstrcpy(name2,dname);
if (!name_map_mangle(name2,False,True,SNUM(conn)))
continue;
- if ((mangled && mangled_equal(name,name2)) || fname_equal(name, name2)) {
+ /*
+ * At this point name2 is the mangled name, dname is the unmangled name.
+ * name is either mangled or not, depending on the state of the "mangled"
+ * variable. JRA.
+ */
+
+ /*
+ * Check mangled name against mangled name, or unmangled name
+ * against unmangled name.
+ */
+
+ if ((mangled && mangled_equal(name,name2)) || fname_equal(name, dname)) {
/* we've found the file, change it's name and return */
if (docache)
DirCacheAdd(path,name,dname,SNUM(conn));
diff --git a/source/smbd/files.c b/source/smbd/files.c
index 27dfad7c483..3935a12442b 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static int real_max_open_files;
#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < real_max_open_files))
@@ -41,8 +39,22 @@ static files_struct *oplock_save_chain_fsp = NULL;
static int files_used;
/****************************************************************************
- find first available file slot
+ Return a unique number identifying this fsp over the life of this pid.
+****************************************************************************/
+
+static unsigned long get_gen_count(void)
+{
+ static unsigned long file_gen_counter;
+
+ if ((++file_gen_counter) == 0)
+ return ++file_gen_counter;
+ return file_gen_counter;
+}
+
+/****************************************************************************
+ Find first available file slot.
****************************************************************************/
+
files_struct *file_new(connection_struct *conn)
{
int i;
@@ -92,6 +104,8 @@ files_struct *file_new(connection_struct *conn)
ZERO_STRUCTP(fsp);
fsp->fd = -1;
fsp->conn = conn;
+ fsp->file_id = get_gen_count();
+ GetTimeOfDay(&fsp->open_time);
first_file = (i+1) % real_max_open_files;
@@ -111,10 +125,10 @@ files_struct *file_new(connection_struct *conn)
return fsp;
}
-
/****************************************************************************
-close all open files for a connection
+ Close all open files for a connection.
****************************************************************************/
+
void file_close_conn(connection_struct *conn)
{
files_struct *fsp, *next;
@@ -128,7 +142,7 @@ void file_close_conn(connection_struct *conn)
}
/****************************************************************************
-initialise file structures
+ Initialise file structures.
****************************************************************************/
#define MAX_OPEN_FUDGEFACTOR 10
@@ -164,10 +178,10 @@ open files, %d are available.\n", request_max_open_files, real_max_open_files));
set_pipe_handle_offset(real_max_open_files);
}
-
/****************************************************************************
-close files open by a specified vuid
+ Close files open by a specified vuid.
****************************************************************************/
+
void file_close_user(int vuid)
{
files_struct *fsp, *next;
@@ -180,13 +194,32 @@ void file_close_user(int vuid)
}
}
+/****************************************************************************
+ Find a fsp given a file descriptor.
+****************************************************************************/
+
+files_struct *file_find_fd(int fd)
+{
+ int count=0;
+ files_struct *fsp;
+
+ for (fsp=Files;fsp;fsp=fsp->next,count++) {
+ if (fsp->fd == fd) {
+ if (count > 10) {
+ DLIST_PROMOTE(Files, fsp);
+ }
+ return fsp;
+ }
+ }
+
+ return NULL;
+}
/****************************************************************************
- Find a fsp given a device, inode and timevalue
- If this is from a kernel oplock break request then tval may be NULL.
+ Find a fsp given a device, inode and file_id.
****************************************************************************/
-files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
+files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id)
{
int count=0;
files_struct *fsp;
@@ -195,8 +228,7 @@ files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval
if (fsp->fd != -1 &&
fsp->dev == dev &&
fsp->inode == inode &&
- (tval ? (fsp->open_time.tv_sec == tval->tv_sec) : True ) &&
- (tval ? (fsp->open_time.tv_usec == tval->tv_usec) : True )) {
+ fsp->file_id == file_id ) {
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
@@ -260,8 +292,9 @@ files_struct *file_find_di_next(files_struct *start_fsp)
}
/****************************************************************************
-find a fsp that is open for printing
+ Find a fsp that is open for printing.
****************************************************************************/
+
files_struct *file_find_print(void)
{
files_struct *fsp;
@@ -273,10 +306,10 @@ files_struct *file_find_print(void)
return NULL;
}
-
/****************************************************************************
-sync open files on a connection
+ Sync open files on a connection.
****************************************************************************/
+
void file_sync_all(connection_struct *conn)
{
files_struct *fsp, *next;
@@ -289,10 +322,10 @@ void file_sync_all(connection_struct *conn)
}
}
-
/****************************************************************************
-free up a fsp
+ Free up a fsp.
****************************************************************************/
+
void file_free(files_struct *fsp)
{
DLIST_REMOVE(Files, fsp);
@@ -311,19 +344,20 @@ void file_free(files_struct *fsp)
if (fsp == chain_fsp) chain_fsp = NULL;
- free(fsp);
+ SAFE_FREE(fsp);
}
-
/****************************************************************************
-get a fsp from a packet given the offset of a 16 bit fnum
+ Get a fsp from a packet given the offset of a 16 bit fnum.
****************************************************************************/
+
files_struct *file_fsp(char *buf, int where)
{
int fnum, count=0;
files_struct *fsp;
- if (chain_fsp) return chain_fsp;
+ if (chain_fsp)
+ return chain_fsp;
fnum = SVAL(buf, where);
@@ -340,7 +374,7 @@ files_struct *file_fsp(char *buf, int where)
}
/****************************************************************************
- Reset the chained fsp - done at the start of a packet reply
+ Reset the chained fsp - done at the start of a packet reply.
****************************************************************************/
void file_chain_reset(void)
@@ -360,6 +394,7 @@ void file_chain_save(void)
/****************************************************************************
Restore the chained fsp - done after an oplock break.
****************************************************************************/
+
void file_chain_restore(void)
{
chain_fsp = oplock_save_chain_fsp;
diff --git a/source/smbd/groupname.c b/source/smbd/groupname.c
index d44e9a7a39c..2c7440d75a7 100644
--- a/source/smbd/groupname.c
+++ b/source/smbd/groupname.c
@@ -22,7 +22,6 @@
#ifdef USING_GROUPNAME_MAP
#include "includes.h"
-extern int DEBUGLEVEL;
extern DOM_SID global_sam_sid;
@@ -53,11 +52,9 @@ static void delete_groupname_map_list(void)
groupname_map_entry *gmep;
while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
- if(gmep->windows_name)
- free(gmep->windows_name);
- if(gmep->unix_name)
- free(gmep->unix_name);
- free((char *)gmep);
+ SAFE_FREE(gmep->windows_name);
+ SAFE_FREE(gmep->unix_name);
+ SAFE_FREE(gmep);
}
}
@@ -188,11 +185,9 @@ Error was %s.\n", unixname, strerror(errno) ));
if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
fclose(fp);
- if(new_ep->windows_name != NULL)
- free(new_ep->windows_name);
- if(new_ep->unix_name != NULL)
- free(new_ep->unix_name);
- free((char *)new_ep);
+ SAFE_FREE(new_ep->windows_name);
+ SAFE_FREE(new_ep->unix_name);
+ SAFE_FREE(new_ep);
file_lines_free(lines);
return;
}
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 3ec6d1f1cff..e1c3e7fe4d3 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -28,7 +28,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern int max_send;
extern fstring local_machine;
@@ -108,7 +107,7 @@ void send_trans_reply(char *outbuf,
SCVAL(outbuf, smb_rcls, ERRDOS);
} else {
SIVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
- SIVAL(outbuf, smb_rcls, 0x80000000 | STATUS_BUFFER_OVERFLOW);
+ SIVAL(outbuf, smb_rcls, NT_STATUS_V(STATUS_BUFFER_OVERFLOW));
}
}
@@ -184,13 +183,13 @@ static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
}
if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
- free(rdata);
+ SAFE_FREE(rdata);
return False;
}
send_trans_reply(outbuf, NULL, 0, rdata, data_len, p->out_data.current_pdu_len > data_len);
- free(rdata);
+ SAFE_FREE(rdata);
return True;
}
@@ -394,7 +393,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if((data = (char *)malloc(tdscnt)) == NULL) {
DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
END_PROFILE(SMBtrans);
- return(ERROR(ERRDOS,ERRnomem));
+ return(ERROR_DOS(ERRDOS,ERRnomem));
}
memcpy(data,smb_base(inbuf)+dsoff,dscnt);
}
@@ -403,7 +402,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if((params = (char *)malloc(tpscnt)) == NULL) {
DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
END_PROFILE(SMBtrans);
- return(ERROR(ERRDOS,ERRnomem));
+ return(ERROR_DOS(ERRDOS,ERRnomem));
}
memcpy(params,smb_base(inbuf)+psoff,pscnt);
}
@@ -413,7 +412,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
END_PROFILE(SMBtrans);
- return(ERROR(ERRDOS,ERRnomem));
+ return(ERROR_DOS(ERRDOS,ERRnomem));
}
for (i=0;i<suwcnt;i++)
setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
@@ -443,14 +442,11 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
(smb_read_error == READ_ERROR) ? "error" : "timeout" ));
}
- if (params)
- free(params);
- if (data)
- free(data);
- if (setup)
- free(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ SAFE_FREE(setup);
END_PROFILE(SMBtrans);
- return(ERROR(ERRSRV,ERRerror));
+ return(ERROR_DOS(ERRSRV,ERRerror));
}
show_msg(inbuf);
@@ -510,12 +506,9 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
- if (data)
- free(data);
- if (params)
- free(params);
- if (setup)
- free(setup);
+ SAFE_FREE(data);
+ SAFE_FREE(params);
+ SAFE_FREE(setup);
if (close_on_completion)
close_cnum(conn,vuid);
@@ -527,7 +520,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if (outsize == 0) {
END_PROFILE(SMBtrans);
- return(ERROR(ERRSRV,ERRnosupport));
+ return(ERROR_DOS(ERRSRV,ERRnosupport));
}
END_PROFILE(SMBtrans);
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 3d8844d5be1..70d79a5f566 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -33,8 +33,6 @@
#endif
#define CHECK_TYPES 0
-extern int DEBUGLEVEL;
-
extern fstring local_machine;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -748,6 +746,8 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
PACKS(desc,"z","WinPrint"); /* pszPrProc */
PACKS(desc,"z",NULL); /* pszParms */
PACKS(desc,"z",NULL); /* pszComment - don't ask.... JRA */
+ /* "don't ask" that it's done this way to fix corrupted
+ Win9X/ME printer comments. */
if (!status) {
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
} else {
@@ -956,10 +956,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
- if (queue)
- free(queue);
- if (tmpdata)
- free (tmpdata);
+ SAFE_FREE(queue);
+ SAFE_FREE(tmpdata);
return(True);
}
@@ -1049,7 +1047,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
}
}
- if (subcntarr) free(subcntarr);
+ SAFE_FREE(subcntarr);
*rdata_len = desc.usedlen;
*rparam_len = 8;
@@ -1060,11 +1058,11 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
SSVAL(*rparam,6,queuecnt);
for (i = 0; i < queuecnt; i++) {
- if (queue && queue[i]) free(queue[i]);
+ if (queue) SAFE_FREE(queue[i]);
}
- if (queue) free(queue);
- if (status) free(status);
+ SAFE_FREE(queue);
+ SAFE_FREE(status);
return True;
}
@@ -1137,13 +1135,13 @@ static int get_server_info(uint32 servertype,
struct srv_info_struct *ts;
alloced += 10;
- ts = (struct srv_info_struct *)Realloc(*servers,sizeof(**servers)*alloced);
+ ts = (struct srv_info_struct *)
+ Realloc(*servers,sizeof(**servers)*alloced);
if (!ts) {
DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
return(0);
}
- else
- *servers = ts;
+ else *servers = ts;
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
}
s = &(*servers)[count];
@@ -1414,7 +1412,7 @@ static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param
SSVAL(*rparam,4,counted);
SSVAL(*rparam,6,counted+missed);
- if (servers) free(servers);
+ SAFE_FREE(servers);
DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
domain,uLevel,counted,counted+missed));
@@ -1527,7 +1525,7 @@ static int fill_share_info(connection_struct *conn, int snum, int uLevel,
if (uLevel > 0)
{
int type;
- CVAL(p,13) = 0;
+ SCVAL(p,13,0);
type = STYPE_DISKTREE;
if (lp_print_ok(snum)) type = STYPE_PRINTQ;
if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
@@ -1705,16 +1703,16 @@ static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,ch
t = LocalTime(&unixdate);
SIVAL(p,4,0); /* msecs ? */
- CVAL(p,8) = t->tm_hour;
- CVAL(p,9) = t->tm_min;
- CVAL(p,10) = t->tm_sec;
- CVAL(p,11) = 0; /* hundredths of seconds */
+ SCVAL(p,8,t->tm_hour);
+ SCVAL(p,9,t->tm_min);
+ SCVAL(p,10,t->tm_sec);
+ SCVAL(p,11,0); /* hundredths of seconds */
SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
- CVAL(p,16) = t->tm_mday;
- CVAL(p,17) = t->tm_mon + 1;
+ SCVAL(p,16,t->tm_mday);
+ SCVAL(p,17,t->tm_mon + 1);
SSVAL(p,18,1900+t->tm_year);
- CVAL(p,20) = t->tm_wday;
+ SCVAL(p,20,t->tm_wday);
}
@@ -1795,6 +1793,8 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
if(lp_unix_password_sync() && !chgpasswd(user,pass1,saved_pass2,False))
SSVAL(*rparam,0,NERR_badpass);
}
+
+ pdb_free_sam(sampass);
}
/*
@@ -1830,6 +1830,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
{
SSVAL(*rparam,0,NERR_Success);
}
+ pdb_free_sam(sampass);
}
memset((char *)pass1,'\0',sizeof(fstring));
@@ -1911,6 +1912,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
char *p = skip_string(str2,1);
int jobid, errcode;
extern struct current_user current_user;
+ WERROR werr = WERR_OK;
jobid = SVAL(p,0);
@@ -1931,19 +1933,22 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 81: /* delete */
- if (print_job_delete(&current_user, jobid, &errcode))
+ if (print_job_delete(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
- if (print_job_pause(&current_user, jobid, &errcode))
+ if (print_job_pause(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
- if (print_job_resume(&current_user, jobid, &errcode))
+ if (print_job_resume(&current_user, jobid, &werr))
errcode = NERR_Success;
break;
}
+ if (!W_ERROR_IS_OK(werr))
+ errcode = W_ERROR_V(werr);
+
out:
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
@@ -1965,6 +1970,7 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
char *QueueName = skip_string(str2,1);
int errcode = NERR_notsupported;
int snum;
+ WERROR werr = WERR_OK;
extern struct current_user current_user;
/* check it's a supported varient */
@@ -1984,16 +1990,17 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
switch (function) {
case 74: /* Pause queue */
- if (print_queue_pause(&current_user, snum, &errcode)) errcode = NERR_Success;
+ if (print_queue_pause(&current_user, snum, &werr)) errcode = NERR_Success;
break;
case 75: /* Resume queue */
- if (print_queue_resume(&current_user, snum, &errcode)) errcode = NERR_Success;
+ if (print_queue_resume(&current_user, snum, &werr)) errcode = NERR_Success;
break;
case 103: /* Purge */
- if (print_queue_purge(&current_user, snum, &errcode)) errcode = NERR_Success;
+ if (print_queue_purge(&current_user, snum, &werr)) errcode = NERR_Success;
break;
}
+ if (!W_ERROR_IS_OK(werr)) errcode = W_ERROR_V(werr);
out:
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
@@ -2162,7 +2169,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
pstrcpy(comment,servers[i].comment);
}
}
- if (servers) free(servers);
+ SAFE_FREE(servers);
SCVAL(p,0,lp_major_announce_version());
SCVAL(p,1,lp_minor_announce_version());
@@ -2827,8 +2834,8 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
- if (queue) free(queue);
- if (tmpdata) free(tmpdata);
+ SAFE_FREE(queue);
+ SAFE_FREE(tmpdata);
DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
return(True);
@@ -2897,7 +2904,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
SSVAL(*rparam,4,succnt);
SSVAL(*rparam,6,count);
- if (queue) free(queue);
+ SAFE_FREE(queue);
DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
return(True);
@@ -3016,7 +3023,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
SSVAL(*rparam,4,desc.neededlen);
DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
- if (tmpdata) free (tmpdata);
+ SAFE_FREE(tmpdata);
return(True);
}
@@ -3267,35 +3274,44 @@ struct
int,int,char **,char **,int *,int *);
int flags;
} api_commands[] = {
- {"RNetShareEnum", 0, api_RNetShareEnum,0},
- {"RNetShareGetInfo", 1, api_RNetShareGetInfo,0},
- {"RNetServerGetInfo", 13, api_RNetServerGetInfo,0},
- {"RNetGroupGetUsers", 52, api_RNetGroupGetUsers,0},
- {"RNetUserGetInfo", 56, api_RNetUserGetInfo,0},
- {"NetUserGetGroups", 59, api_NetUserGetGroups,0},
- {"NetWkstaGetInfo", 63, api_NetWkstaGetInfo,0},
- {"DosPrintQEnum", 69, api_DosPrintQEnum,0},
- {"DosPrintQGetInfo", 70, api_DosPrintQGetInfo,0},
- {"WPrintQueuePause", 74, api_WPrintQueueCtrl,0},
- {"WPrintQueueResume", 75, api_WPrintQueueCtrl,0},
- {"WPrintJobEnumerate",76, api_WPrintJobEnumerate,0},
- {"WPrintJobGetInfo", 77, api_WPrintJobGetInfo,0},
- {"RDosPrintJobDel", 81, api_RDosPrintJobDel,0},
- {"RDosPrintJobPause", 82, api_RDosPrintJobDel,0},
- {"RDosPrintJobResume",83, api_RDosPrintJobDel,0},
- {"WPrintDestEnum", 84, api_WPrintDestEnum,0},
- {"WPrintDestGetInfo", 85, api_WPrintDestGetInfo,0},
- {"NetRemoteTOD", 91, api_NetRemoteTOD,0},
- {"WPrintQueuePurge", 103, api_WPrintQueueCtrl,0},
- {"NetServerEnum", 104, api_RNetServerEnum,0},
- {"WAccessGetUserPerms",105, api_WAccessGetUserPerms,0},
- {"SetUserPassword", 115, api_SetUserPassword,0},
- {"WWkstaUserLogon", 132, api_WWkstaUserLogon,0},
- {"PrintJobInfo", 147, api_PrintJobInfo,0},
- {"WPrintDriverEnum", 205, api_WPrintDriverEnum,0},
- {"WPrintQProcEnum", 206, api_WPrintQProcEnum,0},
- {"WPrintPortEnum", 207, api_WPrintPortEnum,0},
- {"SamOEMChangePassword", 214, api_SamOEMChangePassword,0},
+ {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum,0},
+ {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd,0},
+#endif
+ {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo,0},
+#if 0 /* Not yet implemented. */
+ {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum,0},
+#endif
+ {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers,0},
+#if 0 /* Not yet implemented. */
+ {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum,0},
+#endif
+ {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo,0},
+ {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups,0},
+ {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo,0},
+ {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum,0},
+ {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo,0},
+ {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl,0},
+ {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl,0},
+ {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate,0},
+ {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo,0},
+ {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel,0},
+ {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel,0},
+ {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel,0},
+ {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum,0},
+ {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo,0},
+ {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD,0},
+ {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl,0},
+ {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum,0},
+ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms,0},
+ {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword,0},
+ {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon,0},
+ {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo,0},
+ {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum,0},
+ {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum,0},
+ {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum,0},
+ {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword,0},
{NULL, -1, api_Unsupported,0}};
@@ -3364,10 +3380,8 @@ int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *
send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
- if (rdata )
- free(rdata);
- if (rparam)
- free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return -1;
}
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index d6d470c2dab..3d214d46589 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -52,7 +52,6 @@
* External Variables...
*/
-extern int DEBUGLEVEL; /* Global debug level. */
extern int case_default; /* Are conforming 8.3 names all upper or lower? */
extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
@@ -466,7 +465,7 @@ static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
static void cache_free_entry( ubi_trNodePtr WarrenZevon )
{
ZERO_STRUCTP(WarrenZevon);
- free( WarrenZevon );
+ SAFE_FREE( WarrenZevon );
} /* cache_free_entry */
/* ************************************************************************** **
@@ -633,7 +632,7 @@ BOOL check_mangled_cache( char *s )
{
/* Replace the saved_ext as it was truncated. */
(void)pstrcat( s, saved_ext );
- free(saved_ext);
+ SAFE_FREE(saved_ext);
}
return( False );
}
@@ -649,7 +648,7 @@ BOOL check_mangled_cache( char *s )
{
/* Replace the saved_ext as it was truncated. */
(void)pstrcat( s, saved_ext );
- free(saved_ext);
+ SAFE_FREE(saved_ext);
}
DEBUG( 3, ("as %s\n", s) );
@@ -1017,7 +1016,7 @@ BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
if(tmp != NULL) {
cache_mangled_name(OutName, tmp);
- free(tmp);
+ SAFE_FREE(tmp);
}
}
diff --git a/source/smbd/message.c b/source/smbd/message.c
index b3da3f2b611..0097b15b8b4 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -27,8 +27,6 @@
#include "includes.h"
/* look in server.c for some explanation of these variables */
-extern int DEBUGLEVEL;
-
static char msgbuf[1600];
static int msgpos=0;
@@ -113,7 +111,7 @@ int reply_sends(connection_struct *conn,
if (! (*lp_msg_command())) {
END_PROFILE(SMBsends);
- return(ERROR(ERRSRV,ERRmsgoff));
+ return(ERROR_DOS(ERRSRV,ERRmsgoff));
}
outsize = set_message(outbuf,0,0,True);
@@ -154,7 +152,7 @@ int reply_sendstrt(connection_struct *conn,
if (! (*lp_msg_command())) {
END_PROFILE(SMBsendstrt);
- return(ERROR(ERRSRV,ERRmsgoff));
+ return(ERROR_DOS(ERRSRV,ERRmsgoff));
}
outsize = set_message(outbuf,1,0,True);
@@ -188,7 +186,7 @@ int reply_sendtxt(connection_struct *conn,
if (! (*lp_msg_command())) {
END_PROFILE(SMBsendtxt);
- return(ERROR(ERRSRV,ERRmsgoff));
+ return(ERROR_DOS(ERRSRV,ERRmsgoff));
}
outsize = set_message(outbuf,0,0,True);
@@ -219,7 +217,7 @@ int reply_sendend(connection_struct *conn,
if (! (*lp_msg_command())) {
END_PROFILE(SMBsendend);
- return(ERROR(ERRSRV,ERRmsgoff));
+ return(ERROR_DOS(ERRSRV,ERRmsgoff));
}
outsize = set_message(outbuf,0,0,True);
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 25419caf625..1f5de570c66 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -21,7 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern int Protocol;
extern int max_recv;
extern fstring global_myworkgroup;
@@ -158,7 +157,7 @@ reply for the nt protocol
static int reply_nt1(char *outbuf)
{
/* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_LEVEL_II_OPLOCKS|
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_LEVEL_II_OPLOCKS|CAP_STATUS32| (lp_unix_extensions() ? CAP_UNIX : 0) |
(lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
((lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) ?
CAP_LARGE_READX | CAP_LARGE_WRITEX | CAP_W2K_SMBS : 0) |
@@ -217,7 +216,7 @@ static int reply_nt1(char *outbuf)
set_message(outbuf,17,data_len,True);
pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
- CVAL(outbuf,smb_vwv1) = secword;
+ SCVAL(outbuf,smb_vwv1,secword);
SSVALS(outbuf,smb_vwv16+1,crypt_len);
if (doencrypt)
memcpy(smb_buf(outbuf), cryptkey, 8);
diff --git a/source/smbd/noquotas.c b/source/smbd/noquotas.c
index 5c55bb47c8e..a6951d97fc5 100644
--- a/source/smbd/noquotas.c
+++ b/source/smbd/noquotas.c
@@ -25,7 +25,7 @@
* Needed for auto generation of proto.h.
*/
-BOOL disk_quotas(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
(*bsize) = 512; /* This value should be ignored */
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index d0966289fe7..52df3558aa7 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -22,16 +22,13 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-extern uint32 global_client_caps;
-
static struct cnotify_fns *cnotify;
/****************************************************************************
This is the structure to queue to implement NT change
notify. It consists of smb_size bytes stored from the
transact command (to keep the mid, tid etc around).
- Plus the fid to examine and notify private data
+ Plus the fid to examine and notify private data.
*****************************************************************************/
struct change_notify {
@@ -48,26 +45,14 @@ static struct change_notify *change_notify_list;
/****************************************************************************
Setup the common parts of the return packet and send it.
*****************************************************************************/
-static void change_notify_reply_packet(char *inbuf, uint32 error_code)
+static void change_notify_reply_packet(char *inbuf, NTSTATUS error_code)
{
char outbuf[smb_size+38];
memset(outbuf, '\0', sizeof(outbuf));
construct_reply_common(inbuf, outbuf);
- /*
- * If we're returning a 'too much in the directory changed' we need to
- * set this is an NT error status flags. If we don't then the (probably
- * untested) code in the NT redirector has a bug in that it doesn't re-issue
- * the change notify.... Ah - I *love* it when I get so deeply into this I
- * can even determine how MS failed to test stuff and why.... :-). JRA.
- */
-
- if (global_client_caps & CAP_STATUS32) {
- ERROR(0,error_code);
- } else {
- ERROR(ERRDOS,STATUS_NOTIFY_ENUM_DIR);
- }
+ ERROR_NT(error_code);
/*
* Seems NT needs a transact command with an error code
@@ -76,26 +61,26 @@ static void change_notify_reply_packet(char *inbuf, uint32 error_code)
set_message(outbuf,18,0,False);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("change_notify_reply_packet: send_smb failed.\n");
+ exit_server("change_notify_reply_packet: send_smb failed.");
}
/****************************************************************************
-remove an entry from the list and free it, also closing any
-directory handle if necessary
-Notice the horrible stuff we have to do because this is a singly linked list.
+ Remove an entry from the list and free it, also closing any
+ directory handle if necessary.
*****************************************************************************/
+
static void change_notify_remove(struct change_notify *cnbp)
{
cnotify->remove_notify(cnbp->change_data);
DLIST_REMOVE(change_notify_list, cnbp);
ZERO_STRUCTP(cnbp);
- free(cnbp);
+ SAFE_FREE(cnbp);
}
-
/****************************************************************************
Delete entries by fnum from the change notify pending queue.
*****************************************************************************/
+
void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
{
struct change_notify *cnbp, *next;
@@ -111,6 +96,7 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
/****************************************************************************
Delete entries by mid from the change notify pending queue. Always send reply.
*****************************************************************************/
+
void remove_pending_change_notify_requests_by_mid(int mid)
{
struct change_notify *cnbp, *next;
@@ -128,6 +114,7 @@ void remove_pending_change_notify_requests_by_mid(int mid)
Delete entries by filename and cnum from the change notify pending queue.
Always send reply.
*****************************************************************************/
+
void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
{
struct change_notify *cnbp, *next;
@@ -148,6 +135,7 @@ void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
/****************************************************************************
Return true if there are pending change notifies.
****************************************************************************/
+
int change_notify_timeout(void)
{
return cnotify->select_time;
@@ -158,6 +146,7 @@ int change_notify_timeout(void)
Returns True if there are still outstanding change notify requests on the
queue.
*****************************************************************************/
+
BOOL process_pending_change_notify_queue(time_t t)
{
struct change_notify *cnbp, *next;
@@ -167,8 +156,9 @@ BOOL process_pending_change_notify_queue(time_t t)
next=cnbp->next;
vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(cnbp->request_buf,smb_uid);
-
+
if (cnotify->check_notify(cnbp->conn, vuid, cnbp->fsp->fsp_name, cnbp->flags, cnbp->change_data, t)) {
+ DEBUG(10,("process_pending_change_notify_queue: dir %s changed !\n", cnbp->fsp->fsp_name ));
change_notify_reply_packet(cnbp->request_buf,STATUS_NOTIFY_ENUM_DIR);
change_notify_remove(cnbp);
}
@@ -178,11 +168,12 @@ BOOL process_pending_change_notify_queue(time_t t)
}
/****************************************************************************
- * Now queue an entry on the notify change list.
- * We only need to save smb_size bytes from this incoming packet
- * as we will always by returning a 'read the directory yourself'
- * error.
+ Now queue an entry on the notify change list.
+ We only need to save smb_size bytes from this incoming packet
+ as we will always by returning a 'read the directory yourself'
+ error.
****************************************************************************/
+
BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn, uint32 flags)
{
struct change_notify *cnbp;
@@ -201,7 +192,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
cnbp->change_data = cnotify->register_notify(conn, fsp->fsp_name, flags);
if (!cnbp->change_data) {
- free(cnbp);
+ SAFE_FREE(cnbp);
return False;
}
@@ -210,10 +201,10 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
return True;
}
-
/****************************************************************************
-initialise the change notify subsystem
+ Initialise the change notify subsystem.
****************************************************************************/
+
BOOL init_change_notify(void)
{
#if HAVE_KERNEL_CHANGE_NOTIFY
diff --git a/source/smbd/notify_hash.c b/source/smbd/notify_hash.c
index a0a61569a8b..90eb88ac814 100644
--- a/source/smbd/notify_hash.c
+++ b/source/smbd/notify_hash.c
@@ -22,21 +22,20 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
-
struct change_data {
time_t last_check_time; /* time we last checked this entry */
time_t modify_time; /* Info from the directory we're monitoring. */
time_t status_time; /* Info from the directory we're monitoring. */
time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
unsigned int num_entries; /* Zero or the number of files in the directory. */
+ unsigned int mode_sum;
+ unsigned char name_hash[16];
};
-
/****************************************************************************
Create the hash we will use to determine if the contents changed.
*****************************************************************************/
+
static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
struct change_data *data, struct change_data *old_data)
{
@@ -50,7 +49,8 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
ZERO_STRUCTP(data);
- if(vfs_stat(conn,path, &st) == -1) return False;
+ if(vfs_stat(conn,path, &st) == -1)
+ return False;
data->modify_time = st.st_mtime;
data->status_time = st.st_ctime;
@@ -76,10 +76,9 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
* larger than the max time_t value).
*/
- if (!(flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE))) return True;
-
dp = OpenDir(conn, path, True);
- if (dp == NULL) return False;
+ if (dp == NULL)
+ return False;
data->num_entries = 0;
@@ -91,7 +90,8 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
p = &full_name[fullname_len];
while ((fname = ReadDirName(dp))) {
- if(strequal(fname, ".") || strequal(fname, "..")) continue;
+ if(strequal(fname, ".") || strequal(fname, ".."))
+ continue;
data->num_entries++;
safe_strcpy(p, fname, remaining_len);
@@ -102,7 +102,31 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
* Do the stat - but ignore errors.
*/
vfs_stat(conn,full_name, &st);
+
+ /*
+ * Always sum the times.
+ */
+
data->total_time += (st.st_mtime + st.st_ctime);
+
+ /*
+ * If requested hash the names.
+ */
+
+ if (flags & (FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_FILE)) {
+ int i;
+ unsigned char tmp_hash[16];
+ mdfour(tmp_hash, (unsigned char *)fname, strlen(fname));
+ for (i=0;i<16;i++)
+ data->name_hash[i] ^= tmp_hash[i];
+ }
+
+ /*
+ * If requested sum the mode_t's.
+ */
+
+ if (flags & (FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SECURITY))
+ data->mode_sum = st.st_mode;
}
CloseDir(dp);
@@ -110,15 +134,16 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
return True;
}
-
/****************************************************************************
-register a change notify request
+ Register a change notify request.
*****************************************************************************/
+
static void *hash_register_notify(connection_struct *conn, char *path, uint32 flags)
{
struct change_data data;
- if (!notify_hash(conn, path, flags, &data, NULL)) return NULL;
+ if (!notify_hash(conn, path, flags, &data, NULL))
+ return NULL;
data.last_check_time = time(NULL);
@@ -129,16 +154,19 @@ static void *hash_register_notify(connection_struct *conn, char *path, uint32 fl
Check if a change notify should be issued.
A time of zero means instantaneous check - don't modify the last check time.
*****************************************************************************/
+
static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *datap, time_t t)
{
struct change_data *data = (struct change_data *)datap;
struct change_data data2;
- if (t && t < data->last_check_time + lp_change_notify_timeout()) return False;
+ if (t && t < data->last_check_time + lp_change_notify_timeout())
+ return False;
- if (!become_user(conn,vuid)) return True;
- if (!become_service(conn,True)) {
- unbecome_user();
+ if (!change_to_user(conn,vuid))
+ return True;
+ if (!set_current_service(conn,True)) {
+ change_to_root_user();
return True;
}
@@ -146,31 +174,34 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,
data2.modify_time != data->modify_time ||
data2.status_time != data->status_time ||
data2.total_time != data->total_time ||
- data2.num_entries != data->num_entries) {
- unbecome_user();
+ data2.num_entries != data->num_entries ||
+ data2.mode_sum != data->mode_sum ||
+ memcmp(data2.name_hash, data->name_hash, sizeof(data2.name_hash))) {
+ change_to_root_user();
return True;
}
if (t)
data->last_check_time = t;
- unbecome_user();
+ change_to_root_user();
return False;
}
/****************************************************************************
-remove a change notify data structure
+ Remove a change notify data structure.
*****************************************************************************/
+
static void hash_remove_notify(void *datap)
{
- free(datap);
+ SAFE_FREE(datap);
}
-
/****************************************************************************
-setup hash based change notify
+ Setup hash based change notify.
****************************************************************************/
+
struct cnotify_fns *hash_notify_init(void)
{
static struct cnotify_fns cnotify;
@@ -183,7 +214,6 @@ struct cnotify_fns *hash_notify_init(void)
return &cnotify;
}
-
/*
change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c
index f1e40793c85..96164a3199b 100644
--- a/source/smbd/notify_kernel.c
+++ b/source/smbd/notify_kernel.c
@@ -23,7 +23,6 @@
#if HAVE_KERNEL_CHANGE_NOTIFY
-extern int DEBUGLEVEL;
static VOLATILE sig_atomic_t fd_pending;
static VOLATILE sig_atomic_t signals_received;
static VOLATILE sig_atomic_t signals_processed;
@@ -111,7 +110,7 @@ static void kernel_remove_notify(void *datap)
}
close(fd);
}
- free(data);
+ SAFE_FREE(data);
DEBUG(3,("removed kernel change notify fd=%d\n", fd));
}
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index e913daef18a..110d7ed7d26 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -21,14 +21,12 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern int Protocol;
extern int smb_read_error;
extern int global_oplock_break;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
-extern uint32 global_client_caps;
static char *known_nt_pipes[] = {
"\\LANMAN",
@@ -64,8 +62,8 @@ struct generic_mapping file_generic_mapping = {
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, int eclass, uint32 ecode,
- char *params, int paramsize, char *pdata, int datasize)
+static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_error, char *params,
+ int paramsize, char *pdata, int datasize)
{
extern int max_send;
int data_to_send = datasize;
@@ -84,8 +82,8 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
set_message(outbuf,18,0,True);
- if(nt_error != 0) {
- ERROR_BOTH(nt_error,eclass,ecode);
+ if(NT_STATUS_V(nt_error)) {
+ ERROR_NT(nt_error);
}
/*
@@ -95,7 +93,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
if(params_to_send == 0 && data_to_send == 0) {
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.\n");
+ exit_server("send_nt_replies: send_smb failed.");
return 0;
}
@@ -225,7 +223,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
/* Send the packet */
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_nt_replies: send_smb failed.\n");
+ exit_server("send_nt_replies: send_smb failed.");
pp += params_sent_thistime;
pd += data_sent_thistime;
@@ -397,7 +395,7 @@ static int map_create_disposition( uint32 create_disposition)
return -1;
}
- DEBUG(10,("map_create_disposition: Mapped create_disposition %lx to %x\n",
+ DEBUG(10,("map_create_disposition: Mapped create_disposition 0x%lx to 0x%x\n",
(unsigned long)create_disposition, ret ));
return ret;
@@ -407,7 +405,7 @@ static int map_create_disposition( uint32 create_disposition)
Utility function to map share modes.
****************************************************************************/
-static int map_share_mode( BOOL *pstat_open_only, char *fname,
+static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_options,
uint32 desired_access, uint32 share_access, uint32 file_attributes)
{
int smb_open_mode = -1;
@@ -471,7 +469,7 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
smb_open_mode = DOS_OPEN_RDONLY;
} else {
- DEBUG(0,("map_share_mode: Incorrect value %lx for desired_access to file %s\n",
+ DEBUG(0,("map_share_mode: Incorrect value 0x%lx for desired_access to file %s\n",
(unsigned long)desired_access, fname));
return -1;
}
@@ -485,7 +483,7 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
if(share_access & FILE_SHARE_DELETE) {
smb_open_mode |= ALLOW_SHARE_DELETE;
- DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = %x\n", smb_open_mode));
+ DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
}
/*
@@ -497,7 +495,14 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
if(desired_access & DELETE_ACCESS) {
smb_open_mode |= DELETE_ACCESS_REQUESTED;
- DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = %x\n", smb_open_mode));
+ DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
+ }
+
+ if (create_options & FILE_DELETE_ON_CLOSE) {
+ /* Implicit delete access requested... */
+ smb_open_mode |= DELETE_ACCESS_REQUESTED;
+ smb_open_mode |= DELETE_ON_CLOSE_FLAG;
+ DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
}
/* Add in the requested share mode. */
@@ -523,8 +528,8 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
if(file_attributes & FILE_FLAG_WRITE_THROUGH)
smb_open_mode |= FILE_SYNC_OPENMODE;
- DEBUG(10,("map_share_mode: Mapped desired access %lx, share access %lx, file attributes %lx \
-to open_mode %x\n", (unsigned long)desired_access, (unsigned long)share_access,
+ DEBUG(10,("map_share_mode: Mapped desired access 0x%lx, share access 0x%lx, file attributes 0x%lx \
+to open_mode 0x%x\n", (unsigned long)desired_access, (unsigned long)share_access,
(unsigned long)file_attributes, smb_open_mode ));
return smb_open_mode;
@@ -546,14 +551,14 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
/* See if it is one we want to handle. */
if (lp_disable_spoolss() && strequal(fname, "\\spoolss"))
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
for( i = 0; known_nt_pipes[i]; i++ )
if( strequal(fname,known_nt_pipes[i]))
break;
if ( known_nt_pipes[i] == NULL )
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
/* Strip \\ off the name. */
fname++;
@@ -562,7 +567,7 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
p = open_rpc_pipe_p(fname, conn, vuid);
if (!p)
- return(ERROR(ERRSRV,ERRnofids));
+ return(ERROR_DOS(ERRSRV,ERRnofids));
*ppnum = p->pnum;
@@ -657,7 +662,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
} else {
END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRbadaccess));
+ return(ERROR_DOS(ERRDOS,ERRbadaccess));
}
}
@@ -669,87 +674,87 @@ int reply_ntcreate_and_X(connection_struct *conn,
if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRbadaccess));
+ return(ERROR_DOS(ERRDOS,ERRbadaccess));
}
/*
* Get the file name.
*/
- if(root_dir_fid != 0) {
- /*
- * This filename is relative to a directory fid.
- */
- files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
- size_t dir_name_len;
+ if(root_dir_fid != 0) {
+ /*
+ * This filename is relative to a directory fid.
+ */
+ files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
+ size_t dir_name_len;
- if(!dir_fsp) {
- END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRbadfid));
- }
+ if(!dir_fsp) {
+ END_PROFILE(SMBntcreateX);
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
+ }
- if(!dir_fsp->is_directory) {
- /*
- * Check to see if this is a mac fork of some kind.
- */
+ if(!dir_fsp->is_directory) {
+ /*
+ * Check to see if this is a mac fork of some kind.
+ */
- get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
- smb_buflen(inbuf),fname_len);
+ get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
- if( strchr(fname, ':')) {
- END_PROFILE(SMBntcreateX);
- return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
- }
- END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRbadfid));
- }
+ if( strchr(fname, ':')) {
+ END_PROFILE(SMBntcreateX);
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ }
+ END_PROFILE(SMBntcreateX);
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
+ }
- /*
- * Copy in the base directory name.
- */
+ /*
+ * Copy in the base directory name.
+ */
- pstrcpy( fname, dir_fsp->fsp_name );
- dir_name_len = strlen(fname);
+ pstrcpy( fname, dir_fsp->fsp_name );
+ dir_name_len = strlen(fname);
- /*
- * Ensure it ends in a '\'.
- */
+ /*
+ * Ensure it ends in a '\'.
+ */
- if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
- pstrcat(fname, "\\");
- dir_name_len++;
- }
+ if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
+ pstrcat(fname, "\\");
+ dir_name_len++;
+ }
- /*
- * This next calculation can refuse a correct filename if we're dealing
- * with the Win2k unicode bug, but that would be rare. JRA.
- */
+ /*
+ * This next calculation can refuse a correct filename if we're dealing
+ * with the Win2k unicode bug, but that would be rare. JRA.
+ */
- if(fname_len + dir_name_len >= sizeof(pstring)) {
- END_PROFILE(SMBntcreateX);
- return(ERROR(ERRSRV,ERRfilespecs));
- }
+ if(fname_len + dir_name_len >= sizeof(pstring)) {
+ END_PROFILE(SMBntcreateX);
+ return(ERROR_DOS(ERRSRV,ERRfilespecs));
+ }
- get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
- smb_buflen(inbuf),fname_len);
+ get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
- } else {
+ } else {
- get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
- smb_buflen(inbuf),fname_len);
- }
+ get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
+ smb_buflen(inbuf),fname_len);
+ }
/*
* Now contruct the smb_open_mode value from the filename,
- * desired access and the share access.
+ * desired access and the share access.
*/
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access,
+ if((smb_open_mode = map_share_mode(&stat_open_only, fname, create_options, desired_access,
share_access,
file_attributes)) == -1) {
END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -776,15 +781,12 @@ int reply_ntcreate_and_X(connection_struct *conn,
if(create_options & FILE_DIRECTORY_FILE) {
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
restore_case_semantics(file_attributes);
if(!fsp) {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBntcreateX);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -837,19 +839,18 @@ int reply_ntcreate_and_X(connection_struct *conn,
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(file_attributes);
+ SSVAL(outbuf, smb_flg2,
+ SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
- return(ERROR_BOTH(NT_STATUS_FILE_IS_A_DIRECTORY,ERRDOS,ERRbadaccess));
+ return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
if(!fsp) {
restore_case_semantics(file_attributes);
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBntcreateX);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -875,12 +876,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
} else {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBntcreateX);
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -897,7 +894,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
if (!fsp->is_directory && (fmode & aDIR)) {
close_file(fsp,False);
END_PROFILE(SMBntcreateX);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
/*
@@ -912,7 +909,12 @@ int reply_ntcreate_and_X(connection_struct *conn,
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
smb_action |= EXTENDED_OPLOCK_GRANTED;
+#if 1 /* JRATEST */
+ /* W2K sends back 42 words here ! */
+ set_message(outbuf,42,0,True);
+#else
set_message(outbuf,34,0,True);
+#endif
p = outbuf + smb_vwv2;
@@ -921,10 +923,10 @@ int reply_ntcreate_and_X(connection_struct *conn,
* exclusive & batch here.
*/
- if (smb_action & EXTENDED_OPLOCK_GRANTED)
- SCVAL(p,0, BATCH_OPLOCK_RETURN);
+ if (smb_action & 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);
+ SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
else
SCVAL(p,0,NO_OPLOCK_RETURN);
@@ -990,7 +992,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(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
@@ -1004,7 +1006,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
/* Realloc the size of parameters and data we will return */
params = Realloc(*ppparams, 69);
if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
*ppparams = params;
@@ -1030,7 +1032,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 69, *ppdata, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
return -1;
}
@@ -1164,7 +1166,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(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
/*
@@ -1173,7 +1175,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(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
flags = IVAL(params,0);
@@ -1193,7 +1195,7 @@ static int call_nt_transact_create(connection_struct *conn,
*/
if((smb_ofun = map_create_disposition( create_disposition )) == -1)
- return(ERROR(ERRDOS,ERRbadmem));
+ return ERROR_DOS(ERRDOS,ERRbadmem);
/*
* Get the file name.
@@ -1208,7 +1210,7 @@ static int call_nt_transact_create(connection_struct *conn,
size_t dir_name_len;
if(!dir_fsp)
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
if(!dir_fsp->is_directory) {
/*
@@ -1222,7 +1224,7 @@ static int call_nt_transact_create(connection_struct *conn,
return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
}
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
}
/*
@@ -1247,7 +1249,7 @@ static int call_nt_transact_create(connection_struct *conn,
*/
if(fname_len + dir_name_len >= sizeof(pstring))
- return(ERROR(ERRSRV,ERRfilespecs));
+ return(ERROR_DOS(ERRSRV,ERRfilespecs));
get_filename_transact(&fname[dir_name_len], params, 53,
total_parameter_count - 53 - fname_len, fname_len);
@@ -1262,9 +1264,9 @@ static int call_nt_transact_create(connection_struct *conn,
* and the share access.
*/
- if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
+ if((smb_open_mode = map_share_mode( &stat_open_only, fname, create_options, desired_access,
share_access, file_attributes)) == -1)
- return(ERROR(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
@@ -1295,14 +1297,11 @@ static int call_nt_transact_create(connection_struct *conn,
* CreateDirectory() call.
*/
- fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
if(!fsp) {
restore_case_semantics(file_attributes);
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1325,18 +1324,17 @@ static int call_nt_transact_create(connection_struct *conn,
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(file_attributes);
- return(ERROR_BOTH(NT_STATUS_FILE_IS_A_DIRECTORY,ERRDOS, ERRbadaccess));
+ SSVAL(outbuf, smb_flg2,
+ SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
+ return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
+ fsp = open_directory(conn, fname, &sbuf, smb_open_mode, smb_ofun, unixmode, &smb_action);
if(!fsp) {
restore_case_semantics(file_attributes);
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
#ifdef EROFS
@@ -1360,12 +1358,8 @@ static int call_nt_transact_create(connection_struct *conn,
}
} else {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
restore_case_semantics(file_attributes);
+ set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1379,7 +1373,7 @@ static int call_nt_transact_create(connection_struct *conn,
if (fmode & aDIR) {
close_file(fsp,False);
restore_case_semantics(file_attributes);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
/*
@@ -1402,7 +1396,7 @@ static int call_nt_transact_create(connection_struct *conn,
if (!set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION, &error_class, &error_code)) {
close_file(fsp,False);
restore_case_semantics(file_attributes);
- return(ERROR(error_class, error_code));
+ return ERROR_DOS(error_class, error_code);
}
restore_case_semantics(file_attributes);
@@ -1410,7 +1404,7 @@ static int call_nt_transact_create(connection_struct *conn,
/* Realloc the size of parameters and data we will return */
params = Realloc(*ppparams, 69);
if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
*ppparams = params;
@@ -1457,7 +1451,7 @@ static int call_nt_transact_create(connection_struct *conn,
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 69, *ppdata, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 69, *ppdata, 0);
return -1;
}
@@ -1515,10 +1509,10 @@ static int call_nt_transact_notify_change(connection_struct *conn,
DEBUG(3,("call_nt_transact_notify_change\n"));
if(!fsp)
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
if((!fsp->is_directory) || (conn != fsp->conn))
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
if (!change_notify_set(inbuf, fsp, conn, flags)) {
return(UNIXERROR(ERRDOS,ERRbadfid));
@@ -1539,30 +1533,30 @@ static int call_nt_transact_rename(connection_struct *conn,
int bufsize,
char **ppsetup, char **ppparams, char **ppdata)
{
- char *params = *ppparams;
- pstring new_name;
- files_struct *fsp = file_fsp(params, 0);
- BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
- uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
- ((uint32)sizeof(new_name)-1));
- int outsize = 0;
-
- CHECK_FSP(fsp, conn);
- StrnCpy(new_name,params+4,fname_len);
- new_name[fname_len] = '\0';
-
- outsize = rename_internals(conn, inbuf, outbuf, fsp->fsp_name,
+ char *params = *ppparams;
+ pstring new_name;
+ files_struct *fsp = file_fsp(params, 0);
+ BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
+ NTSTATUS status;
+ uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
+ ((uint32)sizeof(new_name)-1));
+
+ CHECK_FSP(fsp, conn);
+ StrnCpy(new_name,params+4,fname_len);
+ new_name[fname_len] = '\0';
+
+ status = rename_internals(conn, fsp->fsp_name,
new_name, replace_if_exists);
- if(outsize == 0) {
- /*
- * Rename was successful.
- */
- send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, NULL, 0, NULL, 0);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
- DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
- fsp->fsp_name, new_name));
+ /*
+ * Rename was successful.
+ */
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
- outsize = -1;
+ DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
+ fsp->fsp_name, new_name));
/*
* Win2k needs a changenotify request response before it will
@@ -1570,9 +1564,8 @@ static int call_nt_transact_rename(connection_struct *conn,
*/
process_pending_change_notify_queue((time_t)0);
- }
- return(outsize);
+ return -1;
}
/******************************************************************************
@@ -1593,7 +1586,7 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
return sd_size;
}
-/**************************************************************************n
+/****************************************************************************
Reply to query a security descriptor - currently this is not implemented (it
is planned to be though). Right now it just returns the same thing NT would
when queried on a FAT filesystem. JRA.
@@ -1615,19 +1608,19 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
files_struct *fsp = file_fsp(params,0);
if(!fsp)
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
params = Realloc(*ppparams, 4);
if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
*ppparams = params;
if ((mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
}
/*
@@ -1650,7 +1643,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
if(max_data_count < sd_size) {
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL, ERRDOS, 122,
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
params, 4, *ppdata, 0);
talloc_destroy(mem_ctx);
return -1;
@@ -1663,7 +1656,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
data = Realloc(*ppdata, sd_size);
if(data == NULL) {
talloc_destroy(mem_ctx);
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
}
*ppdata = data;
@@ -1703,7 +1696,7 @@ security descriptor.\n"));
talloc_destroy(mem_ctx);
- send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 4, data, (int)sd_size);
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data, (int)sd_size);
return -1;
}
@@ -1726,10 +1719,10 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
uint32 error_code;
if(total_parameter_count < 8)
- return(ERROR(ERRDOS,ERRbadfunc));
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
if((fsp = file_fsp(params,0)) == NULL)
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
if(!lp_nt_acl_support(SNUM(conn)))
goto done;
@@ -1740,11 +1733,11 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
(unsigned int)security_info_sent ));
if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code))
- return (ERROR(error_class, error_code));
+ return ERROR_DOS(error_class, error_code);
done:
- send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, NULL, 0, NULL, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
}
@@ -1759,10 +1752,10 @@ static int call_nt_transact_ioctl(connection_struct *conn,
static BOOL logged_message = False;
if(!logged_message) {
- DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
+ DEBUG(2,("call_nt_transact_ioctl: Currently not implemented.\n"));
logged_message = True; /* Only print this once... */
}
- return(ERROR_BOTH(NT_STATUS_NOT_IMPLEMENTED,ERRSRV,ERRnosupport));
+ return ERROR_DOS(ERRSRV,ERRnosupport);
}
/****************************************************************************
@@ -1804,7 +1797,7 @@ due to being in oplock break state.\n" ));
if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
END_PROFILE(SMBnttrans);
- return (ERROR(ERRSRV,ERRaccess));
+ return ERROR_DOS(ERRSRV,ERRaccess);
}
outsize = set_message(outbuf,0,0,True);
@@ -1818,7 +1811,7 @@ due to being in oplock break state.\n" ));
DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
END_PROFILE(SMBnttrans);
- return(ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
/* Allocate the space for the setup, the maximum needed parameters and data */
@@ -1837,7 +1830,7 @@ due to being in oplock break state.\n" ));
safe_free(data);
DEBUG(0,("reply_nttrans : Out of memory\n"));
END_PROFILE(SMBnttrans);
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
}
/* Copy the param and data bytes sent with this request into
@@ -1846,7 +1839,7 @@ due to being in oplock break state.\n" ));
num_data_sofar = data_count;
if (parameter_count > total_parameter_count || data_count > total_data_count)
- exit_server("reply_nttrans: invalid sizes in packet.\n");
+ exit_server("reply_nttrans: invalid sizes in packet.");
if(setup) {
memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
@@ -1869,7 +1862,7 @@ due to being in oplock break state.\n" ));
of the parameter/data bytes */
outsize = set_message(outbuf,0,0,True);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_nttrans: send_smb failed.\n");
+ exit_server("reply_nttrans: send_smb failed.");
while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
BOOL ret;
@@ -1884,14 +1877,11 @@ due to being in oplock break state.\n" ));
DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
(smb_read_error == READ_ERROR) ? "error" : "timeout" ));
}
- if(params)
- free(params);
- if(data)
- free(data);
- if(setup)
- free(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
+ SAFE_FREE(setup);
END_PROFILE(SMBnttrans);
- return(ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
/* Revise total_params and total_data in case they have changed downwards */
@@ -1900,7 +1890,7 @@ due to being in oplock break state.\n" ));
num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
- exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
+ exit_server("reply_nttrans2: data overflow in secondary nttrans packet");
memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)],
smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
@@ -1910,8 +1900,7 @@ due to being in oplock break state.\n" ));
}
if (Protocol >= PROTOCOL_NT1) {
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
}
/* Now we must call the relevant NT_TRANS function */
@@ -1961,14 +1950,11 @@ due to being in oplock break state.\n" ));
default:
/* Error in request */
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
- if(setup)
- free(setup);
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBnttrans);
- return (ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
/* As we do not know how many data packets will need to be
@@ -1978,12 +1964,9 @@ due to being in oplock break state.\n" ));
an error packet.
*/
- if(setup)
- free(setup);
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(setup);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBnttrans);
return outsize; /* If a correct response was needed the call_nt_transact_xxxx
calls have already sent it. If outsize != -1 then it is
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 6919249a226..9cefcc9b45e 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -22,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern userdom_struct current_user_info;
extern uint16 global_oplock_port;
extern BOOL global_client_failed_oplock_break;
@@ -36,8 +34,10 @@ static int fd_open(struct connection_struct *conn, char *fname,
int flags, mode_t mode)
{
int fd;
-#ifdef O_NONBLOCK
- flags |= O_NONBLOCK;
+
+#ifdef O_NOFOLLOW
+ if (!lp_symlinks(SNUM(conn)))
+ flags |= O_NOFOLLOW;
#endif
fd = conn->vfs_ops.open(conn,dos_to_unix(fname,False),flags,mode);
@@ -184,7 +184,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
- GetTimeOfDay(&fsp->open_time);
fsp->vuid = current_user.vuid;
fsp->size = psbuf->st_size;
fsp->pos = -1;
@@ -216,16 +215,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
conn->num_files_open + 1));
- /*
- * Take care of inherited ACLs on created files. JRA.
- */
-
- if ((flags & O_CREAT) && (conn->vfs_ops.fchmod_acl != NULL)) {
- int saved_errno = errno; /* We might get ENOSYS in the next call.. */
- if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
- errno = saved_errno; /* Ignore ENOSYS */
- }
-
return True;
}
@@ -364,7 +353,7 @@ static int access_table(int new_deny,int old_deny,int old_mode,
check if we can open a file with a share mode
****************************************************************************/
-static int check_share_mode( share_mode_entry *share, int share_mode,
+static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, int share_mode,
const char *fname, BOOL fcbopen, int *flags)
{
int deny_mode = GET_DENY_MODE(share_mode);
@@ -372,6 +361,14 @@ static int check_share_mode( share_mode_entry *share, int share_mode,
int old_deny_mode = GET_DENY_MODE(share->share_mode);
/*
+ * share modes = false means don't bother to check for
+ * DENY mode conflict. This is a *really* bad idea :-). JRA.
+ */
+
+ if(!lp_share_modes(SNUM(conn)))
+ return True;
+
+ /*
* Don't allow any opens once the delete on close flag has been
* set.
*/
@@ -500,7 +497,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
- opb_ret = request_oplock_break(share_entry, dev, inode);
+ opb_ret = request_oplock_break(share_entry);
/* Now relock. */
lock_share_entry(conn, dev, inode);
@@ -508,7 +505,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
if(opb_ret == False) {
DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
errno = EACCES;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
@@ -526,8 +523,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
/* someone else has a share lock on it, check to see
if we can too */
- if(check_share_mode(share_entry, share_mode, fname, fcbopen, p_flags) == False) {
- free((char *)old_shares);
+ if(check_share_mode(conn, share_entry, share_mode, fname, fcbopen, p_flags) == False) {
+ SAFE_FREE(old_shares);
errno = EACCES;
return -1;
}
@@ -535,7 +532,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
} /* end for */
if(broke_oplock) {
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
oplock_contention_count++;
@@ -555,11 +552,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
if (process_exists(broken_entry.pid)) {
- pstring errmsg;
- slprintf(errmsg, sizeof(errmsg)-1,
- "open_mode_check: Existant process %d left active oplock.\n",
- broken_entry.pid );
- smb_panic(errmsg);
+ DEBUG(0,("open_mode_check: Existent process %d left active oplock.\n",
+ broken_entry.pid ));
}
if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
@@ -574,7 +568,7 @@ dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fn
* other process's entry.
*/
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
break;
}
@@ -583,8 +577,7 @@ dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fn
} while(broke_oplock);
- if(old_shares != 0)
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
/*
* Refuse to grant an oplock in case the contention limit is
@@ -629,6 +622,7 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
int deny_mode = GET_DENY_MODE(share_mode);
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
BOOL delete_access_requested = GET_DELETE_ACCESS_REQUESTED(share_mode);
+ BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
BOOL file_existed = VALID_STAT(*psbuf);
BOOL fcbopen = False;
SMB_DEV_T dev = 0;
@@ -645,7 +639,7 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
of the passed parameters are ignored */
*Access = DOS_OPEN_WRONLY;
*action = FILE_WAS_CREATED;
- return print_fsp_open(conn);
+ return print_fsp_open(conn, fname);
}
fsp = file_new(conn);
@@ -688,10 +682,10 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
return NULL;
}
- if (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST)
+ if (CAN_WRITE(conn) && (GET_FILE_CREATE_DISPOSITION(ofun) == FILE_CREATE_IF_NOT_EXIST))
flags2 |= O_CREAT;
- if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)
+ if (CAN_WRITE(conn) && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE))
flags2 |= O_TRUNC;
if (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL)
@@ -916,6 +910,27 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
set_share_mode(fsp, port, oplock_request);
+ if (delete_on_close) {
+ NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+
+ if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
+ unlock_share_entry_fsp(fsp);
+ fd_close(conn,fsp);
+ file_free(fsp);
+ return NULL;
+ }
+ }
+
+ /*
+ * Take care of inherited ACLs on created files. JRA.
+ */
+
+ if (!file_existed && (conn->vfs_ops.fchmod_acl != NULL)) {
+ int saved_errno = errno; /* We might get ENOSYS in the next call.. */
+ if (conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode) == -1 && errno == ENOSYS)
+ errno = saved_errno; /* Ignore ENOSYS */
+ }
+
unlock_share_entry_fsp(fsp);
conn->num_files_open++;
@@ -956,11 +971,9 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
* Setup the files_struct for it.
*/
- fsp->fd = -1;
fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
- GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
fsp->pos = -1;
@@ -985,7 +998,7 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
*/
string_set(&fsp->fsp_name,fname);
fsp->wbmpx_ptr = NULL;
- fsp->wcp = NULL; /* Write cache pointer. */
+ fsp->wcp = NULL; /* Write cache pointer. */
conn->num_files_open++;
@@ -1040,11 +1053,12 @@ int close_file_fchmod(files_struct *fsp)
****************************************************************************/
files_struct *open_directory(connection_struct *conn, char *fname,
- SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action)
+ SMB_STRUCT_STAT *psbuf, int share_mode, int smb_ofun, mode_t unixmode, int *action)
{
extern struct current_user current_user;
BOOL got_stat = False;
files_struct *fsp = file_new(conn);
+ BOOL delete_on_close = GET_DELETE_ON_CLOSE_FLAG(share_mode);
if(!fsp)
return NULL;
@@ -1128,18 +1142,16 @@ files_struct *open_directory(connection_struct *conn, char *fname,
* Setup the files_struct for it.
*/
- fsp->fd = -1;
fsp->mode = psbuf->st_mode;
fsp->inode = psbuf->st_ino;
fsp->dev = psbuf->st_dev;
- GetTimeOfDay(&fsp->open_time);
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
fsp->pos = -1;
fsp->can_lock = True;
fsp->can_read = False;
fsp->can_write = False;
- fsp->share_mode = 0;
+ fsp->share_mode = share_mode;
fsp->print_file = False;
fsp->modified = False;
fsp->oplock_type = NO_OPLOCK;
@@ -1147,6 +1159,16 @@ files_struct *open_directory(connection_struct *conn, char *fname,
fsp->is_directory = True;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
+
+ if (delete_on_close) {
+ NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close);
+
+ if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
+ file_free(fsp);
+ return NULL;
+ }
+ }
+
/*
* Note that the file name here is the *untranslated* name
* ie. it is still in the DOS codepage sent from the client.
@@ -1256,12 +1278,12 @@ dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (doub
/* Oplock break.... */
unlock_share_entry(conn, dev, inode);
- if(request_oplock_break(share_entry, dev, inode) == False)
+ if(request_oplock_break(share_entry) == False)
{
DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
return False;
}
lock_share_entry(conn, dev, inode);
@@ -1291,7 +1313,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
if(broke_oplock)
{
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
}
} while(broke_oplock);
@@ -1312,7 +1334,6 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
free_and_exit:
unlock_share_entry(conn, dev, inode);
- if(old_shares != NULL)
- free((char *)old_shares);
+ SAFE_FREE(old_shares);
return(ret);
}
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 7033eddc163..cae94bc7a8f 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -1,8 +1,9 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 2.2.x
oplock processing
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998 - 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,8 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* Oplock ipc UDP socket. */
static int oplock_sock = -1;
uint16 global_oplock_port = 0;
@@ -37,7 +36,7 @@ extern int smb_read_error;
static struct kernel_oplocks *koplocks;
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local);
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local);
/****************************************************************************
Get the number of current exclusive oplocks.
@@ -76,97 +75,97 @@ BOOL oplock_message_waiting(fd_set *fds)
BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout)
{
- struct sockaddr_in from;
- int fromlen = sizeof(from);
- int32 msg_len = 0;
-
- smb_read_error = 0;
-
- if(timeout != 0) {
- struct timeval to;
- int selrtn;
- int maxfd = oplock_sock;
-
- if (koplocks && koplocks->notification_fd != -1) {
- FD_SET(koplocks->notification_fd, fds);
- maxfd = MAX(maxfd, koplocks->notification_fd);
- }
-
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- selrtn = sys_select(maxfd+1,fds,&to);
-
- if (selrtn == -1 && errno == EINTR) {
- /* could be a kernel oplock interrupt */
- if (koplocks && koplocks->msg_waiting(fds)) {
- return koplocks->receive_message(fds, buffer, buffer_len);
- }
- }
-
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
- }
-
- if (koplocks && koplocks->msg_waiting(fds)) {
- return koplocks->receive_message(fds, buffer, buffer_len);
- }
-
- if (!FD_ISSET(oplock_sock, fds)) return False;
-
- /*
- * From here down we deal with the smbd <--> smbd
- * oplock break protocol only.
- */
-
- /*
- * Read a loopback udp message.
- */
- msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
- buffer_len - OPBRK_CMD_HEADER_LEN, 0,
- (struct sockaddr *)&from, &fromlen);
-
- if(msg_len < 0) {
- DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
- return False;
- }
-
- /* Validate message length. */
- if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
- DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
- msg_len,
- buffer_len - OPBRK_CMD_HEADER_LEN));
- return False;
- }
-
- /* Validate message from address (must be localhost). */
- if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
- DEBUG(0,("receive_local_message: invalid 'from' address \
-(was %lx should be 127.0.0.1\n", (long)from.sin_addr.s_addr));
- return False;
- }
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
-
- return True;
+ struct sockaddr_in from;
+ int fromlen = sizeof(from);
+ int32 msg_len = 0;
+
+ smb_read_error = 0;
+
+ if(timeout != 0) {
+ struct timeval to;
+ int selrtn;
+ int maxfd = oplock_sock;
+
+ if (koplocks && koplocks->notification_fd != -1) {
+ FD_SET(koplocks->notification_fd, fds);
+ maxfd = MAX(maxfd, koplocks->notification_fd);
+ }
+
+ to.tv_sec = timeout / 1000;
+ to.tv_usec = (timeout % 1000) * 1000;
+
+ selrtn = sys_select(maxfd+1,fds,NULL,NULL,&to);
+
+ if (selrtn == -1 && errno == EINTR) {
+ /* could be a kernel oplock interrupt */
+ if (koplocks && koplocks->msg_waiting(fds)) {
+ return koplocks->receive_message(fds, buffer, buffer_len);
+ }
+ }
+
+ /* Check if error */
+ if(selrtn == -1) {
+ /* something is wrong. Maybe the socket is dead? */
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+
+ /* Did we timeout ? */
+ if (selrtn == 0) {
+ smb_read_error = READ_TIMEOUT;
+ return False;
+ }
+ }
+
+ if (koplocks && koplocks->msg_waiting(fds)) {
+ return koplocks->receive_message(fds, buffer, buffer_len);
+ }
+
+ if (!FD_ISSET(oplock_sock, fds))
+ return False;
+
+ /*
+ * From here down we deal with the smbd <--> smbd
+ * oplock break protocol only.
+ */
+
+ /*
+ * Read a loopback udp message.
+ */
+ msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
+ buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen);
+
+ if(msg_len < 0) {
+ DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
+ return False;
+ }
+
+ /* Validate message length. */
+ if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
+ DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n", msg_len,
+ buffer_len - OPBRK_CMD_HEADER_LEN));
+ return False;
+ }
+
+ /* Validate message from address (must be localhost). */
+ if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+ DEBUG(0,("receive_local_message: invalid 'from' address \
+(was %lx should be 127.0.0.1)\n", (long)from.sin_addr.s_addr));
+ return False;
+ }
+
+ /* Setup the message header */
+ SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
+ SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
+
+ return True;
}
/****************************************************************************
Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
disabled (just sets flags). Returns True if oplock set.
****************************************************************************/
+
BOOL set_file_oplock(files_struct *fsp, int oplock_type)
{
if (koplocks && !koplocks->set_oplock(fsp, oplock_type))
@@ -179,8 +178,9 @@ BOOL set_file_oplock(files_struct *fsp, int oplock_type)
else
exclusive_oplocks_open++;
- DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
+ DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, file_id = %lu, \
+tv_sec = %x, tv_usec = %x\n",
+ fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
(int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
return True;
@@ -192,7 +192,8 @@ BOOL set_file_oplock(files_struct *fsp, int oplock_type)
void release_file_oplock(files_struct *fsp)
{
- if (koplocks) koplocks->release_oplock(fsp);
+ if (koplocks)
+ koplocks->release_oplock(fsp);
if (fsp->oplock_type == LEVEL_II_OPLOCK)
level_II_oplocks_open--;
@@ -211,7 +212,8 @@ void release_file_oplock(files_struct *fsp)
static void downgrade_file_oplock(files_struct *fsp)
{
- if (koplocks) koplocks->release_oplock(fsp);
+ if (koplocks)
+ koplocks->release_oplock(fsp);
fsp->oplock_type = LEVEL_II_OPLOCK;
exclusive_oplocks_open--;
level_II_oplocks_open++;
@@ -293,161 +295,142 @@ int setup_oplock_select_set( fd_set *fds)
Process an oplock break message - whether it came from the UDP socket
or from the kernel.
****************************************************************************/
+
BOOL process_local_message(char *buffer, int buf_size)
{
- int32 msg_len;
- uint16 from_port;
- char *msg_start;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- pid_t remotepid;
- struct timeval tval;
- struct timeval *ptval = NULL;
- uint16 break_cmd_type;
-
- msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
- from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
-
- msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
-
- DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
- msg_len, from_port));
-
- /*
- * Pull the info out of the requesting packet.
- */
-
- break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
-
- switch(break_cmd_type)
- {
- case KERNEL_OPLOCK_BREAK_CMD:
- if (!koplocks) {
- DEBUG(0,("unexpected kernel oplock break!\n"));
- break;
- }
- if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev)) {
- DEBUG(0,("kernel oplock break parse failure!\n"));
- }
- break;
-
- case OPLOCK_BREAK_CMD:
- case LEVEL_II_OPLOCK_BREAK_CMD:
-
- /* Ensure that the msg length is correct. */
- if(msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
- (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
- return False;
- }
- {
- long usec;
- time_t sec;
-
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
- memcpy((char *)&sec, msg_start+OPLOCK_BREAK_SEC_OFFSET,sizeof(sec));
- tval.tv_sec = sec;
- memcpy((char *)&usec, msg_start+OPLOCK_BREAK_USEC_OFFSET, sizeof(usec));
- tval.tv_usec = usec;
-
- ptval = &tval;
-
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
-
- DEBUG(5,("process_local_message: (%s) oplock break request from \
-pid %d, port %d, dev = %x, inode = %.0f\n",
- (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode));
- }
- break;
-
- /*
- * Keep this as a debug case - eventually we can remove it.
- */
- case 0x8001:
- DEBUG(0,("process_local_message: Received unsolicited break \
+ int32 msg_len;
+ uint16 from_port;
+ char *msg_start;
+ pid_t remotepid;
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ unsigned long file_id;
+ uint16 break_cmd_type;
+
+ msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
+ from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
+
+ msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
+
+ DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
+ msg_len, from_port));
+
+ /*
+ * Pull the info out of the requesting packet.
+ */
+
+ break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
+
+ switch(break_cmd_type) {
+ case KERNEL_OPLOCK_BREAK_CMD:
+ if (!koplocks) {
+ DEBUG(0,("unexpected kernel oplock break!\n"));
+ break;
+ }
+ if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev, &file_id)) {
+ DEBUG(0,("kernel oplock break parse failure!\n"));
+ }
+ break;
+
+ case OPLOCK_BREAK_CMD:
+ case LEVEL_II_OPLOCK_BREAK_CMD:
+
+ /* Ensure that the msg length is correct. */
+ if(msg_len != OPLOCK_BREAK_MSG_LEN) {
+ DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
+ (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
+ return False;
+ }
+
+ memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
+ memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+ memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
+ memcpy((char *)&file_id, msg_start+OPLOCK_BREAK_FILEID_OFFSET,sizeof(file_id));
+
+ DEBUG(5,("process_local_message: (%s) oplock break request from \
+pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
+ (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
+ (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
+ break;
+
+ /*
+ * Keep this as a debug case - eventually we can remove it.
+ */
+ case 0x8001:
+ DEBUG(0,("process_local_message: Received unsolicited break \
reply - dumping info.\n"));
- if(msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: ubr: incorrect length for reply \
+ if(msg_len != OPLOCK_BREAK_MSG_LEN) {
+ DEBUG(0,("process_local_message: ubr: incorrect length for reply \
(was %d, should be %d).\n", (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- {
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
-
- DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %.0f\n", (int)remotepid, from_port, (unsigned int)dev, (double)inode));
-
- }
- return False;
-
- default:
- DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
- (unsigned int)SVAL(msg_start,0)));
- return False;
- }
-
- /*
- * Now actually process the break request.
- */
-
- if((exclusive_oplocks_open + level_II_oplocks_open) != 0)
- {
- if (oplock_break(dev, inode, ptval, False) == False)
- {
- DEBUG(0,("process_local_message: oplock break failed.\n"));
- return False;
- }
- }
- else
- {
- /*
- * If we have no record of any currently open oplocks,
- * it's not an error, as a close command may have
- * just been issued on the file that was oplocked.
- * Just log a message and return success in this case.
- */
- DEBUG(3,("process_local_message: oplock break requested with no outstanding \
+ return False;
+ }
+
+ memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
+ memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
+ memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
+ memcpy((char *)&file_id, msg_start+OPLOCK_BREAK_FILEID_OFFSET,sizeof(file_id));
+
+ DEBUG(0,("process_local_message: unsolicited oplock break reply from \
+pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
+ (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
+
+ return False;
+
+ default:
+ DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
+ (unsigned int)SVAL(msg_start,0)));
+ return False;
+ }
+
+ /*
+ * Now actually process the break request.
+ */
+
+ if((exclusive_oplocks_open + level_II_oplocks_open) != 0) {
+ if (oplock_break(dev, inode, file_id, False) == False) {
+ DEBUG(0,("process_local_message: oplock break failed.\n"));
+ return False;
+ }
+ } else {
+ /*
+ * If we have no record of any currently open oplocks,
+ * it's not an error, as a close command may have
+ * just been issued on the file that was oplocked.
+ * Just log a message and return success in this case.
+ */
+ DEBUG(3,("process_local_message: oplock break requested with no outstanding \
oplocks. Returning success.\n"));
- }
-
- /*
- * Do the appropriate reply - none in the kernel or level II case.
- */
-
- if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
- {
- struct sockaddr_in toaddr;
-
- /* Send the message back after OR'ing in the 'REPLY' bit. */
- SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
-
- memset((char *)&toaddr,'\0',sizeof(toaddr));
- toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- toaddr.sin_port = htons(from_port);
- toaddr.sin_family = AF_INET;
-
- if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
- (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
- {
- DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
- (int)remotepid, strerror(errno)));
- return False;
- }
-
- DEBUG(5,("process_local_message: oplock break reply sent to \
-pid %d, port %d, for file dev = %x, inode = %.0f\n",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode));
- }
-
- return True;
+ }
+
+ /*
+ * Do the appropriate reply - none in the kernel or level II case.
+ */
+
+ if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD) {
+ struct sockaddr_in toaddr;
+
+ /* Send the message back after OR'ing in the 'REPLY' bit. */
+ SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
+
+ memset((char *)&toaddr,'\0',sizeof(toaddr));
+ toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ toaddr.sin_port = htons(from_port);
+ toaddr.sin_family = AF_INET;
+
+ if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
+ (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) {
+ DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
+ (int)remotepid, strerror(errno)));
+ return False;
+ }
+
+ DEBUG(5,("process_local_message: oplock break reply sent to \
+pid %d, port %d, for file dev = %x, inode = %.0f, file_id = %lu\n",
+ (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
+ }
+
+ return True;
}
/****************************************************************************
@@ -476,81 +459,82 @@ static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
static void wait_before_sending_break(BOOL local_request)
{
- extern struct timeval smb_last_time;
+ extern struct timeval smb_last_time;
- if(local_request) {
- struct timeval cur_tv;
- long wait_left = (long)lp_oplock_break_wait_time();
+ if(local_request) {
+ struct timeval cur_tv;
+ long wait_left = (long)lp_oplock_break_wait_time();
- if (wait_left == 0)
- return;
+ if (wait_left == 0)
+ return;
- GetTimeOfDay(&cur_tv);
+ GetTimeOfDay(&cur_tv);
- wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
+ wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
- if(wait_left > 0) {
- wait_left = MIN(wait_left, 1000);
- sys_usleep(wait_left * 1000);
- }
- }
+ if(wait_left > 0) {
+ wait_left = MIN(wait_left, 1000);
+ sys_usleep(wait_left * 1000);
+ }
+ }
}
/****************************************************************************
Ensure that we have a valid oplock.
****************************************************************************/
-static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
+
+static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id)
{
- files_struct *fsp = NULL;
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "initial_break_processing: called for dev = %x, inode = %.0f tv_sec = %x, tv_usec = %x.\n",
- (unsigned int)dev, (double)inode, tval ? (int)tval->tv_sec : 0,
- tval ? (int)tval->tv_usec : 0);
- dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
- exclusive_oplocks_open, level_II_oplocks_open );
- }
-
- /* We need to search the file open table for the
- entry containing this dev and inode, and ensure
- we have an oplock on it. */
- fsp = file_find_dit(dev, inode, tval);
-
- if(fsp == NULL)
- {
- /* The file could have been closed in the meantime - return success. */
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "initial_break_processing: cannot find open file with " );
- dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
- dbgtext( "allowing break to succeed.\n" );
- }
- return NULL;
- }
-
- /* Ensure we have an oplock on the file */
-
- /* There is a potential race condition in that an oplock could
- have been broken due to another udp request, and yet there are
- still oplock break messages being sent in the udp message
- queue for this file. So return true if we don't have an oplock,
- as we may have just freed it.
- */
-
- if(fsp->oplock_type == NO_OPLOCK)
- {
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
- dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
- dbgtext( "Allowing break to succeed regardless.\n" );
- }
- return NULL;
- }
-
- return fsp;
+ files_struct *fsp = NULL;
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "initial_break_processing: called for dev = %x, inode = %.0f file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id);
+ dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
+ exclusive_oplocks_open, level_II_oplocks_open );
+ }
+
+ /*
+ * We need to search the file open table for the
+ * entry containing this dev and inode, and ensure
+ * we have an oplock on it.
+ */
+
+ fsp = file_find_dif(dev, inode, file_id);
+
+ if(fsp == NULL) {
+ /* The file could have been closed in the meantime - return success. */
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "initial_break_processing: cannot find open file with " );
+ dbgtext( "dev = %x, inode = %.0f file_id = %lu", (unsigned int)dev,
+ (double)inode, file_id);
+ dbgtext( "allowing break to succeed.\n" );
+ }
+ return NULL;
+ }
+
+ /* Ensure we have an oplock on the file */
+
+ /*
+ * There is a potential race condition in that an oplock could
+ * have been broken due to another udp request, and yet there are
+ * still oplock break messages being sent in the udp message
+ * queue for this file. So return true if we don't have an oplock,
+ * as we may have just freed it.
+ */
+
+ if(fsp->oplock_type == NO_OPLOCK) {
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
+ dbgtext( "(dev = %x, inode = %.0f, file_id = %lu) has no oplock.\n",
+ (unsigned int)dev, (double)inode, fsp->file_id );
+ dbgtext( "Allowing break to succeed regardless.\n" );
+ }
+ return NULL;
+ }
+
+ return fsp;
}
/****************************************************************************
@@ -559,336 +543,322 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, st
BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
{
- extern uint32 global_client_caps;
- char outbuf[128];
- BOOL got_lock = False;
- SMB_DEV_T dev = fsp->dev;
- SMB_INO_T inode = fsp->inode;
-
- /*
- * We can have a level II oplock even if the client is not
- * level II oplock aware. In this case just remove the
- * flags and don't send the break-to-none message to
- * the client.
- */
-
- if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- wait_before_sending_break(local_request);
-
- /* Prepare the SMBlockingX message. */
-
- prepare_break_message( outbuf, fsp, False);
- if (!send_smb(smbd_server_fd(), outbuf))
- exit_server("oplock_break_level2: send_smb failed.\n");
- }
-
- /*
- * Now we must update the shared memory structure to tell
- * everyone else we no longer have a level II oplock on
- * this open file. If local_request is true then token is
- * the existing lock on the shared memory area.
- */
-
- if(!local_request && lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
- } else {
- got_lock = True;
- }
-
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
- }
-
- if (!local_request && got_lock)
- unlock_share_entry_fsp(fsp);
-
- fsp->oplock_type = NO_OPLOCK;
- level_II_oplocks_open--;
-
- if(level_II_oplocks_open < 0)
- {
- DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
- level_II_oplocks_open));
- abort();
- }
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "oplock_break_level2: returning success for " );
- dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
- }
-
- return True;
+ extern uint32 global_client_caps;
+ char outbuf[128];
+ BOOL got_lock = False;
+ SMB_DEV_T dev = fsp->dev;
+ SMB_INO_T inode = fsp->inode;
+
+ /*
+ * We can have a level II oplock even if the client is not
+ * level II oplock aware. In this case just remove the
+ * flags and don't send the break-to-none message to
+ * the client.
+ */
+
+ if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
+ /*
+ * If we are sending an oplock break due to an SMB sent
+ * by our own client we ensure that we wait at leat
+ * lp_oplock_break_wait_time() milliseconds before sending
+ * the packet. Sending the packet sooner can break Win9x
+ * and has reported to cause problems on NT. JRA.
+ */
+
+ wait_before_sending_break(local_request);
+
+ /* Prepare the SMBlockingX message. */
+
+ prepare_break_message( outbuf, fsp, False);
+ if (!send_smb(smbd_server_fd(), outbuf))
+ exit_server("oplock_break_level2: send_smb failed.\n");
+ }
+
+ /*
+ * Now we must update the shared memory structure to tell
+ * everyone else we no longer have a level II oplock on
+ * this open file. If local_request is true then token is
+ * the existing lock on the shared memory area.
+ */
+
+ if(!local_request && lock_share_entry_fsp(fsp) == False) {
+ DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
+ } else {
+ got_lock = True;
+ }
+
+ if(remove_share_oplock(fsp)==False) {
+ DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
+ }
+
+ if (!local_request && got_lock)
+ unlock_share_entry_fsp(fsp);
+
+ fsp->oplock_type = NO_OPLOCK;
+ level_II_oplocks_open--;
+
+ if(level_II_oplocks_open < 0) {
+ DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
+ level_II_oplocks_open));
+ abort();
+ }
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "oplock_break_level2: returning success for " );
+ dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, fsp->file_id );
+ dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
+ }
+
+ return True;
}
/****************************************************************************
Process an oplock break directly.
****************************************************************************/
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local_request)
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local_request)
{
- extern uint32 global_client_caps;
- extern struct current_user current_user;
- char *inbuf = NULL;
- char *outbuf = NULL;
- files_struct *fsp = NULL;
- time_t start_time;
- BOOL shutdown_server = False;
- BOOL oplock_timeout = False;
- connection_struct *saved_user_conn;
- connection_struct *saved_fsp_conn;
- int saved_vuid;
- pstring saved_dir;
- int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
- pstring file_name;
- BOOL using_levelII;
-
- if((fsp = initial_break_processing(dev, inode, tval)) == NULL)
- return True;
-
- /*
- * Deal with a level II oplock going break to none separately.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
- return oplock_break_level2(fsp, local_request, -1);
-
- /* Mark the oplock break as sent - we don't want to send twice! */
- if (fsp->sent_oplock_break)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
- dbgtext( "file %s ", fsp->fsp_name);
- dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
- }
-
- /* We have to fail the open here as we cannot send another oplock break on
- this file whilst we are awaiting a response from the client - neither
- can we allow another open to succeed while we are waiting for the
- client.
- */
- return False;
- }
-
- if(global_oplock_break) {
- DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
- abort();
- }
-
- /* Now comes the horrid part. We must send an oplock break to the client,
- and then process incoming messages until we get a close or oplock release.
- At this point we know we need a new inbuf/outbuf buffer pair.
- We cannot use these staticaly as we may recurse into here due to
- messages crossing on the wire.
- */
-
- if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
- {
- DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
- return False;
- }
-
- if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
- {
- DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
- free(inbuf);
- inbuf = NULL;
- return False;
- }
-
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- wait_before_sending_break(local_request);
-
- /* Prepare the SMBlockingX message. */
-
- if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
- !koplocks && /* NOTE: we force levelII off for kernel oplocks -
- this will change when it is supported */
- lp_level2_oplocks(SNUM(fsp->conn))) {
- using_levelII = True;
- } else {
- using_levelII = False;
- }
-
- prepare_break_message( outbuf, fsp, using_levelII);
- /* Remember if we just sent a break to level II on this file. */
- fsp->sent_oplock_break = using_levelII?
- LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
-
- if (!send_smb(smbd_server_fd(), outbuf))
- exit_server("oplock_break: send_smb failed.\n");
-
- /* We need this in case a readraw crosses on the wire. */
- global_oplock_break = True;
+ extern uint32 global_client_caps;
+ extern struct current_user current_user;
+ char *inbuf = NULL;
+ char *outbuf = NULL;
+ files_struct *fsp = NULL;
+ time_t start_time;
+ BOOL shutdown_server = False;
+ BOOL oplock_timeout = False;
+ connection_struct *saved_user_conn;
+ connection_struct *saved_fsp_conn;
+ int saved_vuid;
+ pstring saved_dir;
+ int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
+ pstring file_name;
+ BOOL using_levelII;
+
+ if((fsp = initial_break_processing(dev, inode, file_id)) == NULL)
+ return True;
+
+ /*
+ * Deal with a level II oplock going break to none separately.
+ */
+
+ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+ return oplock_break_level2(fsp, local_request, -1);
+
+ /* Mark the oplock break as sent - we don't want to send twice! */
+ if (fsp->sent_oplock_break) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
+ dbgtext( "file %s ", fsp->fsp_name);
+ dbgtext( "(dev = %x, inode = %.0f, file_id = %lu)\n", (unsigned int)dev, (double)inode, fsp->file_id );
+ }
+
+ /*
+ * We have to fail the open here as we cannot send another oplock break on
+ * this file whilst we are awaiting a response from the client - neither
+ * can we allow another open to succeed while we are waiting for the client.
+ */
+ return False;
+ }
+
+ if(global_oplock_break) {
+ DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
+ abort();
+ }
+
+ /*
+ * Now comes the horrid part. We must send an oplock break to the client,
+ * and then process incoming messages until we get a close or oplock release.
+ * At this point we know we need a new inbuf/outbuf buffer pair.
+ * We cannot use these staticaly as we may recurse into here due to
+ * messages crossing on the wire.
+ */
+
+ if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) {
+ DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
+ return False;
+ }
+
+ if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL) {
+ DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
+ SAFE_FREE(inbuf);
+ return False;
+ }
+
+ /*
+ * If we are sending an oplock break due to an SMB sent
+ * by our own client we ensure that we wait at leat
+ * lp_oplock_break_wait_time() milliseconds before sending
+ * the packet. Sending the packet sooner can break Win9x
+ * and has reported to cause problems on NT. JRA.
+ */
+
+ wait_before_sending_break(local_request);
+
+ /* Prepare the SMBlockingX message. */
+
+ if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
+ !koplocks && /* NOTE: we force levelII off for kernel oplocks - this will change when it is supported */
+ lp_level2_oplocks(SNUM(fsp->conn))) {
+ using_levelII = True;
+ } else {
+ using_levelII = False;
+ }
+
+ prepare_break_message( outbuf, fsp, using_levelII);
+ /* Remember if we just sent a break to level II on this file. */
+ fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
+
+ if (!send_smb(smbd_server_fd(), outbuf))
+ exit_server("oplock_break: send_smb failed.\n");
+
+ /* We need this in case a readraw crosses on the wire. */
+ global_oplock_break = True;
- /* Process incoming messages. */
-
- /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
- seconds we should just die.... */
-
- start_time = time(NULL);
-
- /*
- * Save the information we need to re-become the
- * user, then unbecome the user whilst we're doing this.
- */
- saved_user_conn = current_user.conn;
- saved_vuid = current_user.vuid;
- saved_fsp_conn = fsp->conn;
- vfs_GetWd(saved_fsp_conn,saved_dir);
- unbecome_user();
- /* Save the chain fnum. */
- file_chain_save();
-
- /*
- * From Charles Hoch <hoch@exemplary.com>. If the break processing
- * code closes the file (as it often does), then the fsp pointer here
- * points to free()'d memory. We *must* revalidate fsp each time
- * around the loop.
- */
-
- pstrcpy(file_name, fsp->fsp_name);
-
- while((fsp = initial_break_processing(dev, inode, tval)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- {
- if(receive_smb(smbd_server_fd(),inbuf, timeout) == False)
- {
- /*
- * Die if we got an error.
- */
-
- if (smb_read_error == READ_EOF) {
- DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
- shutdown_server = True;
- } else if (smb_read_error == READ_ERROR) {
- DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
- shutdown_server = True;
- } else if (smb_read_error == READ_TIMEOUT) {
- DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
- OPLOCK_BREAK_TIMEOUT ) );
- oplock_timeout = True;
- }
-
- DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
- DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
-
- break;
- }
-
- /*
- * There are certain SMB requests that we shouldn't allow
- * to recurse. opens, renames and deletes are the obvious
- * ones. This is handled in the switch_message() function.
- * If global_oplock_break is set they will push the packet onto
- * the pending smb queue and return -1 (no reply).
- * JRA.
- */
-
- process_smb(inbuf, outbuf);
-
- /*
- * Die if we go over the time limit.
- */
-
- if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "oplock_break: no break received from client " );
- dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
- dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
- dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
- }
- oplock_timeout = True;
- break;
- }
- }
-
- /*
- * Go back to being the user who requested the oplock
- * break.
- */
- if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !become_user(saved_user_conn, saved_vuid))
- {
- DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
- DEBUGADD( 0, ( "Shutting down server\n" ) );
- close(oplock_sock);
- exit_server("unable to re-become user");
- }
- /* Including the directory. */
- vfs_ChDir(saved_fsp_conn,saved_dir);
-
- /* Restore the chain fnum. */
- file_chain_restore();
-
- /* Free the buffers we've been using to recurse. */
- free(inbuf);
- free(outbuf);
-
- /* We need this in case a readraw crossed on the wire. */
- if(global_oplock_break)
- global_oplock_break = False;
-
- /*
- * If the client timed out then clear the oplock (or go to level II)
- * and continue. This seems to be what NT does and is better than dropping
- * the connection.
- */
-
- if(oplock_timeout && (fsp = initial_break_processing(dev, inode, tval)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- {
- DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
- remove_oplock(fsp,True);
- global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
- }
-
- /*
- * If the client had an error we must die.
- */
-
- if(shutdown_server)
- {
- DEBUG( 0, ( "oplock_break: client failure in break - " ) );
- DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
- close(oplock_sock);
- exit_server("oplock break failure");
- }
-
- /* Santity check - remove this later. JRA */
- if(exclusive_oplocks_open < 0)
- {
- DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n",
- exclusive_oplocks_open));
- abort();
- }
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "oplock_break: returning success for " );
- dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
- }
-
- return True;
+ /* Process incoming messages. */
+
+ /*
+ * JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
+ * seconds we should just die....
+ */
+
+ start_time = time(NULL);
+
+ /*
+ * Save the information we need to re-become the
+ * user, then unbecome the user whilst we're doing this.
+ */
+ saved_user_conn = current_user.conn;
+ saved_vuid = current_user.vuid;
+ saved_fsp_conn = fsp->conn;
+ vfs_GetWd(saved_fsp_conn,saved_dir);
+ change_to_root_user();
+ /* Save the chain fnum. */
+ file_chain_save();
+
+ /*
+ * From Charles Hoch <hoch@exemplary.com>. If the break processing
+ * code closes the file (as it often does), then the fsp pointer here
+ * points to free()'d memory. We *must* revalidate fsp each time
+ * around the loop.
+ */
+
+ pstrcpy(file_name, fsp->fsp_name);
+
+ while((fsp = initial_break_processing(dev, inode, file_id)) &&
+ OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ if(receive_smb(smbd_server_fd(),inbuf, timeout) == False) {
+ /*
+ * Die if we got an error.
+ */
+
+ if (smb_read_error == READ_EOF) {
+ DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
+ shutdown_server = True;
+ } else if (smb_read_error == READ_ERROR) {
+ DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
+ shutdown_server = True;
+ } else if (smb_read_error == READ_TIMEOUT) {
+ DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n", OPLOCK_BREAK_TIMEOUT ) );
+ oplock_timeout = True;
+ }
+
+ DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
+ DEBUGADD( 0, ( "(dev = %x, inode = %.0f, file_id = %lu).\n",
+ (unsigned int)dev, (double)inode, file_id));
+
+ break;
+ }
+
+ /*
+ * There are certain SMB requests that we shouldn't allow
+ * to recurse. opens, renames and deletes are the obvious
+ * ones. This is handled in the switch_message() function.
+ * If global_oplock_break is set they will push the packet onto
+ * the pending smb queue and return -1 (no reply).
+ * JRA.
+ */
+
+ process_smb(inbuf, outbuf);
+
+ /*
+ * Die if we go over the time limit.
+ */
+
+ if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "oplock_break: no break received from client " );
+ dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
+ dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
+ dbgtext( "(dev = %x, inode = %.0f, file_id = %lu).\n",
+ (unsigned int)dev, (double)inode, file_id );
+ }
+ oplock_timeout = True;
+ break;
+ }
+ }
+
+ /*
+ * Go back to being the user who requested the oplock
+ * break.
+ */
+ if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !change_to_user(saved_user_conn, saved_vuid)) {
+ DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
+ DEBUGADD( 0, ( "Shutting down server\n" ) );
+ close(oplock_sock);
+ exit_server("unable to re-become user");
+ }
+
+ /* Including the directory. */
+ vfs_ChDir(saved_fsp_conn,saved_dir);
+
+ /* Restore the chain fnum. */
+ file_chain_restore();
+
+ /* Free the buffers we've been using to recurse. */
+ SAFE_FREE(inbuf);
+ SAFE_FREE(outbuf);
+
+ /* We need this in case a readraw crossed on the wire. */
+ if(global_oplock_break)
+ global_oplock_break = False;
+
+ /*
+ * If the client timed out then clear the oplock (or go to level II)
+ * and continue. This seems to be what NT does and is better than dropping
+ * the connection.
+ */
+
+ if(oplock_timeout && (fsp = initial_break_processing(dev, inode, file_id)) &&
+ OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
+ remove_oplock(fsp,True);
+ global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
+ }
+
+ /*
+ * If the client had an error we must die.
+ */
+
+ if(shutdown_server) {
+ DEBUG( 0, ( "oplock_break: client failure in break - " ) );
+ DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
+ close(oplock_sock);
+ exit_server("oplock break failure");
+ }
+
+ /* Santity check - remove this later. JRA */
+ if(exclusive_oplocks_open < 0) {
+ DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n", exclusive_oplocks_open));
+ abort();
+ }
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "oplock_break: returning success for " );
+ dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, file_id );
+ dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
+ }
+
+ return True;
}
/****************************************************************************
@@ -896,212 +866,187 @@ Send an oplock break message to another smbd process. If the oplock is held
by the local smbd then call the oplock break function directly.
****************************************************************************/
-BOOL request_oplock_break(share_mode_entry *share_entry,
- SMB_DEV_T dev, SMB_INO_T inode)
+BOOL request_oplock_break(share_mode_entry *share_entry)
{
- char op_break_msg[OPLOCK_BREAK_MSG_LEN];
- struct sockaddr_in addr_out;
- pid_t pid = sys_getpid();
- time_t start_time;
- int time_left;
- long usec;
- time_t sec;
-
- if(pid == share_entry->pid)
- {
- /* We are breaking our own oplock, make sure it's us. */
- if(share_entry->op_port != global_oplock_port)
- {
- DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
+ char op_break_msg[OPLOCK_BREAK_MSG_LEN];
+ struct sockaddr_in addr_out;
+ pid_t pid = sys_getpid();
+ time_t start_time;
+ int time_left;
+ SMB_DEV_T dev = share_entry->dev;
+ SMB_INO_T inode = share_entry->inode;
+ unsigned long file_id = share_entry->share_file_id;
+
+ if(pid == share_entry->pid) {
+ /* We are breaking our own oplock, make sure it's us. */
+ if(share_entry->op_port != global_oplock_port) {
+ DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
- return False;
- }
+ return False;
+ }
- DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
+ DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
#if 1 /* JRA PARANOIA TEST.... */
- {
- files_struct *fsp = file_find_dit(dev, inode, &share_entry->time);
- if (!fsp) {
- DEBUG(0,("request_oplock_break: PANIC : breaking our own oplock requested for \
-dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x and no fsp found !\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec ));
- smb_panic("request_oplock_break: no fsp found for our own oplock\n");
- }
- }
+ {
+ files_struct *fsp = file_find_dif(dev, inode, file_id);
+ if (!fsp) {
+ DEBUG(0,("request_oplock_break: PANIC : breaking our own oplock requested for \
+dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
+ (unsigned int)dev, (double)inode, file_id ));
+ smb_panic("request_oplock_break: no fsp found for our own oplock\n");
+ }
+ }
#endif /* END JRA PARANOIA TEST... */
- /* Call oplock break direct. */
- return oplock_break(dev, inode, &share_entry->time, True);
- }
-
- /* We need to send a OPLOCK_BREAK_CMD message to the
- port in the share mode entry. */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,LEVEL_II_OPLOCK_BREAK_CMD);
- } else {
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
- }
- memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
- sec = (time_t)share_entry->time.tv_sec;
- memcpy(op_break_msg+OPLOCK_BREAK_SEC_OFFSET,(char *)&sec,sizeof(sec));
- usec = (long)share_entry->time.tv_usec;
- memcpy(op_break_msg+OPLOCK_BREAK_USEC_OFFSET,(char *)&usec,sizeof(usec));
- memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
- memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
-
- /* set the address and port */
- memset((char *)&addr_out,'\0',sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( share_entry->op_port );
- addr_out.sin_family = AF_INET;
+ /* Call oplock break direct. */
+ return oplock_break(dev, inode, file_id, True);
+ }
+
+ /* We need to send a OPLOCK_BREAK_CMD message to the port in the share mode entry. */
+
+ if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,LEVEL_II_OPLOCK_BREAK_CMD);
+ } else {
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
+ }
+
+ memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
+ memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
+ memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
+ memcpy(op_break_msg+OPLOCK_BREAK_FILEID_OFFSET,(char *)&file_id,sizeof(file_id));
+
+ /* Set the address and port. */
+ memset((char *)&addr_out,'\0',sizeof(addr_out));
+ addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr_out.sin_port = htons( share_entry->op_port );
+ addr_out.sin_family = AF_INET;
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "request_oplock_break: sending a oplock break message to " );
- dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
-
- }
-
- if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "request_oplock_break: failed when sending a oplock " );
- dbgtext( "break message to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
- dbgtext( "Error was %s\n", strerror(errno) );
- }
- return False;
- }
-
- /*
- * If we just sent a message to a level II oplock share entry then
- * we are done and may return.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- DEBUG(3,("request_oplock_break: sent break message to level II entry.\n"));
- return True;
- }
-
- /*
- * Now we must await the oplock broken message coming back
- * from the target smbd process. Timeout if it fails to
- * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
- * While we get messages that aren't ours, loop.
- */
-
- start_time = time(NULL);
- time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
-
- while(time_left >= 0)
- {
- char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
- uint16 reply_from_port;
- char *reply_msg_start;
- fd_set fds;
-
- FD_ZERO(&fds);
- FD_SET(oplock_sock,&fds);
-
- if (koplocks && koplocks->notification_fd != -1) {
- FD_SET(koplocks->notification_fd, &fds);
- }
-
- if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
- time_left ? time_left * 1000 : 1) == False)
- {
- if(smb_read_error == READ_TIMEOUT)
- {
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "request_oplock_break: no response received to oplock " );
- dbgtext( "break request to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
- }
-
- /*
- * This is a hack to make handling of failing clients more robust.
- * If a oplock break response message is not received in the timeout
- * period we may assume that the smbd servicing that client holding
- * the oplock has died and the client changes were lost anyway, so
- * we should continue to try and open the file.
- */
- break;
- }
- else
- if( DEBUGLVL( 0 ) )
- {
- dbgtext( "request_oplock_break: error in response received " );
- dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
- dbgtext( "Error was (%s).\n", strerror(errno) );
- }
- return False;
- }
-
- reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
-
- reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
-
-
- /*
- * Test to see if this is the reply we are awaiting.
- */
- if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
- ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
- (reply_from_port == share_entry->op_port) &&
- (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
- &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
- OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
- {
- /*
- * This is the reply we've been waiting for.
- */
- break;
- }
- else
- {
- /*
- * This is another message - a break request.
- * Note that both kernel oplock break requests
- * and UDP inter-smbd oplock break requests will
- * be processed here.
- *
- * Process it to prevent potential deadlock.
- * Note that the code in switch_message() prevents
- * us from recursing into here as any SMB requests
- * we might process that would cause another oplock
- * break request to be made will be queued.
- * JRA.
- */
-
- process_local_message(op_break_reply, sizeof(op_break_reply));
- }
-
- time_left -= (time(NULL) - start_time);
- }
-
- DEBUG(3,("request_oplock_break: broke oplock.\n"));
-
- return True;
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "request_oplock_break: sending a oplock break message to " );
+ dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ }
+
+ if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
+ (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "request_oplock_break: failed when sending a oplock " );
+ dbgtext( "break message to pid %d ", (int)share_entry->pid );
+ dbgtext( "on port %d ", share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ dbgtext( "Error was %s\n", strerror(errno) );
+ }
+ return False;
+ }
+
+ /*
+ * If we just sent a message to a level II oplock share entry then
+ * we are done and may return.
+ */
+
+ if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ DEBUG(3,("request_oplock_break: sent break message to level II entry.\n"));
+ return True;
+ }
+
+ /*
+ * Now we must await the oplock broken message coming back
+ * from the target smbd process. Timeout if it fails to
+ * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
+ * While we get messages that aren't ours, loop.
+ */
+
+ start_time = time(NULL);
+ time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
+
+ while(time_left >= 0) {
+ char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
+ uint16 reply_from_port;
+ char *reply_msg_start;
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ FD_SET(oplock_sock,&fds);
+
+ if (koplocks && koplocks->notification_fd != -1) {
+ FD_SET(koplocks->notification_fd, &fds);
+ }
+
+ if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
+ time_left ? time_left * 1000 : 1) == False) {
+ if(smb_read_error == READ_TIMEOUT) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "request_oplock_break: no response received to oplock " );
+ dbgtext( "break request to pid %d ", (int)share_entry->pid );
+ dbgtext( "on port %d ", share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ }
+
+ /*
+ * This is a hack to make handling of failing clients more robust.
+ * If a oplock break response message is not received in the timeout
+ * period we may assume that the smbd servicing that client holding
+ * the oplock has died and the client changes were lost anyway, so
+ * we should continue to try and open the file.
+ */
+ break;
+ } else {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "request_oplock_break: error in response received " );
+ dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
+ dbgtext( "on port %d ", share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ dbgtext( "Error was (%s).\n", strerror(errno) );
+ }
+ }
+ return False;
+ }
+
+ reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
+ reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
+
+ /*
+ * Test to see if this is the reply we are awaiting.
+ */
+ if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
+ ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
+ (reply_from_port == share_entry->op_port) &&
+ (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
+ OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0)) {
+
+ /*
+ * This is the reply we've been waiting for.
+ */
+ break;
+ } else {
+ /*
+ * This is another message - a break request.
+ * Note that both kernel oplock break requests
+ * and UDP inter-smbd oplock break requests will
+ * be processed here.
+ *
+ * Process it to prevent potential deadlock.
+ * Note that the code in switch_message() prevents
+ * us from recursing into here as any SMB requests
+ * we might process that would cause another oplock
+ * break request to be made will be queued.
+ * JRA.
+ */
+
+ process_local_message(op_break_reply, sizeof(op_break_reply));
+ }
+
+ time_left -= (time(NULL) - start_time);
+ }
+
+ DEBUG(3,("request_oplock_break: broke oplock.\n"));
+
+ return True;
}
/****************************************************************************
@@ -1111,20 +1056,20 @@ dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x and no fsp found !\n",
Used as a last ditch attempt to free a space in the
file table when we have run out.
****************************************************************************/
+
BOOL attempt_close_oplocked_file(files_struct *fsp)
{
+ DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
- DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
-
- if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd != -1)) {
- /* Try and break the oplock. */
- if (oplock_break(fsp->dev, fsp->inode, &fsp->open_time, True)) {
- if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */
- return True;
- }
- }
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd != -1)) {
+ /* Try and break the oplock. */
+ if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) {
+ if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */
+ return True;
+ }
+ }
- return False;
+ return False;
}
/****************************************************************************
@@ -1192,7 +1137,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
*/
if (pid == share_entry->pid) {
- files_struct *new_fsp = file_find_dit(fsp->dev, fsp->inode, &share_entry->time);
+ files_struct *new_fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
/* Paranoia check... */
if(new_fsp == NULL) {
@@ -1213,12 +1158,11 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
*/
DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock.\n"));
- request_oplock_break(share_entry, fsp->dev, fsp->inode);
+ request_oplock_break(share_entry);
}
}
- if (share_list)
- free((char *)share_list);
+ SAFE_FREE(share_list);
unlock_share_entry_fsp(fsp);
/* Paranoia check... */
@@ -1231,6 +1175,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
/****************************************************************************
setup oplocks for this process
****************************************************************************/
+
BOOL init_oplocks(void)
{
struct sockaddr_in sock_name;
diff --git a/source/smbd/oplock_irix.c b/source/smbd/oplock_irix.c
index faf7e8e3c87..10520461753 100644
--- a/source/smbd/oplock_irix.c
+++ b/source/smbd/oplock_irix.c
@@ -22,14 +22,14 @@
#include "includes.h"
#if HAVE_KERNEL_OPLOCKS_IRIX
-extern int DEBUGLEVEL;
static int oplock_pipe_write = -1;
static int oplock_pipe_read = -1;
/****************************************************************************
-test to see if IRIX kernel oplocks work
+ Test to see if IRIX kernel oplocks work.
****************************************************************************/
+
static BOOL irix_oplocks_available(void)
{
int fd;
@@ -82,106 +82,113 @@ Disabling kernel oplock support.\n", strerror(errno) ));
return True;
}
-
-
/****************************************************************************
* Deal with the IRIX kernel <--> smbd
* oplock break protocol.
****************************************************************************/
+
static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{
extern int smb_read_error;
- oplock_stat_t os;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- char dummy;
-
- /*
- * Read one byte of zero to clear the
- * kernel break notify message.
- */
-
- if(read(oplock_pipe_read, &dummy, 1) != 1) {
- DEBUG(0,("receive_local_message: read of kernel notification failed. \
+ oplock_stat_t os;
+ char dummy;
+ files_struct *fsp;
+
+ /*
+ * Read one byte of zero to clear the
+ * kernel break notify message.
+ */
+
+ if(read(oplock_pipe_read, &dummy, 1) != 1) {
+ DEBUG(0,("receive_local_message: read of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /*
- * Do a query to get the
- * device and inode of the file that has the break
- * request outstanding.
- */
-
- if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
- DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+
+ /*
+ * Do a query to get the
+ * device and inode of the file that has the break
+ * request outstanding.
+ */
+
+ if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
+ DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
- if(errno == EAGAIN) {
- /*
- * Duplicate kernel break message - ignore.
- */
- memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
- return True;
- }
- smb_read_error = READ_ERROR;
- return False;
- }
-
- dev = (SMB_DEV_T)os.os_dev;
- inode = (SMB_INO_T)os.os_ino;
-
- DEBUG(5,("receive_local_message: kernel oplock break request received for \
-dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
-
- /*
- * Create a kernel oplock break message.
- */
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
-
- buffer += OPBRK_CMD_HEADER_LEN;
+ if(errno == EAGAIN) {
+ /*
+ * Duplicate kernel break message - ignore.
+ */
+ memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
+ return True;
+ }
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+
+ /*
+ * We only have device and inode info here - we have to guess that this
+ * is the first fsp open with this dev,ino pair.
+ */
+
+ if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev, (SMB_INO_T)os.os_ino)) == NULL) {
+ DEBUG(0,("receive_local_message: unable to find open file with dev = %x, inode = %.0f\n",
+ (unsigned int)os.os_dev, (double)os.os_ino ));
+ return False;
+ }
- SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
+ DEBUG(5,("receive_local_message: kernel oplock break request received for \
+dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
+ /*
+ * Create a kernel oplock break message.
+ */
+
+ /* Setup the message header */
+ SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
+ SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
+
+ buffer += OPBRK_CMD_HEADER_LEN;
- return True;
+ SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
+
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
+
+ return True;
}
-
/****************************************************************************
Attempt to set an kernel oplock on a file.
****************************************************************************/
+
static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (fcntl(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) {
if(errno != EAGAIN) {
DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
-inode = %.0f. Error was %s\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
+inode = %.0f, file_id = %ul. Error was %s\n",
+ fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
strerror(errno) ));
} else {
DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
-inode = %.0f. Another process had the file open.\n",
- fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode ));
+inode = %.0f, file_id = %ul. Another process had the file open.\n",
+ fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
}
return False;
}
- DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode));
+ DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %ul\n",
+ fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
return True;
}
-
/****************************************************************************
Release a kernel oplock on a file.
****************************************************************************/
+
static void irix_release_kernel_oplock(files_struct *fsp)
{
if (DEBUGLVL(10)) {
@@ -190,9 +197,9 @@ static void irix_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
int state = fcntl(fsp->fd, F_OPLKACK, -1);
- dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
+ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul, has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, state );
+ (double)fsp->inode, fsp->file_id, state );
}
/*
@@ -201,18 +208,19 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
if(fcntl(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) {
if( DEBUGLVL( 0 )) {
dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
- dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
+ dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, strerror(errno) );
+ (double)fsp->inode, fsp->file_id, strerror(errno) );
}
}
}
-
/****************************************************************************
-parse a kernel oplock message
+ Parse a kernel oplock message.
****************************************************************************/
-static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev)
+
+static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len,
+ SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id)
{
/* Ensure that the msg length is correct. */
if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
@@ -221,36 +229,39 @@ static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *in
return False;
}
- memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
- memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
+ memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
+ memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
+ memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
- DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f\n",
- (unsigned int)*dev, (double)*inode));
+ DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
+ (unsigned int)*dev, (double)*inode, *file_id));
return True;
}
-
/****************************************************************************
-set *maxfd to include oplock read pipe
+ Set *maxfd to include oplock read pipe.
****************************************************************************/
+
static BOOL irix_oplock_msg_waiting(fd_set *fds)
{
- if (oplock_pipe_read == -1) return False;
+ if (oplock_pipe_read == -1)
+ return False;
return FD_ISSET(oplock_pipe_read,fds);
}
-
/****************************************************************************
-setup kernel oplocks
+ Setup kernel oplocks.
****************************************************************************/
+
struct kernel_oplocks *irix_init_kernel_oplocks(void)
{
int pfd[2];
static struct kernel_oplocks koplocks;
- if (!irix_oplocks_available()) return NULL;
+ if (!irix_oplocks_available())
+ return NULL;
if(pipe(pfd) != 0) {
DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
@@ -270,9 +281,6 @@ struct kernel_oplocks *irix_init_kernel_oplocks(void)
return &koplocks;
}
-
-
-
#else
void oplock_irix_dummy(void) {}
#endif /* HAVE_KERNEL_OPLOCKS_IRIX */
diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c
index 39ee3eb86b3..3f22956aa02 100644
--- a/source/smbd/oplock_linux.c
+++ b/source/smbd/oplock_linux.c
@@ -23,8 +23,6 @@
#if HAVE_KERNEL_OPLOCKS_LINUX
-extern int DEBUGLEVEL;
-
static VOLATILE sig_atomic_t signals_received;
static VOLATILE sig_atomic_t signals_processed;
static VOLATILE sig_atomic_t fd_pending; /* the fd of the current pending signal */
@@ -50,8 +48,9 @@ static VOLATILE sig_atomic_t fd_pending; /* the fd of the current pending signal
#endif
/****************************************************************************
-handle a LEASE signal, incrementing the signals_received and blocking the signal
+ Handle a LEASE signal, incrementing the signals_received and blocking the signal.
****************************************************************************/
+
static void signal_handler(int sig, siginfo_t *info, void *unused)
{
BlockSignals(True, sig);
@@ -61,8 +60,10 @@ static void signal_handler(int sig, siginfo_t *info, void *unused)
}
/****************************************************************************
-try to gain a linux capability
-****************************************************************************/static void set_capability(unsigned capability)
+ Try to gain a linux capability.
+****************************************************************************/
+
+static void set_capability(unsigned capability)
{
#ifndef _LINUX_CAPABILITY_VERSION
#define _LINUX_CAPABILITY_VERSION 0x19980330
@@ -94,11 +95,11 @@ try to gain a linux capability
}
}
-
/****************************************************************************
-call SETLEASE. If we get EACCES then we try setting up the right capability and
-try again
+ Call SETLEASE. If we get EACCES then we try setting up the right capability and
+ try again
****************************************************************************/
+
static int linux_setlease(int fd, int leasetype)
{
int ret;
@@ -117,31 +118,27 @@ static int linux_setlease(int fd, int leasetype)
return ret;
}
-
/****************************************************************************
* Deal with the Linux kernel <--> smbd
* oplock break protocol.
****************************************************************************/
+
static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{
- SMB_DEV_T dev;
- SMB_INO_T inode;
- SMB_STRUCT_STAT sbuf;
BOOL ret = True;
+ struct files_struct *fsp;
- if (signals_received == signals_processed) return False;
+ if (signals_received == signals_processed)
+ return False;
- if (sys_fstat((int)fd_pending,&sbuf) == -1) {
+ if ((fsp = file_find_fd(fd_pending)) == NULL) {
DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd_pending));
ret = False;
goto out;
}
- dev = sbuf.st_dev;
- inode = sbuf.st_ino;
-
DEBUG(3,("receive_local_message: kernel oplock break request received for \
-dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
+dev = %x, inode = %.0f\n", (unsigned int)fsp->dev, (double)fsp->inode ));
/*
* Create a kernel oplock break message.
@@ -155,8 +152,9 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
+ memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
out:
/* now we can receive more signals */
@@ -167,10 +165,10 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
return ret;
}
-
/****************************************************************************
Attempt to set an kernel oplock on a file.
****************************************************************************/
+
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (linux_setlease(fsp->fd, F_WRLCK) == -1) {
@@ -181,16 +179,16 @@ inode = %.0f. (%s)\n",
return False;
}
- DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode));
+ DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n",
+ fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
return True;
}
-
/****************************************************************************
Release a kernel oplock on a file.
****************************************************************************/
+
static void linux_release_kernel_oplock(files_struct *fsp)
{
if (DEBUGLVL(10)) {
@@ -199,9 +197,9 @@ static void linux_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
int state = fcntl(fsp->fd, F_GETLEASE, 0);
- dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
+ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, state );
+ (double)fsp->inode, fsp->file_id, state );
}
/*
@@ -210,18 +208,19 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
if (linux_setlease(fsp->fd, F_UNLCK) == -1) {
if (DEBUGLVL(0)) {
dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
- dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
+ dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, strerror(errno) );
+ (double)fsp->inode, fsp->file_id, strerror(errno) );
}
}
}
-
/****************************************************************************
-parse a kernel oplock message
+ Parse a kernel oplock message.
****************************************************************************/
-static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev)
+
+static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode,
+ SMB_DEV_T *dev, unsigned long *file_id)
{
/* Ensure that the msg length is correct. */
if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
@@ -230,41 +229,44 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i
return False;
}
- memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
- memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
+ memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
+ memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
+ memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
- DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f\n",
- (unsigned int)*dev, (double)*inode));
+ DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)*dev, (double)*inode, *file_id));
return True;
}
-
/****************************************************************************
-see if a oplock message is waiting
+ See if a oplock message is waiting.
****************************************************************************/
+
static BOOL linux_oplock_msg_waiting(fd_set *fds)
{
return signals_processed != signals_received;
}
/****************************************************************************
-see if the kernel supports oplocks
+ See if the kernel supports oplocks.
****************************************************************************/
+
static BOOL linux_oplocks_available(void)
{
int fd, ret;
fd = open("/dev/null", O_RDONLY);
- if (fd == -1) return False; /* uggh! */
+ if (fd == -1)
+ return False; /* uggh! */
ret = fcntl(fd, F_GETLEASE, 0);
close(fd);
return ret == F_UNLCK;
}
-
/****************************************************************************
-setup kernel oplocks
+ Setup kernel oplocks.
****************************************************************************/
+
struct kernel_oplocks *linux_init_kernel_oplocks(void)
{
static struct kernel_oplocks koplocks;
@@ -275,13 +277,13 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return NULL;
}
- act.sa_handler = NULL;
- act.sa_sigaction = signal_handler;
- act.sa_flags = SA_SIGINFO;
- if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
+ act.sa_handler = NULL;
+ act.sa_sigaction = signal_handler;
+ act.sa_flags = SA_SIGINFO;
+ if (sigaction(RT_SIGNAL_LEASE, &act, NULL) != 0) {
DEBUG(0,("Failed to setup RT_SIGNAL_LEASE handler\n"));
return NULL;
- }
+ }
koplocks.receive_message = linux_oplock_receive_message;
koplocks.set_oplock = linux_set_kernel_oplock;
@@ -294,9 +296,6 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
return &koplocks;
}
-
-
-
#else
void oplock_linux_dummy(void) {}
#endif /* HAVE_KERNEL_OPLOCKS_LINUX */
diff --git a/source/smbd/password.c b/source/smbd/password.c
index c6be5f68eda..4ccade52cec 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -21,7 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern int Protocol;
extern struct in_addr ipzero;
@@ -44,6 +43,7 @@ static BOOL challenge_sent=False;
/*******************************************************************
Get the next challenge value - no repeats.
********************************************************************/
+
void generate_next_challenge(char *challenge)
{
unsigned char buf[8];
@@ -56,23 +56,26 @@ void generate_next_challenge(char *challenge)
}
/*******************************************************************
-set the last challenge sent, usually from a password server
+ Set the last challenge sent, usually from a password server.
********************************************************************/
+
BOOL set_challenge(unsigned char *challenge)
{
- memcpy(saved_challenge,challenge,8);
- challenge_sent = True;
- return(True);
+ memcpy(saved_challenge,challenge,8);
+ challenge_sent = True;
+ return(True);
}
/*******************************************************************
-get the last challenge sent
+ Get the last challenge sent.
********************************************************************/
+
static BOOL last_challenge(unsigned char *challenge)
{
- if (!challenge_sent) return(False);
- memcpy(challenge,saved_challenge,8);
- return(True);
+ if (!challenge_sent)
+ return(False);
+ memcpy(challenge,saved_challenge,8);
+ return(True);
}
/* this holds info on user ids that are already validated for this VC */
@@ -81,10 +84,11 @@ static int next_vuid = VUID_OFFSET;
static int num_validated_vuids;
/****************************************************************************
-check if a uid has been validated, and return an pointer to the user_struct
-if it has. NULL if not. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
+ Check if a uid has been validated, and return an pointer to the user_struct
+ if it has. NULL if not. vuid is biased by an offset. This allows us to
+ tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
+
user_struct *get_valid_user_struct(uint16 vuid)
{
user_struct *usp;
@@ -106,8 +110,9 @@ user_struct *get_valid_user_struct(uint16 vuid)
}
/****************************************************************************
-invalidate a uid
+ Invalidate a uid.
****************************************************************************/
+
void invalidate_vuid(uint16 vuid)
{
user_struct *vuser = get_valid_user_struct(vuid);
@@ -119,15 +124,16 @@ void invalidate_vuid(uint16 vuid)
DLIST_REMOVE(validated_users, vuser);
- safe_free(vuser->groups);
+ SAFE_FREE(vuser->groups);
delete_nt_token(&vuser->nt_user_token);
safe_free(vuser);
num_validated_vuids--;
}
/****************************************************************************
-invalidate all vuid entries for this process
+ Invalidate all vuid entries for this process.
****************************************************************************/
+
void invalidate_all_vuids(void)
{
user_struct *usp, *next=NULL;
@@ -140,8 +146,9 @@ void invalidate_all_vuids(void)
}
/****************************************************************************
-return a validated username
+ Return a validated username.
****************************************************************************/
+
char *validated_username(uint16 vuid)
{
user_struct *vuser = get_valid_user_struct(vuid);
@@ -151,8 +158,9 @@ char *validated_username(uint16 vuid)
}
/****************************************************************************
-return a validated domain
+ Return a validated domain.
****************************************************************************/
+
char *validated_domain(uint16 vuid)
{
user_struct *vuser = get_valid_user_struct(vuid);
@@ -161,12 +169,11 @@ char *validated_domain(uint16 vuid)
return(vuser->user.domain);
}
-
/****************************************************************************
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 *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;
@@ -186,8 +193,11 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
/* 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) {
- free(token);
+ SAFE_FREE(token);
return NULL;
}
@@ -198,13 +208,15 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
* se_access_check depends on this.
*/
- uid_to_sid( &psids[psid_ndx++], uid);
+ uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid);
+ psid_ndx++;
/*
* Primary group SID is second in token. Convention.
*/
- gid_to_sid( &psids[psid_ndx++], gid);
+ gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid);
+ psid_ndx++;
/* Now add the group SIDs. */
@@ -214,6 +226,12 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
}
}
+ /* Now add the additional SIDs from the supplimentary token. */
+ if (sup_tok) {
+ 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
@@ -241,13 +259,13 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
}
/****************************************************************************
-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
-tell random client vuid's (normally zero) from valid vuids.
+ 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
+ tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
- char *domain,BOOL guest)
+ char *domain,BOOL guest, NT_USER_TOKEN **pptok)
{
user_struct *vuser = NULL;
struct passwd *pwfile; /* for getting real name from passwd file */
@@ -292,12 +310,15 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
vuser->groups = NULL;
/* Find all the groups this uid is in and store them.
- Used by become_user() */
+ Used by change_to_user() */
initialise_groups(unix_name, uid, gid);
get_current_groups( &vuser->n_groups, &vuser->groups);
+ if (*pptok)
+ add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, pptok);
+
/* Create an NT_USER_TOKEN struct for this user. */
- vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest);
+ vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest, *pptok);
next_vuid++;
num_validated_vuids++;
@@ -321,33 +342,32 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
return vuser->vuid;
}
-
/****************************************************************************
-add a name to the session users list
+ Add a name to the session users list.
****************************************************************************/
+
void add_session_user(char *user)
{
- fstring suser;
- StrnCpy(suser,user,sizeof(suser)-1);
+ fstring suser;
+ StrnCpy(suser,user,sizeof(suser)-1);
- if (!Get_Pwnam(suser,True)) return;
+ if (!Get_Pwnam(suser,True))
+ return;
- if (suser && *suser && !in_list(suser,session_users,False))
- {
- if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
- DEBUG(1,("Too many session users??\n"));
- else
- {
- pstrcat(session_users," ");
- pstrcat(session_users,suser);
+ if (suser && *suser && !in_list(suser,session_users,False)) {
+ if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
+ DEBUG(1,("Too many session users??\n"));
+ else {
+ pstrcat(session_users," ");
+ pstrcat(session_users,suser);
+ }
}
- }
}
-
/****************************************************************************
-update the encrypted smbpasswd file from the plaintext username and password
+ Update the encrypted smbpasswd file from the plaintext username and password.
*****************************************************************************/
+
static BOOL update_smbpassword_file(char *user, char *password)
{
SAM_ACCOUNT *sampass = NULL;
@@ -383,56 +403,55 @@ static BOOL update_smbpassword_file(char *user, char *password)
return ret;
}
-
-
-
-
/****************************************************************************
-core of smb password checking routine.
+ Core of smb password checking routine.
****************************************************************************/
+
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8)
{
- /* Finish the encryption of part_passwd. */
- unsigned char p21[21];
- unsigned char p24[24];
-
- if (part_passwd == NULL)
- DEBUG(10,("No password set - allowing access\n"));
- /* No password set - always true ! */
- if (part_passwd == NULL)
- return 1;
-
- memset(p21,'\0',21);
- memcpy(p21,part_passwd,16);
- E_P24(p21, c8, p24);
+ /* Finish the encryption of part_passwd. */
+ unsigned char p21[21];
+ unsigned char p24[24];
+
+ if (part_passwd == NULL)
+ DEBUG(10,("No password set - allowing access\n"));
+
+ /* No password set - always true ! */
+ if (part_passwd == NULL)
+ return True;
+
+ memset(p21,'\0',21);
+ memcpy(p21,part_passwd,16);
+ E_P24(p21, c8, p24);
#if DEBUG_PASSWORD
- {
- int i;
- DEBUG(100,("Part password (P16) was |"));
- for(i = 0; i < 16; i++)
- DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Password from client was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)password[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Given challenge was |"));
- for(i = 0; i < 8; i++)
- DEBUG(100,("%X ", (unsigned char)c8[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Value from encryption was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)p24[i]));
- DEBUG(100,("|\n"));
- }
+ {
+ int i;
+ DEBUG(100,("Part password (P16) was |"));
+ for(i = 0; i < 16; i++)
+ DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Password from client was |"));
+ for(i = 0; i < 24; i++)
+ DEBUG(100,("%X ", (unsigned char)password[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Given challenge was |"));
+ for(i = 0; i < 8; i++)
+ DEBUG(100,("%X ", (unsigned char)c8[i]));
+ DEBUG(100,("|\n"));
+ DEBUG(100,("Value from encryption was |"));
+ for(i = 0; i < 24; i++)
+ DEBUG(100,("%X ", (unsigned char)p24[i]));
+ DEBUG(100,("|\n"));
+ }
#endif
- return (memcmp(p24, password, 24) == 0);
+ return (memcmp(p24, password, 24) == 0);
}
/****************************************************************************
Do a specific test for an smb password being correct, given a smb_password and
the lanman and NT responses.
****************************************************************************/
+
BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24])
{
@@ -482,8 +501,7 @@ BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
lm_pw = pdb_get_lanman_passwd(sampass);
- if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
- {
+ if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) {
DEBUG(4,("smb_password_ok: no password required for user %s\n",user_name));
return True;
}
@@ -500,11 +518,9 @@ BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
return False;
}
-
/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash
-return True if the password is correct, False otherwise
+ Check if a username/password is OK assuming the password is a 24 byte
+ SMB hash. Return True if the password is correct, False otherwise.
****************************************************************************/
BOOL pass_check_smb(char *user, char *domain, uchar *chal,
@@ -513,27 +529,21 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal,
SAM_ACCOUNT *sampass = NULL;
if (!lm_pwd || !nt_pwd)
- {
return(False);
- }
#if 0 /* JERRY */
/* FIXME! this code looks to be unnecessary now that the passdb
validates that the username exists and has a valid uid */
- if (pwd != NULL && user == NULL)
- {
+ if (pwd != NULL && user == NULL) {
pass = (struct passwd *) pwd;
user = pass->pw_name;
- }
- else
- {
+ } else {
/* I don't get this call here. I think it should be moved.
Need to check on it. --jerry */
pass = smb_getpwnam(user,True);
}
- if (pass == NULL)
- {
+ if (pass == NULL) {
DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user));
return(False);
}
@@ -541,8 +551,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal,
/* get the account information */
pdb_init_sam(&sampass);
- if (!pdb_getsampwnam(sampass, user))
- {
+ if (!pdb_getsampwnam(sampass, user)) {
DEBUG(1,("Couldn't find user '%s' in passdb.\n", user));
return(False);
}
@@ -550,39 +559,40 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal,
/* Quit if the account was disabled. */
if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
DEBUG(1,("Account for user '%s' was disabled.\n", user));
+ pdb_free_sam(sampass);
return(False);
}
- if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)
- {
- if (lp_null_passwords())
- {
+ if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) {
+ if (lp_null_passwords()) {
DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user));
+ pdb_free_sam(sampass);
return(True);
- }
- else
- {
+ } else {
DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user));
+ pdb_free_sam(sampass);
return(False);
}
}
- if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd))
- {
+ if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) {
+ pdb_free_sam(sampass);
return(True);
}
-
+
DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user));
+ pdb_free_sam(sampass);
return False;
}
/****************************************************************************
-check if a username/password pair is OK either via the system password
-database or the encrypted SMB password database
-return True if the password is correct, False otherwise
+ Check if a username/password pair is OK either via the system password
+ database or the encrypted SMB password database
+ return True if the password is correct, False otherwise.
****************************************************************************/
+
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
{
@@ -612,7 +622,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
*/
if (ret)
- return (smb_pam_accountcheck(user) == NT_STATUS_OK);
+ return (NT_STATUS_V(smb_pam_accountcheck(user)) == NT_STATUS_V(NT_STATUS_OK));
return ret;
}
@@ -623,8 +633,9 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
}
/****************************************************************************
-check if a username is valid
+ Check if a username is valid
****************************************************************************/
+
BOOL user_ok(char *user,int snum)
{
pstring valid, invalid;
@@ -638,9 +649,8 @@ BOOL user_ok(char *user,int snum)
ret = !user_in_list(user,invalid);
- if (ret && valid && *valid) {
+ if (ret && valid && *valid)
ret = user_in_list(user,valid);
- }
if (ret && lp_onlyuser(snum)) {
char *user_list = lp_username(snum);
@@ -651,13 +661,11 @@ BOOL user_ok(char *user,int snum)
return(ret);
}
-
-
-
/****************************************************************************
-validate a group username entry. Return the username or NULL
+ Validate a group username entry. Return the username or NULL.
****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum)
+
+static char *validate_group(const char *group,char *password,int pwlen,int snum)
{
#ifdef HAVE_NETGROUP
{
@@ -676,66 +684,24 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
}
#endif
-#ifdef HAVE_GETGRENT
{
- struct group *gptr;
- setgrent();
- while ((gptr = (struct group *)getgrent())) {
- if (strequal(gptr->gr_name,group))
- break;
- }
-
- /*
- * As user_ok can recurse doing a getgrent(), we must
- * copy the member list into a pstring on the stack before
- * use. Bug pointed out by leon@eatworms.swmed.edu.
- */
-
- if (gptr) {
- pstring member_list;
- char *member;
- size_t copied_len = 0;
- int i;
-
- *member_list = '\0';
- member = member_list;
-
- for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) {
- size_t member_len = strlen(gptr->gr_mem[i]) + 1;
- if( copied_len + member_len < sizeof(pstring)) {
-
- DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i]));
-
- safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1);
- copied_len += member_len;
- member += copied_len;
- } else {
- *member = '\0';
- }
+ struct sys_userlist *user_list = get_users_in_group(group);
+ struct sys_userlist *member;
+
+ for (member = user_list; member; member = member->next) {
+ static fstring name;
+ fstrcpy(name,member->unix_name);
+ if (user_ok(name,snum) &&
+ password_ok(name,password,pwlen,NULL)) {
+ free_userlist(user_list);
+ return(&name[0]);
}
- endgrent();
-
- member = member_list;
- while (*member) {
- static fstring name;
- fstrcpy(name,member);
- if (user_ok(name,snum) &&
- password_ok(name,password,pwlen,NULL)) {
- endgrent();
- return(&name[0]);
- }
-
- DEBUG(10,("validate_group = member = %s\n", member));
-
- member += strlen(member) + 1;
- }
- } else {
- endgrent();
- return NULL;
+ DEBUG(10,("validate_group = member = %s\n", member->unix_name));
}
+ free_userlist(user_list);
}
-#endif
+
return(NULL);
}
@@ -835,7 +801,7 @@ and given password ok\n", user));
}
}
- free(user_list);
+ SAFE_FREE(user_list);
}
/* check for a previously validated username/password pair */
@@ -864,7 +830,7 @@ and given password ok\n", user));
pstring_sub(user_list,"%S",lp_servicename(snum));
for (auser=strtok(user_list,LIST_SEP); auser && !ok;
- auser = strtok(NULL,LIST_SEP)) {
+ auser = strtok(NULL,LIST_SEP)) {
if (*auser == '@') {
auser = validate_group(auser+1,password,pwlen,snum);
if (auser) {
@@ -1016,41 +982,39 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
return False;
}
-
/****************************************************************************
-check for a possible hosts equiv or rhosts entry for the user
+ Check for a possible hosts equiv or rhosts entry for the user.
****************************************************************************/
+
BOOL check_hosts_equiv(char *user)
{
- char *fname = NULL;
- pstring rhostsfile;
- struct passwd *pass = Get_Pwnam(user,True);
+ char *fname = NULL;
+ pstring rhostsfile;
+ struct passwd *pass = Get_Pwnam(user,True);
- if (!pass)
- return(False);
+ if (!pass)
+ return(False);
- fname = lp_hosts_equiv();
+ fname = lp_hosts_equiv();
- /* note: don't allow hosts.equiv on root */
- if (fname && *fname && (pass->pw_uid != 0)) {
- if (check_user_equiv(user,client_name(),fname))
- return(True);
- }
+ /* note: don't allow hosts.equiv on root */
+ if (fname && *fname && (pass->pw_uid != 0)) {
+ if (check_user_equiv(user,client_name(),fname))
+ return(True);
+ }
- if (lp_use_rhosts())
- {
- char *home = get_user_home_dir(user);
- if (home) {
- slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
- if (check_user_equiv(user,client_name(),rhostsfile))
- return(True);
- }
- }
+ if (lp_use_rhosts()) {
+ char *home = get_user_service_home_dir(user);
+ if (home) {
+ slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+ if (check_user_equiv(user,client_name(),rhostsfile))
+ return(True);
+ }
+ }
- return(False);
+ return(False);
}
-
/****************************************************************************
Return the client state structure.
****************************************************************************/
@@ -1102,7 +1066,7 @@ struct cli_state *server_cryptkey(void)
}
}
- free(pserver);
+ SAFE_FREE(pserver);
if (!connected_ok) {
DEBUG(0,("password server not available\n"));
@@ -1266,7 +1230,7 @@ static BOOL connect_to_domain_password_server(struct cli_state *pcli,
return False;
}
- if (!name_status_find(0x20, to_ip, remote_machine)) {
+ if (!name_status_find("*", 0, 0x20, to_ip, remote_machine)) {
DEBUG(1, ("connect_to_domain_password_server: Can't "
"resolve name for IP %s\n", server));
return False;
@@ -1367,7 +1331,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
return False;
}
- if (cli_nt_setup_creds(pcli, trust_passwd) == False) {
+ if (!NT_STATUS_IS_OK(cli_nt_setup_creds(pcli, trust_passwd))) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
%s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
cli_nt_session_close(pcli);
@@ -1394,18 +1358,17 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un
if (ip_equal(ipzero, *ip))
return False;
- if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name))
+ if (!lookup_dc_name(global_myname, lp_workgroup(), ip, dc_name))
return False;
return connect_to_domain_password_server(pcli, dc_name, trust_passwd);
}
-
-
/***********************************************************************
We have been asked to dynamcially determine the IP addresses of
the PDC and BDC's for this DOMAIN, and query them in turn.
************************************************************************/
+
static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd, time_t last_change_time)
{
struct in_addr *ip_list = NULL;
@@ -1468,15 +1431,11 @@ static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd
}
}
- if(ip_list != NULL)
- free((char *)ip_list);
-
+ SAFE_FREE(ip_list);
return connected_ok;
}
-
-
/***********************************************************************
Do the same as security=server, but using NT Domain calls and a session
key from the machine password.
@@ -1485,7 +1444,7 @@ static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd
BOOL domain_client_validate( char *user, char *domain,
char *smb_apasswd, int smb_apasslen,
char *smb_ntpasswd, int smb_ntpasslen,
- BOOL *user_exists)
+ BOOL *user_exists, NT_USER_TOKEN **pptoken)
{
unsigned char local_challenge[8];
unsigned char local_lm_response[24];
@@ -1499,6 +1458,10 @@ BOOL domain_client_validate( char *user, char *domain,
uint32 smb_uid_low;
BOOL connected_ok = False;
time_t last_change_time;
+ NTSTATUS status;
+
+ if (pptoken)
+ *pptoken = NULL;
if(user_exists != NULL)
*user_exists = True; /* Only set false on a very specific error. */
@@ -1598,20 +1561,20 @@ BOOL domain_client_validate( char *user, char *domain,
ZERO_STRUCT(info3);
- if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge,
+ status = cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge,
((smb_apasslen != 0) ? smb_apasswd : NULL),
((smb_ntpasslen != 0) ? smb_ntpasswd : NULL),
- &ctr, &info3) == False) {
- uint32 nt_rpc_err;
+ &ctr, &info3);
+
+ if (!NT_STATUS_IS_OK(status)) {
- cli_error(&cli, NULL, NULL, &nt_rpc_err);
DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, get_nt_error_msg(status) ));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
- if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL))
+ if((NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NO_SUCH_USER)) && (user_exists != NULL))
*user_exists = False;
return False;
@@ -1621,6 +1584,43 @@ BOOL domain_client_validate( char *user, char *domain,
* Here, if we really want it, we have lots of info about the user in info3.
*/
+ /* Return group membership as returned by NT. This contains group
+ membership in nested groups which doesn't seem to be accessible by any
+ other means. We merge this into the NT_USER_TOKEN associated with the vuid
+ later on. */
+
+ if (pptoken && (info3.num_groups2 != 0)) {
+ NT_USER_TOKEN *ptok;
+ int i;
+ DOM_SID domain_sid;
+
+ *pptoken = NULL;
+
+ if ((ptok = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) {
+ DEBUG(0, ("domain_client_validate: Out of memory allocating NT_USER_TOKEN\n"));
+ return False;
+ }
+
+ 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"));
+ SAFE_FREE(ptok);
+ return False;
+ }
+
+ if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
+ DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n"));
+ delete_nt_token(&ptok);
+ return False;
+ }
+
+ for (i = 0; i < ptok->num_sids; i++) {
+ sid_copy(&ptok->user_sids[i], &domain_sid);
+ sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid);
+ }
+ *pptoken = ptok;
+ }
+
#if 0
/*
* We don't actually need to do this - plus it fails currently with
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index 366707cd589..2837187f4bf 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -31,8 +31,6 @@
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
-extern int DEBUGLEVEL;
-
extern struct pipe_id_info pipe_names[];
/****************************************************************************
@@ -58,7 +56,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
/* at a mailslot or something we really, really don't understand, */
/* not just something we really don't understand. */
if ( strncmp(fname,PIPE,PIPELEN) != 0 )
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
DEBUG(4,("Opening pipe %s.\n", fname));
@@ -68,7 +66,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
break;
if (pipe_names[i].client_pipe == NULL)
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
/* Strip \PIPE\ off the name. */
pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
@@ -78,7 +76,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
* Hack for NT printers... JRA.
*/
if(should_fail_next_srvsvc_open(fname))
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
#endif
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
@@ -87,7 +85,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
smb_ofun |= FILE_CREATE_IF_NOT_EXIST;
p = open_rpc_pipe_p(fname, conn, vuid);
- if (!p) return(ERROR(ERRSRV,ERRnofids));
+ if (!p) return(ERROR_DOS(ERRSRV,ERRnofids));
/* Prepare the reply */
set_message(outbuf,15,0,True);
@@ -123,7 +121,7 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
char *data;
if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
data = smb_buf(inbuf) + 3;
@@ -163,7 +161,7 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
char *data;
if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
data = smb_base(inbuf) + smb_doff;
@@ -223,7 +221,7 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
#endif
if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
@@ -252,12 +250,12 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
int outsize = set_message(outbuf,0,0,True);
if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
if (!close_rpc_pipe_hnd(p, conn))
- return(ERROR(ERRDOS,ERRbadfid));
+ return(ERROR_DOS(ERRDOS,ERRbadfid));
return(outsize);
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 5c22b89a8d8..99c5760314b 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -38,7 +38,7 @@ typedef struct canon_ace {
struct canon_ace *next, *prev;
SMB_ACL_TAG_T type;
mode_t perms; /* Only use S_I(R|W|X)USR mode bits here. */
- DOM_SID sid;
+ DOM_SID trustee;
enum ace_owner owner_type;
enum ace_attribute attr;
posix_id unix_ug;
@@ -74,7 +74,7 @@ static void free_canon_ace_list( canon_ace *list_head )
while (list_head) {
canon_ace *old_head = list_head;
DLIST_REMOVE(list_head, list_head);
- free(old_head);
+ SAFE_FREE(old_head);
}
}
@@ -103,13 +103,13 @@ static void print_canon_ace(canon_ace *pace, int num)
fstring str;
dbgtext( "canon_ace index %d. Type = %s ", num, pace->attr == ALLOW_ACE ? "allow" : "deny" );
- dbgtext( "SID = %s ", sid_to_string( str, &pace->sid));
+ dbgtext( "SID = %s ", sid_to_string( str, &pace->trustee));
if (pace->owner_type == UID_ACE) {
- struct passwd *pass = sys_getpwuid(pace->unix_ug.uid);
- dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, pass ? pass->pw_name : "UNKNOWN");
+ char *u_name = uidtoname(pace->unix_ug.uid);
+ dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name);
} else if (pace->owner_type == GID_ACE) {
- struct group *grp = getgrgid(pace->unix_ug.gid);
- dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, grp ? grp->gr_name : "UNKNOWN");
+ char *g_name = gidtoname(pace->unix_ug.gid);
+ dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name);
} else
dbgtext( "other ");
switch (pace->type) {
@@ -243,7 +243,7 @@ static void merge_aces( canon_ace **pp_list_head )
curr_ace_next = curr_ace->next; /* Save the link in case of delete. */
- if (sid_equal(&curr_ace->sid, &curr_ace_outer->sid) &&
+ if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
(curr_ace->attr == curr_ace_outer->attr)) {
if( DEBUGLVL( 10 )) {
@@ -256,7 +256,7 @@ static void merge_aces( canon_ace **pp_list_head )
curr_ace_outer->perms |= curr_ace->perms;
DLIST_REMOVE(list_head, curr_ace);
- free(curr_ace);
+ SAFE_FREE(curr_ace);
curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
}
}
@@ -283,7 +283,7 @@ static void merge_aces( canon_ace **pp_list_head )
* we've put on the ACL, we know the deny must be the first one.
*/
- if (sid_equal(&curr_ace->sid, &curr_ace_outer->sid) &&
+ if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
(curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
if( DEBUGLVL( 10 )) {
@@ -301,7 +301,7 @@ static void merge_aces( canon_ace **pp_list_head )
*/
DLIST_REMOVE(list_head, curr_ace);
- free(curr_ace);
+ SAFE_FREE(curr_ace);
curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */
} else {
@@ -317,7 +317,8 @@ static void merge_aces( canon_ace **pp_list_head )
*/
DLIST_REMOVE(list_head, curr_ace_outer);
- free(curr_ace_outer);
+ SAFE_FREE(curr_ace_outer);
+ break;
}
}
@@ -572,7 +573,7 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->type = SMB_ACL_USER_OBJ;
pace->owner_type = UID_ACE;
pace->unix_ug.uid = pst->st_uid;
- pace->sid = *pfile_owner_sid;
+ pace->trustee = *pfile_owner_sid;
pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR);
pace->attr = ALLOW_ACE;
@@ -589,7 +590,7 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->type = SMB_ACL_GROUP_OBJ;
pace->owner_type = GID_ACE;
pace->unix_ug.uid = pst->st_gid;
- pace->sid = *pfile_grp_sid;
+ pace->trustee = *pfile_grp_sid;
pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP);
pace->attr = ALLOW_ACE;
@@ -606,7 +607,7 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->type = SMB_ACL_OTHER;
pace->owner_type = WORLD_ACE;
pace->unix_ug.world = -1;
- pace->sid = global_sid_World;
+ pace->trustee = global_sid_World;
pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH);
pace->attr = ALLOW_ACE;
@@ -688,7 +689,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
if (psa1->info.mask != psa2->info.mask)
continue;
- if (!sid_equal(&psa1->sid, &psa2->sid))
+ if (!sid_equal(&psa1->trustee, &psa2->trustee))
continue;
/*
@@ -718,10 +719,10 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
* Ignore non-mappable SIDs (NT Authority, BUILTIN etc).
*/
- if (non_mappable_sid(&psa->sid)) {
+ if (non_mappable_sid(&psa->trustee)) {
fstring str;
DEBUG(10,("create_canon_ace_lists: ignoring non-mappable SID %s\n",
- sid_to_string(str, &psa->sid) ));
+ sid_to_string(str, &psa->trustee) ));
continue;
}
@@ -738,28 +739,28 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
ZERO_STRUCTP(current_ace);
- sid_copy(&current_ace->sid, &psa->sid);
+ sid_copy(&current_ace->trustee, &psa->trustee);
/*
* Try and work out if the SID is a user or group
* as we need to flag these differently for POSIX.
*/
- if( sid_equal(&current_ace->sid, &global_sid_World)) {
+ if( sid_equal(&current_ace->trustee, &global_sid_World)) {
current_ace->owner_type = WORLD_ACE;
current_ace->unix_ug.world = -1;
- } else if (sid_to_uid( &current_ace->sid, &current_ace->unix_ug.uid, &sid_type)) {
+ } else if (sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid, &sid_type)) {
current_ace->owner_type = UID_ACE;
- } else if (sid_to_gid( &current_ace->sid, &current_ace->unix_ug.gid, &sid_type)) {
+ } else if (sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid, &sid_type)) {
current_ace->owner_type = GID_ACE;
} else {
fstring str;
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
- free(current_ace);
DEBUG(0,("create_canon_ace_lists: unable to map SID %s to uid or gid.\n",
- sid_to_string(str, &current_ace->sid) ));
+ sid_to_string(str, &current_ace->trustee) ));
+ SAFE_FREE(current_ace);
return False;
}
@@ -775,15 +776,15 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
* Now note what kind of a POSIX ACL this should map to.
*/
- if(sid_equal(&current_ace->sid, pfile_owner_sid)) {
+ if(sid_equal(&current_ace->trustee, pfile_owner_sid)) {
current_ace->type = SMB_ACL_USER_OBJ;
- } else if( sid_equal(&current_ace->sid, pfile_grp_sid)) {
+ } else if( sid_equal(&current_ace->trustee, pfile_grp_sid)) {
current_ace->type = SMB_ACL_GROUP_OBJ;
- } else if( sid_equal(&current_ace->sid, &global_sid_World)) {
+ } else if( sid_equal(&current_ace->trustee, &global_sid_World)) {
current_ace->type = SMB_ACL_OTHER;
@@ -827,7 +828,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
- free(current_ace);
+ SAFE_FREE(current_ace);
return False;
}
@@ -878,7 +879,7 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
- free(current_ace);
+ SAFE_FREE(current_ace);
return False;
}
@@ -894,8 +895,7 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
* Free if ACE was not added.
*/
- if (current_ace)
- free(current_ace);
+ SAFE_FREE(current_ace);
}
if (fsp->is_directory && all_aces_are_inherit_only) {
@@ -926,26 +926,23 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
{
extern DOM_SID global_sid_World;
- struct passwd *pass = NULL;
- struct group *gptr = NULL;
+ fstring u_name;
+ fstring g_name;
/* "Everyone" always matches every uid. */
- if (sid_equal(&group_ace->sid, &global_sid_World))
+ if (sid_equal(&group_ace->trustee, &global_sid_World))
return True;
- if (!(pass = sys_getpwuid(uid_ace->unix_ug.uid)))
- return False;
-
- if (!(gptr = getgrgid(group_ace->unix_ug.gid)))
- return False;
+ fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid));
+ fstrcpy(g_name, gidtoname(group_ace->unix_ug.gid));
/*
* Due to the winbind interfaces we need to do this via names,
* not uids/gids.
*/
- return user_in_group_list(pass->pw_name, gptr->gr_name );
+ return user_in_group_list(u_name, g_name );
}
/****************************************************************************
@@ -1068,7 +1065,7 @@ static void process_deny_list( canon_ace **pp_ace_list )
continue;
}
- if (!sid_equal(&curr_ace->sid, &global_sid_World))
+ if (!sid_equal(&curr_ace->trustee, &global_sid_World))
continue;
/* JRATEST - assert. */
@@ -1519,7 +1516,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
ace->type = tagtype;
ace->perms = convert_permset_to_mode_t(permset);
ace->attr = ALLOW_ACE;
- ace->sid = sid;
+ ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
@@ -1720,6 +1717,12 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if(default_ace || fsp->is_directory || fsp->fd == -1) {
if (sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), the_acl_type, the_acl) == -1) {
+ /*
+ * Some systems allow all the above calls and only fail with no ACL support
+ * when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
+ */
+ if (errno == ENOSYS)
+ *pacl_set_support = False;
DEBUG(2,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
fsp->fsp_name, strerror(errno) ));
@@ -1727,6 +1730,12 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
}
} else {
if (sys_acl_set_fd(fsp->fd, the_acl) == -1) {
+ /*
+ * Some systems allow all the above calls and only fail with no ACL support
+ * when attempting to apply the acl. HPUX with HFS is an example of this. JRA.
+ */
+ if (errno == ENOSYS)
+ *pacl_set_support = False;
DEBUG(2,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
fsp->fsp_name, strerror(errno) ));
goto done;
@@ -1938,14 +1947,14 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
for (i = 0; i < num_acls; i++, ace = ace->next) {
SEC_ACCESS acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->sid, nt_acl_type, acc, 0);
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
}
ace = dir_ace;
for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
SEC_ACCESS acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->sid, nt_acl_type, acc,
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
}
@@ -1979,8 +1988,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
sys_acl_free_acl(dir_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
- if (nt_ace_list)
- free(nt_ace_list);
+ SAFE_FREE(nt_ace_list);
return sd_size;
}
@@ -2244,7 +2252,7 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
Note that name is in UNIX character set.
****************************************************************************/
-int chmod_acl(char *name, mode_t mode)
+int chmod_acl(const char *name, mode_t mode)
{
SMB_ACL_T posix_acl = NULL;
int ret = -1;
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 5c329a7c8ac..1299fd20e3a 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -21,7 +21,8 @@
#include "includes.h"
-extern int DEBUGLEVEL;
+/* To be removed.... JRA */
+#define SMB_ALIGNMENT 1
struct timeval smb_last_time;
@@ -44,9 +45,6 @@ int max_recv = BUFFER_SIZE;
extern int last_message;
extern int global_oplock_break;
extern userdom_struct current_user_info;
-extern char *last_inbuf;
-extern char *InBuffer;
-extern char *OutBuffer;
extern int smb_read_error;
extern VOLATILE sig_atomic_t reload_after_sighup;
extern BOOL global_machine_password_needs_changing;
@@ -87,7 +85,7 @@ static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
if(msg->msg_buf == NULL)
{
DEBUG(0,("push_message: malloc fail (2)\n"));
- free((char *)msg);
+ SAFE_FREE(msg);
return False;
}
@@ -125,7 +123,7 @@ static void async_processing(fd_set *fds, char *buffer, int buffer_len)
/* check for sighup processing */
if (reload_after_sighup) {
- unbecome_user();
+ change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(False);
reload_after_sighup = False;
@@ -180,8 +178,8 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
/* Free the message we just copied. */
- free((char *)msg->msg_buf);
- free((char *)msg);
+ SAFE_FREE(msg->msg_buf);
+ SAFE_FREE(msg);
DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
return True;
@@ -199,7 +197,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,timeout>0?&to:NULL);
+ selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,timeout>0?&to:NULL);
/* if we get EINTR then maybe we have received an oplock
signal - treat this as select returning 1. This is ugly, but
@@ -366,11 +364,11 @@ struct smb_message_struct
/* 0x18 */ { NULL, NULL, 0 },
/* 0x19 */ { NULL, NULL, 0 },
/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
-/* 0x1b */ { "SMBreadBmpx",NULL,0},
+/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
/* 0x1c */ { "SMBreadBs",NULL,0},
/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
-/* 0x1e */ { "SMBwriteBmpx",NULL,0},
-/* 0x1f */ { "SMBwriteBs",NULL,0},
+/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
+/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
/* 0x20 */ { "SMBwritec",NULL,0},
/* 0x21 */ { NULL, NULL, 0 },
/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
@@ -615,7 +613,9 @@ static void smb_dump(char *name, int type, char *data, ssize_t len)
if (fd != -1 || errno != EEXIST) break;
}
if (fd != -1) {
- write(fd, data, len);
+ ssize_t ret = write(fd, data, len);
+ if (ret != len)
+ DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
close(fd);
DEBUG(0,("created %s len %d\n", fname, len));
}
@@ -708,20 +708,20 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
/* does this protocol need to be run as root? */
if (!(flags & AS_USER))
- unbecome_user();
+ change_to_root_user();
/* does this protocol need a valid tree connection? */
if ((flags & AS_USER) && !conn) {
- return ERROR(ERRSRV, ERRinvnid);
+ return ERROR_DOS(ERRSRV, ERRinvnid);
}
/* does this protocol need to be run as the connected user? */
- if ((flags & AS_USER) && !become_user(conn,session_tag)) {
+ if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
if (flags & AS_GUEST)
flags &= ~AS_USER;
else
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
/* this code is to work around a bug is MS client 3 without
@@ -732,23 +732,23 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
/* does it need write permission? */
if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
/* ipc services are limited */
if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC)) {
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
/* load service specific parameters */
- if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
- return(ERROR(ERRSRV,ERRaccess));
+ 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) &&
- (!become_guest() ||
+ (!change_to_guest() ||
!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) {
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR_DOS(ERRSRV,ERRaccess));
}
last_inbuf = inbuf;
@@ -797,7 +797,7 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
****************************************************************************/
static BOOL smbd_process_limit(void)
{
- int total_smbds;
+ int32 total_smbds;
if (lp_max_smbd_processes()) {
@@ -813,7 +813,7 @@ set. Ignoring max smbd restriction.\n"));
return False;
}
- if (tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
+ if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
return True;
return total_smbds > lp_max_smbd_processes();
@@ -920,11 +920,11 @@ void construct_reply_common(char *inbuf,char *outbuf)
memset(outbuf,'\0',smb_size);
set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
+ SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
memcpy(outbuf+4,inbuf+4,4);
- CVAL(outbuf,smb_rcls) = SMB_SUCCESS;
- CVAL(outbuf,smb_reh) = 0;
+ SCVAL(outbuf,smb_rcls,SMB_SUCCESS);
+ SCVAL(outbuf,smb_reh,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); /* bit 7 set
means a reply */
SSVAL(outbuf,smb_flg2,FLAGS2_LONG_PATH_COMPONENTS);
@@ -955,7 +955,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
/* maybe its not chained */
if (smb_com2 == 0xFF) {
- CVAL(outbuf,smb_vwv0) = 0xFF;
+ SCVAL(outbuf,smb_vwv0,0xFF);
return outsize;
}
@@ -975,7 +975,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
/* we need to tell the client where the next part of the reply will be */
SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
- CVAL(outbuf,smb_vwv0) = smb_com2;
+ SCVAL(outbuf,smb_vwv0,smb_com2);
/* remember how much the caller added to the chain, only counting stuff
after the parameter words */
@@ -997,7 +997,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
memmove(inbuf2,inbuf,smb_wct);
/* create the in buffer */
- CVAL(inbuf2,smb_com) = smb_com2;
+ SCVAL(inbuf2,smb_com,smb_com2);
/* create the out buffer */
construct_reply_common(inbuf2, outbuf2);
@@ -1012,7 +1012,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
/* copy the new reply and request headers over the old ones, but
preserve the smb_com field */
memmove(orig_outbuf,outbuf2,smb_wct);
- CVAL(orig_outbuf,smb_com) = smb_com1;
+ SCVAL(orig_outbuf,smb_com,smb_com1);
/* restore the saved data, being careful not to overwrite any
data from the reply header */
@@ -1102,7 +1102,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
last_idle_closed_check = t;
/* become root again if waiting */
- unbecome_user();
+ change_to_root_user();
/* check if we need to reload services */
check_reload(t);
@@ -1141,7 +1141,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
return False;
}
- if(global_machine_password_needs_changing)
+ if(global_machine_password_needs_changing && lp_security() == SEC_DOMAIN)
{
unsigned char trust_passwd_hash[16];
time_t lct;
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index 46693a6fe1e..5e744bc97dd 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -28,8 +28,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
#if defined(VXFS_QUOTA)
/*
@@ -57,6 +55,9 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
*/
#include <linux/quota.h>
+#ifdef HAVE_LINUX_XQM_H
+#include <linux/xqm.h>
+#endif
#include <mntent.h>
#include <linux/unistd.h>
@@ -75,10 +76,35 @@ typedef struct _LINUX_SMB_DISK_QUOTA {
} LINUX_SMB_DISK_QUOTA;
/****************************************************************************
+ Abstract out the XFS Quota Manager quota get call.
+****************************************************************************/
+
+static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+{
+ int ret = -1;
+#ifdef HAVE_LINUX_XQM_H
+ struct fs_disk_quota D;
+ ZERO_STRUCT(D);
+
+ if ((ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return ret;
+
+ dp->bsize = (SMB_BIG_UINT)512;
+ dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
+ dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
+ dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
+ dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
+ dp->curinodes = (SMB_BIG_UINT)D.d_icount;
+ dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
+#endif
+ return ret;
+}
+
+/****************************************************************************
Abstract out the old and new Linux quota get calls.
****************************************************************************/
-static int get_smb_linux_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
{
int ret;
#ifdef LINUX_QUOTAS_1
@@ -116,7 +142,7 @@ static int get_smb_linux_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA
try to get the disk space from disk quotas (LINUX version)
****************************************************************************/
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
int r;
SMB_STRUCT_STAT S;
@@ -156,7 +182,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
save_re_uid();
set_effective_uid(0);
- r=get_smb_linux_quota(mnt->mnt_fsname, euser_id, &D);
+ if (strcmp(mnt->mnt_type, "xfs") == 0)
+ r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
+ else
+ r=get_smb_linux_vfs_quota(mnt->mnt_fsname, euser_id, &D);
restore_re_uid();
/* Use softlimit to determine disk space, except when it has been exceeded */
@@ -201,7 +230,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
try to get the disk space from disk quotas (CRAY VERSION)
****************************************************************************/
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
struct mntent *mnt;
FILE *fd;
@@ -481,7 +510,7 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version)
Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
****************************************************************************/
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
uid_t euser_id;
int ret;
@@ -641,7 +670,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
try to get the disk space from disk quotas - OSF1 version
****************************************************************************/
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
int r, save_errno;
struct dqblk D;
@@ -707,7 +736,7 @@ try to get the disk space from disk quotas (IRIX 6.2 version)
#include <sys/quota.h>
#include <mntent.h>
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
uid_t euser_id;
int r;
@@ -845,7 +874,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
try to get the disk space from disk quotas - default version
****************************************************************************/
-BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
int r;
struct dqblk D;
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index ffcbe6d8986..0d89adf25b6 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -28,7 +28,6 @@
/* look in server.c for some explanation of these variables */
extern int Protocol;
-extern int DEBUGLEVEL;
extern int max_send;
extern int max_recv;
extern char magic_char;
@@ -80,8 +79,8 @@ int reply_special(char *inbuf,char *outbuf)
switch (msg_type) {
case 0x81: /* session request */
- CVAL(outbuf,0) = 0x82;
- CVAL(outbuf,3) = 0;
+ SCVAL(outbuf,0,0x82);
+ SCVAL(outbuf,3,0);
if (name_len(inbuf+4) > 50 ||
name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
DEBUG(0,("Invalid name length in session request\n"));
@@ -114,7 +113,7 @@ int reply_special(char *inbuf,char *outbuf)
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
no thanks! */
- CVAL(outbuf, 0) = 0x83;
+ SCVAL(outbuf, 0, 0x83);
break;
}
@@ -127,16 +126,15 @@ int reply_special(char *inbuf,char *outbuf)
reload_services(True);
reopen_logs();
- if (lp_status(-1)) {
- claim_connection(NULL,"",MAXSTATUS,True);
- }
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
break;
case 0x89: /* session keepalive request
(some old clients produce this?) */
- CVAL(outbuf,0) = 0x85;
- CVAL(outbuf,3) = 0;
+ SCVAL(outbuf,0,0x85);
+ SCVAL(outbuf,3,0);
break;
case 0x82: /* positive session response */
@@ -161,12 +159,12 @@ int reply_special(char *inbuf,char *outbuf)
work out what error to give to a failed connection
********************************************************************/
-static int connection_error(char *inbuf,char *outbuf,int ecode)
+static int connection_error(char *outbuf, int ecode)
{
if (ecode == ERRnoipc || ecode == ERRnosuchshare)
- return(ERROR(ERRDOS,ecode));
-
- return(ERROR(ERRSRV,ecode));
+ return(ERROR_DOS(ERRDOS,ecode));
+
+ return(ERROR_DOS(ERRSRV,ecode));
}
/****************************************************************************
@@ -258,7 +256,7 @@ int reply_tcon(connection_struct *conn,
if (!conn) {
END_PROFILE(SMBtcon);
- return(connection_error(inbuf,outbuf,ecode));
+ return(connection_error(outbuf,ecode));
}
outsize = set_message(outbuf,2,0,True);
@@ -300,7 +298,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (passlen > MAX_PASS_LEN) {
overflow_attack(passlen);
- return(ERROR(ERRDOS,ERRbuftoosmall));
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
}
memcpy(password,smb_buf(inbuf),passlen);
@@ -321,7 +319,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
p = strchr(path+2,'\\');
if (!p) {
END_PROFILE(SMBtconX);
- return(ERROR(ERRDOS,ERRnosuchshare));
+ return(ERROR_DOS(ERRDOS,ERRnosuchshare));
}
fstrcpy(service,p+1);
}
@@ -368,7 +366,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (!conn) {
END_PROFILE(SMBtconX);
- return(connection_error(inbuf,outbuf,ecode));
+ return(connection_error(outbuf,ecode));
}
if (Protocol < PROTOCOL_NT1) {
@@ -416,7 +414,7 @@ int reply_unknown(char *inbuf,char *outbuf)
DEBUG(0,("unknown command type (%s): type=%d (0x%X)\n",
smb_fn_name(type), type, type));
- return(ERROR(ERRSRV,ERRunknownsmb));
+ return(ERROR_DOS(ERRSRV,ERRunknownsmb));
}
/****************************************************************************
@@ -442,7 +440,7 @@ int reply_ioctl(connection_struct *conn,
break;
default:
END_PROFILE(SMBioctl);
- return(ERROR(ERRSRV,ERRnosupport));
+ return(ERROR_DOS(ERRSRV,ERRnosupport));
}
outsize = set_message(outbuf,8,replysize+1,True);
@@ -466,7 +464,6 @@ int reply_ioctl(connection_struct *conn,
/****************************************************************************
Always return an error: it's just a matter of which one...
- FIXME: memory leak - no call to pdb_free_sam() --jerry
****************************************************************************/
static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
@@ -491,32 +488,38 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
} else {
if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
}
if (!smb_password_ok(sam_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd)) {
DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
}
acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct);
if (acct_ctrl & ACB_DOMTRUST) {
DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT,ERRDOS,1807));
}
if (acct_ctrl & ACB_SVRTRUST) {
DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT,ERRDOS,1809));
}
if (acct_ctrl & ACB_WSTRUST) {
DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT,ERRDOS,1808));
}
}
/* don't know what to do: indicate logon failure */
+ pdb_free_sam(sam_trust_acct);
return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRDOS,1326));
}
@@ -526,17 +529,18 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
int smb_create_user(char *unix_user, char *homedir)
{
- pstring add_script;
- int ret;
-
- pstrcpy(add_script, lp_adduser_script());
- if (! *add_script) return -1;
- all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
- if (homedir)
- all_string_sub(add_script, "%H", homedir, sizeof(pstring));
- ret = smbrun(add_script,NULL);
- DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
- return ret;
+ pstring add_script;
+ int ret;
+
+ pstrcpy(add_script, lp_adduser_script());
+ if (! *add_script)
+ return -1;
+ all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
+ if (homedir)
+ all_string_sub(add_script, "%H", homedir, sizeof(pstring));
+ ret = smbrun(add_script,NULL);
+ DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
+ return ret;
}
/****************************************************************************
@@ -545,15 +549,16 @@ int smb_create_user(char *unix_user, char *homedir)
static int smb_delete_user(char *unix_user)
{
- pstring del_script;
- int ret;
-
- pstrcpy(del_script, lp_deluser_script());
- if (! *del_script) return -1;
- all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
- ret = smbrun(del_script,NULL);
- DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
- return ret;
+ pstring del_script;
+ int ret;
+
+ pstrcpy(del_script, lp_deluser_script());
+ if (! *del_script)
+ return -1;
+ all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
+ ret = smbrun(del_script,NULL);
+ DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
+ return ret;
}
/****************************************************************************
@@ -611,19 +616,6 @@ static BOOL check_server_security(char *orig_user, char *domain, char *unix_user
if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True)))
smb_create_user(unix_user, NULL);
-
- if(lp_adduser_script() && pwd) {
- SMB_STRUCT_STAT st;
-
- /*
- * Also call smb_create_user if the users home directory
- * doesn't exist. Used with winbindd to allow the script to
- * create the home directory for a user mapped with winbindd.
- */
-
- if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
- smb_create_user(unix_user, pwd->pw_dir);
- }
}
return ret;
@@ -635,7 +627,7 @@ static BOOL check_server_security(char *orig_user, char *domain, char *unix_user
static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user,
char *smb_apasswd, int smb_apasslen,
- char *smb_ntpasswd, int smb_ntpasslen)
+ char *smb_ntpasswd, int smb_ntpasslen, NT_USER_TOKEN **pptoken)
{
BOOL ret = False;
BOOL user_exists = True;
@@ -650,7 +642,7 @@ static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user
ret = domain_client_validate(orig_user, domain,
smb_apasswd, smb_apasslen,
smb_ntpasswd, smb_ntpasslen,
- &user_exists);
+ &user_exists, pptoken);
if(ret) {
/*
@@ -712,6 +704,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
static BOOL done_sesssetup = False;
BOOL doencrypt = SMBENCRYPT();
fstring domain;
+ NT_USER_TOKEN *ptok = NULL;
+
START_PROFILE(SMBsesssetupX);
*smb_apasswd = 0;
@@ -724,7 +718,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
smb_apasslen = SVAL(inbuf,smb_vwv7);
if (smb_apasslen > MAX_PASS_LEN) {
overflow_attack(smb_apasslen);
- return(ERROR(ERRDOS,ERRbuftoosmall));
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
}
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
@@ -764,7 +758,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if (passlen1 > MAX_PASS_LEN) {
overflow_attack(passlen1);
- return(ERROR(ERRDOS,ERRbuftoosmall));
+ return(ERROR_DOS(ERRDOS,ERRbuftoosmall));
}
passlen1 = MIN(passlen1, MAX_PASS_LEN);
@@ -887,7 +881,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if (!*user && !*smb_apasswd && !*domain) {
DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
END_PROFILE(SMBsesssetupX);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
}
}
@@ -950,7 +944,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if (!guest && !check_server_security(orig_user, domain, user,
smb_apasswd, smb_apasslen, smb_ntpasswd, smb_ntpasslen) &&
!check_domain_security(orig_user, domain, user, smb_apasswd,
- smb_apasslen, smb_ntpasswd, smb_ntpasslen) &&
+ smb_apasslen, smb_ntpasswd, smb_ntpasslen, &ptok) &&
!check_hosts_equiv(user))
{
@@ -992,6 +986,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
{
if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
{
+ delete_nt_token(&ptok);
DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
END_PROFILE(SMBsesssetupX);
return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
@@ -1001,6 +996,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
{
if (smb_getpwnam(user,True))
{
+ delete_nt_token(&ptok);
DEBUG(1,("Rejecting user '%s': bad password\n", user));
END_PROFILE(SMBsesssetupX);
return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
@@ -1029,7 +1025,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if (!strequal(user,lp_guestaccount(-1)) &&
lp_servicenumber(user) < 0)
{
- add_home_service(user,get_user_home_dir(user));
+ add_home_service(user,get_user_service_home_dir(user));
}
@@ -1054,6 +1050,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
{
const struct passwd *pw = smb_getpwnam(user,False);
if (!pw) {
+ delete_nt_token(&ptok);
DEBUG(1,("Username %s is invalid on this system\n",user));
END_PROFILE(SMBsesssetupX);
return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
@@ -1068,13 +1065,14 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest);
+ sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest,&ptok);
+
+ delete_nt_token(&ptok);
if (sess_vuid == -1) {
- return(ERROR(ERRDOS,ERRnoaccess));
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
}
-
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
@@ -1116,29 +1114,16 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
ok = S_ISDIR(sbuf.st_mode);
}
- if (!ok)
- {
+ 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)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ if(errno == ENOENT) {
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
-#if 0
- /* Ugly - NT specific hack - maybe not needed ? (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-#endif
-
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1201,12 +1186,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!ok)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBgetatr);
return(UNIXERROR(ERRDOS,ERRbadfile));
}
@@ -1221,11 +1201,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SIVAL(outbuf,smb_vwv3,(uint32)size);
if (Protocol >= PROTOCOL_NT1) {
- char *p = strrchr(fname,'/');
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- if (!p) p = fname;
- if (!is_8_3(fname, True))
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | 0x40); /* IS_LONG_NAME */
}
DEBUG( 3, ( "getatr name=%s mode=%d size=%d\n", fname, mode, (uint32)size ) );
@@ -1264,12 +1240,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!ok)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBsetatr);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1387,7 +1358,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (strlen(directory) == 0)
pstrcpy(directory,"./");
memset((char *)status,'\0',21);
- CVAL(status,0) = dirtype;
+ SCVAL(status,0,dirtype);
}
else
{
@@ -1413,16 +1384,12 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
{
if(dptr_num == -2)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- END_PROFILE(SMBsearch);
+ set_bad_path_error(errno, bad_path);
+ END_PROFILE(SMBsearch);
return (UNIXERROR(ERRDOS,ERRnofids));
}
END_PROFILE(SMBsearch);
- return(ERROR(ERRDOS,ERRnofids));
+ return ERROR_DOS(ERRDOS,ERRnofids);
}
dptr_set_wcard(dptr_num, strdup(mask));
}
@@ -1471,7 +1438,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if ( (numentries == 0) || !ok)
{
- CVAL(outbuf,smb_rcls) = ERRDOS;
+ SCVAL(outbuf,smb_rcls,ERRDOS);
SSVAL(outbuf,smb_err,ERRnofiles);
dptr_close(&dptr_num);
}
@@ -1482,7 +1449,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if(ok && expect_close && numentries == 0 && status_len == 0)
{
- CVAL(outbuf,smb_rcls) = ERRDOS;
+ SCVAL(outbuf,smb_rcls,ERRDOS);
SSVAL(outbuf,smb_err,ERRnofiles);
/* Also close the dptr - we know it's gone */
dptr_close(&dptr_num);
@@ -1494,12 +1461,11 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SSVAL(outbuf,smb_vwv0,numentries);
SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
- CVAL(smb_buf(outbuf),0) = 5;
+ SCVAL(smb_buf(outbuf),0,5);
SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
if (Protocol >= PROTOCOL_NT1) {
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | 0x40); /* IS_LONG_NAME */
}
outsize += DIR_STRUCT_SIZE*numentries;
@@ -1536,7 +1502,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (status_len == 0) {
END_PROFILE(SMBfclose);
- return(ERROR(ERRSRV,ERRsrverror));
+ return ERROR_DOS(ERRSRV,ERRsrverror);
}
memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
@@ -1590,11 +1556,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (!fsp)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBopen);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1607,7 +1569,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
DEBUG(3,("attempt to open a directory %s\n",fname));
close_file(fsp,False);
END_PROFILE(SMBopen);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
outsize = set_message(outbuf,7,0,True);
@@ -1621,11 +1583,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
SSVAL(outbuf,smb_vwv6,rmode);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
END_PROFILE(SMBopen);
return(outsize);
}
@@ -1666,7 +1628,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
} else {
END_PROFILE(SMBopenX);
- return (ERROR(ERRSRV,ERRaccess));
+ return ERROR_DOS(ERRSRV,ERRaccess);
}
}
@@ -1685,11 +1647,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (!fsp)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBopenX);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1700,7 +1658,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (fmode & aDIR) {
close_file(fsp,False);
END_PROFILE(SMBopenX);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
/* If the caller set the extended oplock request bit
@@ -1722,11 +1680,11 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
*/
if (core_oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg, CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
set_message(outbuf,15,0,True);
@@ -1824,11 +1782,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (!fsp)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBcreate);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1837,11 +1791,11 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
SSVAL(outbuf,smb_vwv0,fsp->fnum);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
DEBUG( 2, ( "new file %s\n", fname ) );
DEBUG( 3, ( "mknew %s fd=%d dmode=%d umode=%o\n",
@@ -1898,10 +1852,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
close(tmpfd);
if (!fsp) {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBctemp);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
@@ -1923,11 +1874,11 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstrcpy(p,s);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
DEBUG( 2, ( "created temp file %s\n", fname ) );
DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
@@ -1937,27 +1888,36 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(outsize);
}
-
/*******************************************************************
-check if a user is allowed to delete a file
+ Check if a user is allowed to delete a file.
********************************************************************/
-static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
+
+static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
{
- SMB_STRUCT_STAT sbuf;
- int fmode;
+ SMB_STRUCT_STAT sbuf;
+ int fmode;
- if (!CAN_WRITE(conn)) return(False);
+ if (!CAN_WRITE(conn))
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
- if (conn->vfs_ops.lstat(conn,dos_to_unix(fname,False),&sbuf) != 0) return(False);
- fmode = dos_mode(conn,fname,&sbuf);
- if (fmode & aDIR) return(False);
- if (!lp_delete_readonly(SNUM(conn))) {
- if (fmode & aRONLY) return(False);
- }
- if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
- return(False);
- if (!check_file_sharing(conn,fname,False)) return(False);
- return(True);
+ if (conn->vfs_ops.lstat(conn,dos_to_unix(fname,False),&sbuf) != 0)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ fmode = dos_mode(conn,fname,&sbuf);
+ if (fmode & aDIR)
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ if (!lp_delete_readonly(SNUM(conn))) {
+ if (fmode & aRONLY)
+ return NT_STATUS_CANNOT_DELETE;
+ }
+
+ if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
+ return NT_STATUS_CANNOT_DELETE;
+
+ if (!check_file_sharing(conn,fname,False))
+ return NT_STATUS_SHARING_VIOLATION;
+
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -1965,14 +1925,13 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
code.
****************************************************************************/
-int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf,
- int dirtype, char *name)
+NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
{
pstring directory;
pstring mask;
char *p;
int count=0;
- int error = ERRnoaccess;
+ NTSTATUS error = NT_STATUS_OK;
BOOL has_wild;
BOOL exists=False;
BOOL bad_path = False;
@@ -2010,8 +1969,12 @@ int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf,
if (!has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
- if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory))
+ error = can_delete(directory,conn,dirtype);
+ if (!NT_STATUS_IS_OK(error)) return error;
+
+ if (vfs_unlink(conn,directory) == 0) {
count++;
+ }
if (!count)
exists = vfs_file_exist(conn,directory,&sbuf);
} else {
@@ -2026,43 +1989,33 @@ int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf,
We don't implement this yet XXXX
*/
- if (dirptr)
- {
- error = ERRbadfile;
+ if (dirptr) {
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
- while ((dname = ReadDirName(dirptr)))
- {
+ while ((dname = ReadDirName(dirptr))) {
pstring fname;
pstrcpy(fname,dname);
if(!mask_match(fname, mask, case_sensitive)) continue;
- error = ERRnoaccess;
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
- if (!can_delete(fname,conn,dirtype)) continue;
- if (!vfs_unlink(conn,fname)) count++;
+ error = can_delete(fname,conn,dirtype);
+ if (!NT_STATUS_IS_OK(error)) continue;
+ if (vfs_unlink(conn,fname) == 0) count++;
DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
}
CloseDir(dirptr);
}
}
- if (count == 0) {
- if (exists)
- return(ERROR(ERRDOS,error));
- else {
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,error));
- }
+ if (count == 0 && NT_STATUS_IS_OK(error)) {
+ error = map_nt_error_from_unix(errno);
}
- return 0;
+ return error;
}
/****************************************************************************
@@ -2074,6 +2027,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
int outsize = 0;
pstring name;
int dirtype;
+ NTSTATUS status;
START_PROFILE(SMBunlink);
dirtype = SVAL(inbuf,smb_vwv0);
@@ -2084,8 +2038,8 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
DEBUG(3,("reply_unlink : %s\n",name));
- outsize = unlink_internals(conn, inbuf, outbuf, dirtype, name);
- if(outsize == 0) {
+ status = unlink_internals(conn, dirtype, name);
+ if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status);
/*
* Win2k needs a changenotify request response before it will
@@ -2095,10 +2049,9 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
process_pending_change_notify_queue((time_t)0);
outsize = set_message(outbuf,0,0,True);
- }
END_PROFILE(SMBunlink);
- return(outsize);
+ return outsize;
}
/****************************************************************************
@@ -2108,7 +2061,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
void fail_readraw(void)
{
pstring errstr;
- slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)\n",
+ slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
strerror(errno) );
exit_server(errstr);
}
@@ -2119,7 +2072,7 @@ void fail_readraw(void)
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
- size_t maxcount,mincount;
+ ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
char *header = outbuf;
@@ -2210,9 +2163,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
if (size < sizeneeded) {
SMB_STRUCT_STAT st;
if (vfs_fstat(fsp,fsp->fd,&st) == 0)
- size = st.st_size;
- if (!fsp->can_write)
- fsp->size = size;
+ fsp->size = size = st.st_size;
}
if (startpos >= size)
@@ -2253,8 +2204,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
int outsize = 0;
SMB_OFF_T startpos;
size_t numtoread;
- int eclass;
- uint32 ecode;
+ NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBlockread);
@@ -2277,8 +2227,11 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
* for a write lock. JRA.
*/
- if(!do_lock( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK, &eclass, &ecode)) {
- if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
+ status = do_lock(fsp, conn, SVAL(inbuf,smb_pid),
+ (SMB_BIG_UINT)numtoread, (SMB_BIG_UINT)startpos, WRITE_LOCK);
+
+ if (NT_STATUS_V(status)) {
+ if (lp_blocking_locks(SNUM(conn))) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
@@ -2289,7 +2242,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
return -1;
}
END_PROFILE(SMBlockread);
- return (ERROR(eclass,ecode));
+ return ERROR_NT(status);
}
nread = read_file(fsp,data,startpos,numtoread);
@@ -2338,7 +2291,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
END_PROFILE(SMBread);
- return(ERROR(ERRDOS,ERRlock));
+ return ERROR_DOS(ERRDOS,ERRlock);
}
if (numtoread > 0)
@@ -2352,7 +2305,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
outsize += nread;
SSVAL(outbuf,smb_vwv0,nread);
SSVAL(outbuf,smb_vwv5,nread+3);
- CVAL(smb_buf(outbuf),0) = 1;
+ SCVAL(smb_buf(outbuf),0,1);
SSVAL(smb_buf(outbuf),1,nread);
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
@@ -2405,7 +2358,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
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(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
#endif /* LARGE_SMB_OFF_T */
@@ -2414,7 +2367,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
END_PROFILE(SMBreadX);
- return(ERROR(ERRDOS,ERRlock));
+ return ERROR_DOS(ERRDOS,ERRlock);
}
nread = read_file(fsp,data,startpos,smb_maxcnt);
@@ -2470,12 +2423,12 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
/* force the error type */
- CVAL(inbuf,smb_com) = SMBwritec;
- CVAL(outbuf,smb_com) = SMBwritec;
+ SCVAL(inbuf,smb_com,SMBwritec);
+ SCVAL(outbuf,smb_com,SMBwritec);
if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwritebraw);
- return(ERROR(ERRDOS,ERRlock));
+ return(ERROR_DOS(ERRDOS,ERRlock));
}
if (numtowrite>0)
@@ -2492,11 +2445,11 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
total_written = nwritten;
/* Return a message to the redirector to tell it to send more bytes */
- CVAL(outbuf,smb_com) = SMBwritebraw;
+ SCVAL(outbuf,smb_com,SMBwritebraw);
SSVALS(outbuf,smb_vwv0,-1);
outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_writebraw: send_smb failed.\n");
+ exit_server("reply_writebraw: send_smb failed.");
/* Now read the raw data into the buffer and write it */
if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
@@ -2508,7 +2461,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
/* Set up outbuf to return the correct return */
outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
+ SCVAL(outbuf,smb_com,SMBwritec);
SSVAL(outbuf,smb_vwv0,total_written);
if (numtowrite != 0) {
@@ -2533,7 +2486,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
if (nwritten < (ssize_t)numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
+ SCVAL(outbuf,smb_rcls,ERRHRD);
SSVAL(outbuf,smb_err,ERRdiskfull);
}
@@ -2572,8 +2525,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
size_t numtowrite;
SMB_OFF_T startpos;
char *data;
- int eclass;
- uint32 ecode;
+ NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
int outsize = 0;
START_PROFILE(SMBwriteunlock);
@@ -2585,9 +2537,10 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
startpos = IVAL(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
+ WRITE_LOCK,False)) {
END_PROFILE(SMBwriteunlock);
- return(ERROR(ERRDOS,ERRlock));
+ return ERROR_DOS(ERRDOS,ERRlock);
}
/* The special X/Open SMB protocol handling of
@@ -2606,9 +2559,11 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite, (SMB_BIG_UINT)startpos, &eclass, &ecode)) {
+ status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtowrite,
+ (SMB_BIG_UINT)startpos);
+ if (NT_STATUS_V(status)) {
END_PROFILE(SMBwriteunlock);
- return(ERROR(eclass,ecode));
+ return ERROR_NT(status);
}
outsize = set_message(outbuf,1,0,True);
@@ -2622,27 +2577,6 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
return(outsize);
}
-/****************************************************************************
- Return correct error for space allocation fail.
-****************************************************************************/
-
-int allocate_space_error(char *inbuf,char *outbuf, int errno_val)
-{
- errno = errno_val;
- if (!(global_client_caps & CAP_STATUS32))
- return (UNIXERROR(ERRHRD,ERRdiskfull));
-
- /* Use more specific WNT/W2K error codes. */
-#ifdef EDQUOT
- if (errno_val == ENOSPC || errno_val == EDQUOT) {
-#else
- if (errno_val == ENOSPC) {
-#endif
- return(ERROR(0,NT_STATUS_DISK_FULL));
- }
-
- return (UNIXERROR(ERRHRD,ERRdiskfull));
-}
/****************************************************************************
Reply to a write.
@@ -2650,68 +2584,76 @@ int allocate_space_error(char *inbuf,char *outbuf, int errno_val)
int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
{
- size_t numtowrite;
- ssize_t nwritten = -1;
- SMB_OFF_T startpos;
- char *data;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- int outsize = 0;
- START_PROFILE(SMBwrite);
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ SMB_OFF_T startpos;
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwrite);
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
- END_PROFILE(SMBwrite);
- return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
- }
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ END_PROFILE(SMBwrite);
+ return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
+ }
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
+ numtowrite = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL(inbuf,smb_vwv2);
+ data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
- END_PROFILE(SMBwrite);
- return(ERROR(ERRDOS,ERRlock));
- }
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwrite);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
- /* X/Open SMB protocol says that if smb_vwv1 is
- zero then the file size should be extended or
- truncated to the size given in smb_vwv[2-3] */
- if(numtowrite == 0) {
- /* This is actually an allocate call, not set EOF. JRA */
- nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
- if (nwritten < 0) {
- int ret = allocate_space_error(inbuf, outbuf, errno);
- END_PROFILE(SMBwrite);
- return ret;
- }
- } else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ /*
+ * X/Open SMB protocol says that if smb_vwv1 is
+ * zero then the file size should be extended or
+ * truncated to the size given in smb_vwv[2-3].
+ */
+
+ if(numtowrite == 0) {
+ /*
+ * This is actually an allocate call, and set EOF. JRA.
+ */
+ nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
+ if (nwritten < 0) {
+ END_PROFILE(SMBwrite);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
+ if (nwritten < 0) {
+ END_PROFILE(SMBwrite);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ } else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
- if (lp_syncalways(SNUM(conn)))
- sync_file(conn,fsp);
+ if (lp_syncalways(SNUM(conn)))
+ sync_file(conn,fsp);
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- END_PROFILE(SMBwrite);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ END_PROFILE(SMBwrite);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- outsize = set_message(outbuf,1,0,True);
+ outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,nwritten);
+ SSVAL(outbuf,smb_vwv0,nwritten);
- if (nwritten < (ssize_t)numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
+ if (nwritten < (ssize_t)numtowrite) {
+ SCVAL(outbuf,smb_rcls,ERRHRD);
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
- DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten));
+ DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
- END_PROFILE(SMBwrite);
- return(outsize);
+ END_PROFILE(SMBwrite);
+ return(outsize);
}
@@ -2746,7 +2688,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
END_PROFILE(SMBwriteX);
- return(ERROR(ERRDOS,ERRbadmem));
+ return ERROR_DOS(ERRDOS,ERRbadmem);
}
data = smb_base(inbuf) + smb_doff;
@@ -2768,7 +2710,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
END_PROFILE(SMBwriteX);
- return(ERROR(ERRDOS,ERRbadaccess));
+ return ERROR_DOS(ERRDOS,ERRbadaccess);
}
#endif /* LARGE_SMB_OFF_T */
@@ -2776,7 +2718,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteX);
- return(ERROR(ERRDOS,ERRlock));
+ return ERROR_DOS(ERRDOS,ERRlock);
}
/* X/Open SMB protocol says that, unlike SMBwrite
@@ -2800,7 +2742,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
if (nwritten < (ssize_t)numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
+ SCVAL(outbuf,smb_rcls,ERRHRD);
SSVAL(outbuf,smb_err,ERRdiskfull);
}
@@ -2963,7 +2905,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
if(!fsp || (fsp->conn != conn)) {
END_PROFILE(SMBclose);
- return(ERROR(ERRDOS,ERRbadfid));
+ return ERROR_DOS(ERRDOS,ERRbadfid);
}
if(fsp->is_directory || fsp->stat_open) {
@@ -2978,21 +2920,10 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
* Close ordinary file.
*/
int close_err;
+ pstring file_name;
- /*
- * If there was a modify time outstanding,
- * try and set it here.
- */
- if(fsp->pending_modtime)
- set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
-
- /*
- * Now take care of any time sent in the close.
- */
- mtime = make_unix_date3(inbuf+smb_vwv1);
-
- /* try and set the date */
- set_filetime(conn, fsp->fsp_name,mtime);
+ /* Save the name for time set in close. */
+ pstrcpy( file_name, fsp->fsp_name);
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
fsp->fd, fsp->fnum,
@@ -3009,6 +2940,16 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
END_PROFILE(SMBclose);
return (UNIXERROR(ERRHRD,ERRgeneral));
}
+
+ /*
+ * Now take care of any time sent in the close.
+ */
+
+ mtime = make_unix_date3(inbuf+smb_vwv1);
+
+ /* try and set the date */
+ set_filetime(conn, file_name, mtime);
+
}
END_PROFILE(SMBclose);
@@ -3043,7 +2984,7 @@ int reply_writeclose(connection_struct *conn,
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteclose);
- return(ERROR(ERRDOS,ERRlock));
+ return ERROR_DOS(ERRDOS,ERRlock);
}
nwritten = write_file(fsp,data,startpos,numtowrite);
@@ -3083,8 +3024,7 @@ int reply_lock(connection_struct *conn,
{
int outsize = set_message(outbuf,0,0,True);
SMB_BIG_UINT count,offset;
- int eclass;
- uint32 ecode;
+ NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBlock);
@@ -3098,8 +3038,9 @@ int reply_lock(connection_struct *conn,
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fd, fsp->fnum, (double)offset, (double)count));
- if (!do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK, &eclass, &ecode)) {
- if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
+ status = do_lock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, WRITE_LOCK);
+ if (NT_STATUS_V(status)) {
+ if (lp_blocking_locks(SNUM(conn))) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
@@ -3111,7 +3052,7 @@ int reply_lock(connection_struct *conn,
}
}
END_PROFILE(SMBlock);
- return (ERROR(eclass,ecode));
+ return ERROR_NT(status);
}
END_PROFILE(SMBlock);
@@ -3126,8 +3067,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in
{
int outsize = set_message(outbuf,0,0,True);
SMB_BIG_UINT count,offset;
- int eclass;
- uint32 ecode;
+ NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBunlock);
@@ -3136,9 +3076,10 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in
count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
- if(!do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset, &eclass, &ecode)) {
+ status = do_unlock(fsp, conn, SVAL(inbuf,smb_pid), count, offset);
+ if (NT_STATUS_V(status)) {
END_PROFILE(SMBunlock);
- return (ERROR(eclass,ecode));
+ return ERROR_NT(status);
}
DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
@@ -3164,7 +3105,7 @@ int reply_tdis(connection_struct *conn,
if (!conn) {
DEBUG(4,("Invalid connection in tdis\n"));
END_PROFILE(SMBtdis);
- return(ERROR(ERRSRV,ERRinvnid));
+ return ERROR_DOS(ERRSRV,ERRinvnid);
}
conn->used = False;
@@ -3206,7 +3147,7 @@ int reply_echo(connection_struct *conn,
smb_setlen(outbuf,outsize - 4);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_echo: send_smb failed.\n");
+ exit_server("reply_echo: send_smb failed.");
}
DEBUG(3,("echo %d times\n", smb_reverb));
@@ -3230,11 +3171,11 @@ int reply_printopen(connection_struct *conn,
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplopen);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
/* Open for exclusive use, write only. */
- fsp = print_fsp_open(conn);
+ fsp = print_fsp_open(conn, NULL);
if (!fsp) {
END_PROFILE(SMBsplopen);
@@ -3267,7 +3208,7 @@ int reply_printclose(connection_struct *conn,
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplclose);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
DEBUG(3,("printclose fd=%d fnum=%d\n",
@@ -3303,12 +3244,12 @@ int reply_printqueue(connection_struct *conn,
get it right (tridge) */
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplretq);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
SSVAL(outbuf,smb_vwv0,0);
SSVAL(outbuf,smb_vwv1,0);
- CVAL(smb_buf(outbuf),0) = 1;
+ SCVAL(smb_buf(outbuf),0,1);
SSVAL(smb_buf(outbuf),1,0);
DEBUG(3,("printqueue start_index=%d max_count=%d\n",
@@ -3316,8 +3257,9 @@ int reply_printqueue(connection_struct *conn,
{
print_queue_struct *queue = NULL;
+ print_status_struct status;
char *p = smb_buf(outbuf) + 3;
- int count = print_queue_status(SNUM(conn), &queue,NULL);
+ int count = print_queue_status(SNUM(conn), &queue, &status);
int num_to_get = ABS(max_count);
int first = (max_count>0?start_index:start_index+max_count+1);
int i;
@@ -3330,10 +3272,10 @@ int reply_printqueue(connection_struct *conn,
for (i=first;i<first+num_to_get;i++) {
put_dos_date2(p,0,queue[i].time);
- CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
+ SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
SSVAL(p,5, queue[i].job);
SIVAL(p,7,queue[i].size);
- CVAL(p,11) = 0;
+ SCVAL(p,11,0);
StrnCpy(p+12,queue[i].user,16);
p += 28;
}
@@ -3342,11 +3284,11 @@ int reply_printqueue(connection_struct *conn,
outsize = set_message(outbuf,2,28*count+3,False);
SSVAL(outbuf,smb_vwv0,count);
SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
- CVAL(smb_buf(outbuf),0) = 1;
+ SCVAL(smb_buf(outbuf),0,1);
SSVAL(smb_buf(outbuf),1,28*count);
}
- if (queue) free(queue);
+ SAFE_FREE(queue);
DEBUG(3,("%d entries returned in queue\n",count));
}
@@ -3369,7 +3311,7 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplwr);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
CHECK_FSP(fsp,conn);
@@ -3394,7 +3336,7 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
The guts of the mkdir command, split out so it may be called by the NT SMB
code.
****************************************************************************/
-int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory)
+NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
{
BOOL bad_path = False;
SMB_STRUCT_STAT sbuf;
@@ -3405,34 +3347,31 @@ int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring d
if (check_name(directory, conn))
ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
- if (ret < 0)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
}
- return ret;
+ return NT_STATUS_OK;
}
/****************************************************************************
- Reply to a mkdir
+ Reply to a mkdir.
****************************************************************************/
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring directory;
int outsize;
+ NTSTATUS status;
START_PROFILE(SMBmkdir);
pstrcpy(directory,smb_buf(inbuf) + 1);
- outsize=mkdir_internal(conn, inbuf, outbuf, directory);
- if(outsize == 0)
- outsize = set_message(outbuf,0,0,True);
+ status = mkdir_internal(conn, directory);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
+
+ outsize = set_message(outbuf,0,0,True);
DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
@@ -3600,11 +3539,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (!ok)
{
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ set_bad_path_error(errno, bad_path);
END_PROFILE(SMBrmdir);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -3683,26 +3618,26 @@ static BOOL resolve_wildcards(char *name1,char *name2)
}
/*******************************************************************
-check if a user is allowed to rename a file
+ Check if a user is allowed to rename a file.
********************************************************************/
-static BOOL can_rename(char *fname,connection_struct *conn)
+
+static NTSTATUS can_rename(char *fname,connection_struct *conn)
{
- SMB_STRUCT_STAT sbuf;
+ if (!CAN_WRITE(conn))
+ return NT_STATUS_ACCESS_DENIED;
- if (!CAN_WRITE(conn)) return(False);
+ if (!check_file_sharing(conn,fname,True))
+ return NT_STATUS_SHARING_VIOLATION;
- if (conn->vfs_ops.lstat(conn,dos_to_unix(fname,False),&sbuf) != 0) return(False);
- if (!check_file_sharing(conn,fname,True)) return(False);
- return(True);
+ return NT_STATUS_OK;
}
/****************************************************************************
The guts of the rename command, split out so it may be called by the NT SMB
code.
****************************************************************************/
-int rename_internals(connection_struct *conn,
- char *inbuf, char *outbuf, char *name,
- char *newname, BOOL replace_if_exists)
+
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BOOL replace_if_exists)
{
pstring directory;
pstring mask;
@@ -3712,11 +3647,9 @@ int rename_internals(connection_struct *conn,
BOOL bad_path1 = False;
BOOL bad_path2 = False;
int count=0;
- int error = ERRnoaccess;
- BOOL exists=False;
+ NTSTATUS error = NT_STATUS_OK;
BOOL rc = True;
SMB_STRUCT_STAT sbuf1, sbuf2;
- pstring zdirectory;
*directory = *mask = 0;
@@ -3758,6 +3691,9 @@ int rename_internals(connection_struct *conn,
has_wild = ms_has_wild(mask);
if (!has_wild) {
+ pstring zdirectory;
+ pstring znewname;
+
/*
* No wildcards - just process the one file.
*/
@@ -3776,7 +3712,8 @@ int rename_internals(connection_struct *conn,
pstrcpy(newname, tmpstr);
}
- DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
+ DEBUG(3,("rename_internals: case_sensitive = %d, case_preserve = %d, short case preserve = %d, \
+directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
case_sensitive, case_preserve, short_case_preserve, directory,
newname, newname_last_component, is_short_name));
@@ -3814,37 +3751,82 @@ int rename_internals(connection_struct *conn,
}
}
- pstrcpy(zdirectory, dos_to_unix(directory, False));
- if(replace_if_exists) {
- /*
- * NT SMB specific flag - rename can overwrite
- * file with the same name so don't check for
- * vfs_file_exist().
- */
- if(resolve_wildcards(directory,newname) &&
- can_rename(directory,conn) &&
- !conn->vfs_ops.rename(conn,zdirectory,
- dos_to_unix(newname,False)))
- count++;
- } else {
- if (resolve_wildcards(directory,newname) &&
- can_rename(directory,conn) &&
- !vfs_file_exist(conn,newname,NULL) &&
- !conn->vfs_ops.rename(conn,zdirectory,
- dos_to_unix(newname,False)))
- count++;
+ resolve_wildcards(directory,newname);
+
+ /*
+ * The source object must exist.
+ */
+
+ if (!vfs_object_exist(conn, directory, NULL)) {
+ DEBUG(3,("rename_internals: source doesn't exist doing rename %s -> %s\n",
+ directory,newname));
+
+ if (errno == ENOTDIR || errno == EISDIR || errno == ENOENT) {
+ /*
+ * Must return different errors depending on whether the parent
+ * directory existed or not.
+ */
+
+ p = strrchr(directory, '/');
+ if (!p)
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ *p = '\0';
+ if (vfs_object_exist(conn, directory, NULL))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ error = map_nt_error_from_unix(errno);
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+
+ return error;
}
- DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
- directory,newname));
-
- if (!count) exists = vfs_file_exist(conn,directory,NULL);
- if (!count && exists && vfs_file_exist(conn,newname,NULL)) {
- exists = True;
- error = ERRrename;
+ error = can_rename(directory,conn);
+
+ if (!NT_STATUS_IS_OK(error)) {
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+ return error;
}
+
+ pstrcpy(zdirectory, dos_to_unix(directory, False));
+ pstrcpy(znewname, dos_to_unix(newname,False));
+
+ /*
+ * If the src and dest names are identical - including case,
+ * don't do the rename, just return success.
+ */
+
+ if (strcsequal(zdirectory, znewname)) {
+ DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
+ return NT_STATUS_OK;
+ }
+
+ if(!replace_if_exists && vfs_object_exist(conn,newname,NULL)) {
+ DEBUG(3,("rename_internals: dest exists doing rename %s -> %s\n",
+ directory,newname));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ if(conn->vfs_ops.rename(conn,zdirectory, znewname) == 0) {
+ DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
+ directory,newname));
+ return NT_STATUS_OK;
+ }
+
+ if (errno == ENOTDIR || errno == EISDIR)
+ error = NT_STATUS_OBJECT_NAME_COLLISION;
+ else
+ error = map_nt_error_from_unix(errno);
+
+ DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
+ get_nt_error_msg(error), directory,newname));
+
+ return error;
} else {
+
/*
* Wildcards - process each file that matches.
*/
@@ -3856,7 +3838,7 @@ int rename_internals(connection_struct *conn,
dirptr = OpenDir(conn, directory, True);
if (dirptr) {
- error = ERRbadfile;
+ error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
@@ -3869,10 +3851,11 @@ int rename_internals(connection_struct *conn,
if(!mask_match(fname, mask, case_sensitive))
continue;
- error = ERRnoaccess;
+ error = NT_STATUS_ACCESS_DENIED;
slprintf(fname,sizeof(fname)-1,"%s/%s",directory,dname);
- if (!can_rename(fname,conn)) {
- DEBUG(6,("rename %s refused\n", fname));
+ error = can_rename(fname,conn);
+ if (!NT_STATUS_IS_OK(error)) {
+ DEBUG(6,("rename %s failed. Error %s\n", fname, get_nt_error_msg(error)));
continue;
}
pstrcpy(destname,newname);
@@ -3884,9 +3867,9 @@ int rename_internals(connection_struct *conn,
}
if (!replace_if_exists &&
- vfs_file_exist(conn,destname, NULL)) {
+ vfs_object_exist(conn,destname, NULL)) {
DEBUG(6,("file_exist %s\n", destname));
- error = 183;
+ error = NT_STATUS_OBJECT_NAME_COLLISION;
continue;
}
@@ -3898,20 +3881,12 @@ int rename_internals(connection_struct *conn,
CloseDir(dirptr);
}
}
-
- if (count == 0) {
- if (exists)
- return(ERROR(ERRDOS,error));
- else {
- if((errno == ENOENT) && (bad_path1 || bad_path2)) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,error));
- }
+
+ if (count == 0 && NT_STATUS_IS_OK(error)) {
+ error = map_nt_error_from_unix(errno);
}
- return 0;
+ return error;
}
/****************************************************************************
@@ -3920,34 +3895,34 @@ int rename_internals(connection_struct *conn,
int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- int outsize = 0;
- pstring name;
- pstring newname;
- START_PROFILE(SMBmv);
+ int outsize = 0;
+ pstring name;
+ pstring newname;
+ NTSTATUS status;
+ START_PROFILE(SMBmv);
- pstrcpy(name,smb_buf(inbuf) + 1);
- pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
+ pstrcpy(name,smb_buf(inbuf) + 1);
+ pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
- DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
+ DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
- outsize = rename_internals(conn, inbuf, outbuf, name, newname, False);
- if(outsize == 0) {
+ status = rename_internals(conn, name, newname, False);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
/*
- * Win2k needs a changenotify request response before it will
- * update after a rename..
- */
-
- process_pending_change_notify_queue((time_t)0);
-
- outsize = set_message(outbuf,0,0,True);
- }
+ * Win2k needs a changenotify request response before it will
+ * update after a rename..
+ */
+ process_pending_change_notify_queue((time_t)0);
+ outsize = set_message(outbuf,0,0,True);
- END_PROFILE(SMBmv);
- return(outsize);
+ END_PROFILE(SMBmv);
+ return(outsize);
}
/*******************************************************************
@@ -4014,6 +3989,10 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
close_file(fsp1,False);
+
+ /* Ensure the modtime is set correctly on the destination file. */
+ fsp2->pending_modtime = src_sbuf.st_mtime;
+
/*
* As we are opening fsp1 read-only we only expect
* an error on close on fsp2 if we are out of space.
@@ -4063,7 +4042,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
/* can't currently handle inter share copies XXXX */
DEBUG(3,("Rejecting inter-share copy\n"));
END_PROFILE(SMBcopy);
- return(ERROR(ERRSRV,ERRinvdevice));
+ return ERROR_DOS(ERRSRV,ERRinvdevice);
}
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
@@ -4076,19 +4055,19 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if ((flags&1) && target_is_directory) {
END_PROFILE(SMBcopy);
- return(ERROR(ERRDOS,ERRbadfile));
+ return ERROR_DOS(ERRDOS,ERRbadfile);
}
if ((flags&2) && !target_is_directory) {
END_PROFILE(SMBcopy);
- return(ERROR(ERRDOS,ERRbadpath));
+ return ERROR_DOS(ERRDOS,ERRbadpath);
}
if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
/* wants a tree copy! XXXX */
DEBUG(3,("Rejecting tree copy\n"));
END_PROFILE(SMBcopy);
- return(ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
p = strrchr(name,'/');
@@ -4170,7 +4149,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (exists) {
END_PROFILE(SMBcopy);
- return(ERROR(ERRDOS,error));
+ return ERROR_DOS(ERRDOS,error);
} else
{
if((errno == ENOENT) && (bad_path1 || bad_path2))
@@ -4204,7 +4183,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
snum = SNUM(conn);
if (!CAN_SETDIR(snum)) {
END_PROFILE(pathworks_setdir);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
pstrcpy(newdir,smb_buf(inbuf) + 1);
@@ -4221,11 +4200,11 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!ok) {
END_PROFILE(pathworks_setdir);
- return(ERROR(ERRDOS,ERRbadpath));
+ return ERROR_DOS(ERRDOS,ERRbadpath);
}
outsize = set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
+ SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
DEBUG(3,("setdir %s\n", newdir));
@@ -4242,7 +4221,7 @@ uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
if(!large_file_format)
return SVAL(data,SMB_LPID_OFFSET(data_offset));
else
- return SVAL(data,SMB_LARGE__LPID_OFFSET(data_offset));
+ return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
}
/****************************************************************************
@@ -4382,10 +4361,10 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
int32 lock_timeout = IVAL(inbuf,smb_vwv4);
int i;
char *data;
- uint32 ecode=0, dummy2;
- int eclass=0, dummy1;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
BOOL err;
+ NTSTATUS status;
+
START_PROFILE(SMBlockingX);
CHECK_FSP(fsp,conn);
@@ -4395,8 +4374,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
/* Check if this is an oplock break on a file
we have granted an oplock on.
*/
- if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
- {
+ if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
/* Client can insist on breaking to none. */
BOOL break_to_none = (oplocklevel == 0);
@@ -4407,18 +4385,17 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
* Make sure we have granted an exclusive or batch oplock on this file.
*/
- if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- {
+ if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
/* if this is a pure oplock break request then don't send a reply */
if (num_locks == 0 && num_ulocks == 0) {
- END_PROFILE(SMBlockingX);
+ END_PROFILE(SMBlockingX);
return -1;
} else {
- END_PROFILE(SMBlockingX);
- return ERROR(ERRDOS,ERRlock);
+ END_PROFILE(SMBlockingX);
+ return ERROR_DOS(ERRDOS,ERRlock);
}
}
@@ -4428,8 +4405,7 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
}
/* if this is a pure oplock break request then don't send a reply */
- if (num_locks == 0 && num_ulocks == 0)
- {
+ if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
if(CVAL(inbuf,smb_vwv0) != 0xff)
@@ -4459,15 +4435,16 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR(ERRDOS,ERRnoaccess);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
(double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
- if(!do_unlock(fsp,conn,lock_pid,count,offset, &eclass, &ecode)) {
+ status = do_unlock(fsp,conn,lock_pid,count,offset);
+ if (NT_STATUS_V(status)) {
END_PROFILE(SMBlockingX);
- return ERROR(eclass,ecode);
+ return ERROR_NT(status);
}
}
@@ -4490,15 +4467,16 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR(ERRDOS,ERRnoaccess);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s\n",
(double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
- if(!do_lock(fsp,conn,lock_pid, count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
- &eclass, &ecode)) {
- if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
+ status = do_lock(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))) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
@@ -4531,13 +4509,13 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR(ERRDOS,ERRnoaccess);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- do_unlock(fsp,conn,lock_pid,count,offset,&dummy1,&dummy2);
+ do_unlock(fsp,conn,lock_pid,count,offset);
}
END_PROFILE(SMBlockingX);
- return ERROR(eclass,ecode);
+ return ERROR_NT(status);
}
set_message(outbuf,2,0,True);
@@ -4549,8 +4527,86 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return chain_reply(inbuf,outbuf,length,bufsize);
}
+/* Back from the dead for OS/2..... JRA. */
+
/****************************************************************************
- reply to a SMBsetattrE
+ Reply to a SMBreadbmpx (read block multiplex) request
+****************************************************************************/
+
+int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+{
+ ssize_t nread = -1;
+ ssize_t total_read;
+ char *data;
+ SMB_OFF_T startpos;
+ int outsize;
+ size_t maxcount;
+ int max_per_packet;
+ size_t tcount;
+ int pad;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBreadBmpx);
+
+ /* this function doesn't seem to work - disable by default */
+ if (!lp_readbmpx()) {
+ END_PROFILE(SMBreadBmpx);
+ return ERROR_DOS(ERRSRV,ERRuseSTD);
+ }
+
+ outsize = set_message(outbuf,8,0,True);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_READ(fsp);
+ CHECK_ERROR(fsp);
+
+ startpos = IVAL(inbuf,smb_vwv1);
+ maxcount = SVAL(inbuf,smb_vwv3);
+
+ data = smb_buf(outbuf);
+ pad = ((long)data)%4;
+ if (pad)
+ pad = 4 - pad;
+ data += pad;
+
+ max_per_packet = bufsize-(outsize+pad);
+ tcount = maxcount;
+ total_read = 0;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK, False)) {
+ END_PROFILE(SMBreadBmpx);
+ return ERROR_DOS(ERRDOS,ERRlock);
+ }
+
+ do {
+ size_t N = MIN(max_per_packet,tcount-total_read);
+
+ nread = read_file(fsp,data,startpos,N);
+
+ if (nread <= 0)
+ nread = 0;
+
+ if (nread < (ssize_t)N)
+ tcount = total_read + nread;
+
+ set_message(outbuf,8,nread,False);
+ SIVAL(outbuf,smb_vwv0,startpos);
+ SSVAL(outbuf,smb_vwv2,tcount);
+ SSVAL(outbuf,smb_vwv6,nread);
+ SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
+
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_readbmpx: send_smb failed.");
+
+ total_read += nread;
+ startpos += nread;
+ } while (total_read < (ssize_t)tcount);
+
+ END_PROFILE(SMBreadBmpx);
+ return(-1);
+}
+
+/****************************************************************************
+ Reply to a SMBsetattrE.
****************************************************************************/
int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
@@ -4595,7 +4651,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
/* Set the date on this file */
if(file_utime(conn, fsp->fsp_name, &unix_times)) {
END_PROFILE(SMBsetattrE);
- return(ERROR(ERRDOS,ERRnoaccess));
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
}
DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
@@ -4606,8 +4662,199 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
+/* Back from the dead for OS/2..... JRA. */
+
+/****************************************************************************
+ Reply to a SMBwritebmpx (write block multiplex primary) request.
+****************************************************************************/
+
+int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+{
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t tcount;
+ BOOL write_through;
+ int smb_doff;
+ char *data;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBwriteBmpx);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+ CHECK_ERROR(fsp);
+
+ tcount = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL(inbuf,smb_vwv3);
+ write_through = BITSETW(inbuf+smb_vwv7,0);
+ numtowrite = SVAL(inbuf,smb_vwv10);
+ smb_doff = SVAL(inbuf,smb_vwv11);
+
+ data = smb_base(inbuf) + smb_doff;
+
+ /* If this fails we need to send an SMBwriteC response,
+ not an SMBwritebmpx - set this up now so we don't forget */
+ SCVAL(outbuf,smb_com,SMBwritec);
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
+ END_PROFILE(SMBwriteBmpx);
+ return(ERROR_DOS(ERRDOS,ERRlock));
+ }
+
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
+
+ if(nwritten < (ssize_t)numtowrite) {
+ END_PROFILE(SMBwriteBmpx);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
+
+ /* If the maximum to be written to this file
+ is greater than what we just wrote then set
+ up a secondary struct to be attached to this
+ fd, we will use this to cache error messages etc. */
+
+ if((ssize_t)tcount > nwritten) {
+ write_bmpx_struct *wbms;
+ if(fsp->wbmpx_ptr != NULL)
+ wbms = fsp->wbmpx_ptr; /* Use an existing struct */
+ else
+ wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
+
+ if(!wbms) {
+ DEBUG(0,("Out of memory in reply_readmpx\n"));
+ END_PROFILE(SMBwriteBmpx);
+ return(ERROR_DOS(ERRSRV,ERRnoresource));
+ }
+ wbms->wr_mode = write_through;
+ wbms->wr_discard = False; /* No errors yet */
+ wbms->wr_total_written = nwritten;
+ wbms->wr_errclass = 0;
+ wbms->wr_error = 0;
+ fsp->wbmpx_ptr = wbms;
+ }
+
+ /* We are returning successfully, set the message type back to
+ SMBwritebmpx */
+ SCVAL(outbuf,smb_com,SMBwriteBmpx);
+
+ outsize = set_message(outbuf,1,0,True);
+
+ SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
+
+ DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
+ fsp->fnum, (int)numtowrite, (int)nwritten ) );
+
+ if (write_through && tcount==nwritten) {
+ /* We need to send both a primary and a secondary response */
+ smb_setlen(outbuf,outsize - 4);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_writebmpx: send_smb failed.");
+
+ /* Now the secondary */
+ outsize = set_message(outbuf,1,0,True);
+ SCVAL(outbuf,smb_com,SMBwritec);
+ SSVAL(outbuf,smb_vwv0,nwritten);
+ }
+
+ END_PROFILE(SMBwriteBmpx);
+ return(outsize);
+}
+
+/****************************************************************************
+ Reply to a SMBwritebs (write block multiplex secondary) request.
+****************************************************************************/
+
+int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+{
+ size_t numtowrite;
+ ssize_t nwritten = -1;
+ int outsize = 0;
+ SMB_OFF_T startpos;
+ size_t tcount;
+ BOOL write_through;
+ int smb_doff;
+ char *data;
+ write_bmpx_struct *wbms;
+ BOOL send_response = False;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBwriteBs);
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+
+ tcount = SVAL(inbuf,smb_vwv1);
+ startpos = IVAL(inbuf,smb_vwv2);
+ numtowrite = SVAL(inbuf,smb_vwv6);
+ smb_doff = SVAL(inbuf,smb_vwv7);
+
+ data = smb_base(inbuf) + smb_doff;
+
+ /* We need to send an SMBwriteC response, not an SMBwritebs */
+ SCVAL(outbuf,smb_com,SMBwritec);
+
+ /* This fd should have an auxiliary struct attached,
+ check that it does */
+ wbms = fsp->wbmpx_ptr;
+ if(!wbms) {
+ END_PROFILE(SMBwriteBs);
+ return(-1);
+ }
+
+ /* If write through is set we can return errors, else we must cache them */
+ write_through = wbms->wr_mode;
+
+ /* Check for an earlier error */
+ if(wbms->wr_discard) {
+ END_PROFILE(SMBwriteBs);
+ return -1; /* Just discard the packet */
+ }
+
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(lp_syncalways(SNUM(conn)) || write_through)
+ sync_file(conn,fsp);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ if(write_through) {
+ /* We are returning an error - we can delete the aux struct */
+ SAFE_FREE(wbms);
+ fsp->wbmpx_ptr = NULL;
+ END_PROFILE(SMBwriteBs);
+ return(ERROR_DOS(ERRHRD,ERRdiskfull));
+ }
+ END_PROFILE(SMBwriteBs);
+ return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+ }
+
+ /* Increment the total written, if this matches tcount
+ we can discard the auxiliary struct (hurrah !) and return a writeC */
+ wbms->wr_total_written += nwritten;
+ if(wbms->wr_total_written >= tcount) {
+ if (write_through) {
+ outsize = set_message(outbuf,1,0,True);
+ SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
+ send_response = True;
+ }
+
+ SAFE_FREE(wbms);
+ fsp->wbmpx_ptr = NULL;
+ }
+
+ if(send_response) {
+ END_PROFILE(SMBwriteBs);
+ return(outsize);
+ }
+
+ END_PROFILE(SMBwriteBs);
+ return(-1);
+}
+
/****************************************************************************
- reply to a SMBgetattrE
+ Reply to a SMBgetattrE.
****************************************************************************/
int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c
index 03f307164d9..9a61a76f6fe 100644
--- a/source/smbd/sec_ctx.c
+++ b/source/smbd/sec_ctx.c
@@ -21,7 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern struct current_user current_user;
struct sec_ctx {
@@ -60,10 +59,8 @@ static BOOL become_uid(uid_t uid)
/* Set effective user id */
set_effective_uid(uid);
- current_user.uid = uid;
DO_PROFILE_INC(uid_changes);
-
return True;
}
@@ -89,8 +86,6 @@ static BOOL become_gid(gid_t gid)
/* Set effective group id */
set_effective_gid(gid);
- current_user.gid = gid;
-
return True;
}
@@ -157,14 +152,14 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups)
}
if ((ngroups = sys_getgroups(ngroups,groups)) == -1) {
- safe_free(groups);
+ SAFE_FREE(groups);
return -1;
}
(*p_ngroups) = ngroups;
(*p_groups) = groups;
- DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) );
+ DEBUG( 3, ( "get_current_groups: user is in %u groups: ", ngroups ) );
for (i = 0; i < ngroups; i++ ) {
DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
@@ -181,11 +176,10 @@ void delete_nt_token(NT_USER_TOKEN **pptoken)
{
if (*pptoken) {
NT_USER_TOKEN *ptoken = *pptoken;
- safe_free( ptoken->user_sids );
+ SAFE_FREE( ptoken->user_sids );
ZERO_STRUCTP(ptoken);
}
- safe_free(*pptoken);
- *pptoken = NULL;
+ SAFE_FREE(*pptoken);
}
/****************************************************************************
@@ -205,7 +199,7 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
ZERO_STRUCTP(token);
if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
- free(token);
+ SAFE_FREE(token);
return NULL;
}
@@ -248,8 +242,7 @@ BOOL initialise_groups(char *user, uid_t uid, gid_t gid)
prev_ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx - 1];
- safe_free(prev_ctx_p->groups);
- prev_ctx_p->groups = NULL;
+ SAFE_FREE(prev_ctx_p->groups);
prev_ctx_p->ngroups = 0;
get_current_groups(&prev_ctx_p->ngroups, &prev_ctx_p->groups);
@@ -340,7 +333,7 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
ctx_p->ngroups = ngroups;
- safe_free(ctx_p->groups);
+ SAFE_FREE(ctx_p->groups);
if (token && (token == ctx_p->token))
smb_panic("DUPLICATE_TOKEN");
@@ -397,7 +390,7 @@ BOOL pop_sec_ctx(void)
ctx_p->uid = (uid_t)-1;
ctx_p->gid = (gid_t)-1;
- safe_free(ctx_p->groups);
+ SAFE_FREE(ctx_p->groups);
ctx_p->ngroups = 0;
delete_nt_token(&ctx_p->token);
diff --git a/source/smbd/server.c b/source/smbd/server.c
index a8bccc548d9..b3b428a9b42 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -22,7 +22,6 @@
#include "includes.h"
pstring servicesf = CONFIGFILE;
-extern pstring debugf;
extern fstring global_myworkgroup;
extern pstring global_myname;
@@ -34,8 +33,6 @@ int last_message = -1;
/* a useful macro to debug the last message processed */
#define LAST_MESSAGE() smb_fn_name(last_message)
-extern int DEBUGLEVEL;
-
extern pstring user_socket_options;
#ifdef WITH_DFS
@@ -104,7 +101,7 @@ static BOOL open_sockets_inetd(void)
/****************************************************************************
open the socket communication
****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port)
+static BOOL open_sockets(BOOL is_daemon,BOOL interactive, int port)
{
int num_interfaces = iface_count();
int fd_listenset[FD_SETSIZE];
@@ -212,14 +209,14 @@ max can be %d\n",
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
- num = sys_select(FD_SETSIZE,&lfds,NULL);
+ num = sys_select(FD_SETSIZE,&lfds,NULL,NULL,NULL);
if (num == -1 && errno == EINTR) {
extern VOLATILE sig_atomic_t reload_after_sighup;
/* check for sighup processing */
if (reload_after_sighup) {
- unbecome_user();
+ change_to_root_user();
DEBUG(1,("Reloading services after SIGHUP\n"));
reload_services(False);
reload_after_sighup = False;
@@ -258,7 +255,10 @@ max can be %d\n",
strerror(errno)));
continue;
}
-
+
+ if (smbd_server_fd() != -1 && interactive)
+ return True;
+
if (smbd_server_fd() != -1 && sys_fork()==0) {
/* Child code ... */
@@ -365,7 +365,7 @@ BOOL reload_services(BOOL test)
reset_stat_cache();
/* this forces service parameters to be flushed */
- become_service(NULL,True);
+ set_current_service(NULL,True);
return(ret);
}
@@ -398,7 +398,7 @@ static BOOL dump_core(void)
{
char *p;
pstring dname;
- pstrcpy(dname,debugf);
+ pstrcpy(dname,lp_logfile());
if ((p=strrchr(dname,'/'))) *p=0;
pstrcat(dname,"/corefiles");
mkdir(dname,0700);
@@ -434,11 +434,11 @@ update the current smbd process count
static void decrement_smbd_process_count(void)
{
- int total_smbds;
+ int32 total_smbds;
if (lp_max_smbd_processes()) {
total_smbds = 0;
- tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
+ tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
}
}
@@ -454,7 +454,7 @@ void exit_server(char *reason)
if (!firsttime) exit(0);
firsttime = 0;
- unbecome_user();
+ change_to_root_user();
DEBUG(2,("Closing connections\n"));
conn_close_all();
@@ -462,9 +462,8 @@ void exit_server(char *reason)
invalidate_all_vuids();
/* delete our entry in the connections database. */
- if (lp_status(-1)) {
- yield_connection(NULL,"",MAXSTATUS);
- }
+ if (lp_status(-1))
+ yield_connection(NULL,"");
respond_to_all_remaining_local_messages();
decrement_smbd_process_count();
@@ -532,10 +531,11 @@ usage on the program
static void usage(char *pname)
{
- printf("Usage: %s [-DaoPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
+ printf("Usage: %s [-DaioPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
printf(" [-O socket options] [-s services file]\n");
- printf("\t-D Become a daemon\n");
+ printf("\t-D Become a daemon (default)\n");
printf("\t-a Append to log file (default)\n");
+ printf("\t-i Run interactive (not a daemon)\n");
printf("\t-o Overwrite log file, don't append\n");
printf("\t-h Print usage\n");
printf("\t-? Print usage\n");
@@ -557,10 +557,12 @@ static void usage(char *pname)
extern BOOL append_log;
/* shall I run as a daemon */
BOOL is_daemon = False;
+ BOOL interactive = False;
BOOL specified_logfile = False;
int port = SMB_PORT;
int opt;
extern char *optarg;
+ pstring logfile;
#ifdef HAVE_SET_AUTH_PARAMETERS
set_auth_parameters(argc,argv);
@@ -572,7 +574,7 @@ static void usage(char *pname)
argc--;
}
- while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?Vaof:")) )
+ while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dip:h?Vaof:")) )
switch (opt) {
case 'O':
pstrcpy(user_socket_options,optarg);
@@ -584,7 +586,8 @@ static void usage(char *pname)
case 'l':
specified_logfile = True;
- slprintf(debugf, sizeof(debugf)-1, "%s/log.smbd", optarg);
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", optarg);
+ lp_set_logfile(logfile);
break;
case 'a':
@@ -599,6 +602,10 @@ static void usage(char *pname)
is_daemon = True;
break;
+ case 'i':
+ interactive = True;
+ break;
+
case 'd':
if (*optarg == 'A')
DEBUGLEVEL = 10000;
@@ -638,12 +645,13 @@ static void usage(char *pname)
TimeInit();
if(!specified_logfile) {
- slprintf(debugf, sizeof(debugf)-1, "%s/log.smbd", LOGFILEBASE);
+ slprintf(logfile, sizeof(logfile)-1, "%s/log.smbd", LOGFILEBASE);
+ lp_set_logfile(logfile);
}
pstrcpy(remote_machine, "smbd");
- setup_logging(argv[0],False);
+ setup_logging(argv[0],interactive);
charset_initialise();
@@ -683,11 +691,12 @@ static void usage(char *pname)
umask(0);
init_sec_ctx();
+ init_conn_ctx();
reopen_logs();
- DEBUG(1,( "smbd version %s started.\n", VERSION));
- DEBUGADD(1,( "Copyright Andrew Tridgell 1992-1998\n"));
+ DEBUG(0,( "smbd version %s started.\n", VERSION));
+ DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n"));
DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
(int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
@@ -731,59 +740,66 @@ static void usage(char *pname)
DEBUG(3,( "loaded services\n"));
if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+ if (!interactive)
+ DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+
+ /*
+ * Setting is_daemon here prevents us from eventually calling
+ * the open_sockets_inetd()
+ */
+
is_daemon = True;
}
- if (is_daemon) {
+ if (is_daemon && !interactive) {
DEBUG( 3, ( "Becoming a daemon.\n" ) );
become_daemon();
}
- if (!directory_exist(lp_lockdir(), NULL)) {
+#if HAVE_SETPGID
+ /*
+ * If we're interactive we want to set our own process group for
+ * signal management.
+ */
+ if (interactive)
+ setpgid( (pid_t)0, (pid_t)0);
+#endif
+
+ if (!directory_exist(lp_lockdir(), NULL))
mkdir(lp_lockdir(), 0755);
- }
- if (is_daemon) {
+ if (is_daemon)
pidfile_create("smbd");
- }
- if (!message_init()) {
+ if (!message_init())
exit(1);
- }
/* Setup the main smbd so that we can get messages. */
- if (lp_status(-1)) {
- claim_connection(NULL,"",MAXSTATUS,True);
- }
+ if (lp_status(-1))
+ claim_connection(NULL,"",0,True);
/* Attempt to migrate from an old 2.0.x machine account file. */
- if (!migrate_from_old_password_file(global_myworkgroup)) {
+ if (!migrate_from_old_password_file(global_myworkgroup))
DEBUG(0,("Failed to migrate from old MAC file.\n"));
- }
- if (!open_sockets(is_daemon,port))
+ if (!open_sockets(is_daemon,interactive,port))
exit(1);
/*
- * everything after this point is run after the fork()
+ * Everything after this point is run after the fork().
*/
- if (!locking_init(0)) {
+ if (!locking_init(0))
exit(1);
- }
- if (!print_backend_init()) {
+ if (!print_backend_init())
exit(1);
- }
- if (!share_info_db_init()) {
+ if (!share_info_db_init())
exit(1);
- }
- if(!initialize_password_db(False)) {
+ if(!initialize_password_db(False))
exit(1);
- }
/* possibly reload the services file. */
reload_services(True);
@@ -799,14 +815,12 @@ static void usage(char *pname)
}
/* Setup oplocks */
- if (!init_oplocks()) {
+ if (!init_oplocks())
exit(1);
- }
/* Setup change notify */
- if (!init_change_notify()) {
+ if (!init_change_notify())
exit(1);
- }
smbd_process();
diff --git a/source/smbd/service.c b/source/smbd/service.c
index ffbdefbecb7..515bcc5c792 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern struct timeval smb_last_time;
extern int case_default;
extern BOOL case_preserve;
@@ -36,9 +34,10 @@ extern fstring remote_machine;
/****************************************************************************
-load parameters specific to a connection/service
+ Load parameters specific to a connection/service.
****************************************************************************/
-BOOL become_service(connection_struct *conn,BOOL do_chdir)
+
+BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
{
extern char magic_char;
static connection_struct *last_conn;
@@ -126,7 +125,7 @@ int find_service(char *service)
/* now handle the special case of a home directory */
if (iService < 0)
{
- char *phome_dir = get_user_home_dir(service);
+ char *phome_dir = get_user_service_home_dir(service);
if(!phome_dir)
{
@@ -135,7 +134,7 @@ int find_service(char *service)
* be a Windows to unix mapped user name.
*/
if(map_username(service))
- phome_dir = get_user_home_dir(service);
+ phome_dir = get_user_service_home_dir(service);
}
DEBUG(3,("checking for home directory %s gave %s\n",service,
@@ -214,8 +213,11 @@ int find_service(char *service)
/****************************************************************************
- make a connection to a service
+ Make a connection to a service. This function is designed to be called
+ AS ROOT and will return to being root on exit ! Modified current_user conn
+ and vuid elements.
****************************************************************************/
+
connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode)
{
int snum;
@@ -223,8 +225,16 @@ connection_struct *make_connection(char *service,char *user,char *password, int
BOOL guest = False;
BOOL force = False;
connection_struct *conn;
+ uid_t euid;
int ret;
+ /* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
+
+ if (!non_root_mode() && ((euid = geteuid()) != 0)) {
+ DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid ));
+ smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
+ }
+
strlower(service);
snum = find_service(service);
@@ -320,6 +330,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
return NULL;
}
+ add_session_user(user);
+
conn = conn_new();
if (!conn) {
DEBUG(0,("Couldn't find free connection.\n"));
@@ -339,7 +351,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->read_only = lp_readonly(snum);
-
{
pstring list;
StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
@@ -482,7 +493,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->groups = NULL;
/* Find all the groups this uid is in and
- store them. Used by become_user() */
+ store them. Used by change_to_user() */
initialise_groups(conn->user, conn->uid, conn->gid);
get_current_groups(&conn->ngroups,&conn->groups);
@@ -499,7 +510,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
conn->ngroups, conn->groups,
- guest);
+ guest, NULL);
/*
* New code to check if there's a share security descripter
@@ -516,7 +527,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
*ecode = ERRaccess;
DEBUG(0,( "make_connection: connection to %s denied due to security descriptor.\n",
service ));
- yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
return NULL;
} else {
@@ -528,7 +539,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!vfs_init(conn)) {
DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
- yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
return NULL;
}
@@ -542,31 +553,42 @@ connection_struct *make_connection(char *service,char *user,char *password, int
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
DEBUG(1,("preexec gave %d - failing connection\n", ret));
- yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
*ecode = ERRsrverror;
return NULL;
}
}
- if (!become_user(conn, conn->vuid)) {
+ if (!change_to_user(conn, conn->vuid)) {
DEBUG(0,("Can't become connected user!\n"));
- yield_connection(conn,
- lp_servicename(SNUM(conn)),
- lp_max_connections(SNUM(conn)));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
*ecode = ERRbadpw;
return NULL;
}
+ /* execute any "preexec = " line */
+ if (*lp_preexec(SNUM(conn))) {
+ pstring cmd;
+ pstrcpy(cmd,lp_preexec(SNUM(conn)));
+ standard_sub_conn(conn,cmd);
+ ret = smbrun(cmd,NULL);
+ if (ret != 0 && lp_preexec_close(SNUM(conn))) {
+ DEBUG(1,("preexec gave %d - failing connection\n", ret));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
+ conn_free(conn);
+ *ecode = ERRsrverror;
+ return NULL;
+ }
+ }
+
if (vfs_ChDir(conn,conn->connectpath) != 0) {
DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
remote_machine, conn->client_address,
conn->connectpath,strerror(errno)));
- unbecome_user();
- yield_connection(conn,
- lp_servicename(SNUM(conn)),
- lp_max_connections(SNUM(conn)));
+ change_to_root_user();
+ yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
*ecode = ERRnosuchshare;
return NULL;
@@ -585,23 +607,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int
}
#endif
- add_session_user(user);
-
- /* execute any "preexec = " line */
- if (*lp_preexec(SNUM(conn))) {
- pstring cmd;
- pstrcpy(cmd,lp_preexec(SNUM(conn)));
- standard_sub_conn(conn,cmd);
- ret = smbrun(cmd,NULL);
- if (ret != 0 && lp_preexec_close(SNUM(conn))) {
- DEBUG(1,("preexec gave %d - failing connection\n", ret));
- yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
- conn_free(conn);
- *ecode = ERRsrverror;
- return NULL;
- }
- }
-
/*
* Print out the 'connected as' stuff here as we need
* to know the effective uid and gid we will be using.
@@ -616,7 +621,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
}
/* we've finished with the sensitive stuff */
- unbecome_user();
+ change_to_root_user();
/* Add veto/hide lists */
if (!IS_IPC(conn) && !IS_PRINT(conn)) {
@@ -635,15 +640,15 @@ connection_struct *make_connection(char *service,char *user,char *password, int
return(conn);
}
-
/****************************************************************************
-close a cnum
+ Close a cnum
****************************************************************************/
+
void close_cnum(connection_struct *conn, uint16 vuid)
{
DirCacheFlush(SNUM(conn));
- unbecome_user();
+ change_to_root_user();
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
remote_machine,conn->client_address,
@@ -657,24 +662,21 @@ void close_cnum(connection_struct *conn, uint16 vuid)
}
- yield_connection(conn,
- lp_servicename(SNUM(conn)),
- lp_max_connections(SNUM(conn)));
+ yield_connection(conn, lp_servicename(SNUM(conn)));
file_close_conn(conn);
dptr_closecnum(conn);
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(conn)) &&
- become_user(conn, vuid)) {
+ change_to_user(conn, vuid)) {
pstring cmd;
pstrcpy(cmd,lp_postexec(SNUM(conn)));
standard_sub_conn(conn,cmd);
smbrun(cmd,NULL);
- unbecome_user();
}
- unbecome_user();
+ change_to_root_user();
/* execute any "root postexec = " line */
if (*lp_rootpostexec(SNUM(conn))) {
pstring cmd;
diff --git a/source/smbd/session.c b/source/smbd/session.c
index bf21677f566..7f057256cac 100644
--- a/source/smbd/session.c
+++ b/source/smbd/session.c
@@ -89,9 +89,12 @@ BOOL session_claim(uint16 vuid)
return False;
}
- hostname = client_name();
- if (strequal(hostname,"UNKNOWN"))
- hostname = client_addr();
+ /* Don't resolve the hostname in smbd as we can pause for a long
+ time while waiting for DNS timeouts to occur. The correct
+ place to do this is in the code that displays the session
+ information. */
+
+ hostname = client_addr();
fstrcpy(sessionid.username, vuser->user.unix_name);
fstrcpy(sessionid.hostname, hostname);
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 89515f6351e..bfa304605f6 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -2,9 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-1998
-
Extensively modified by Andrew Tridgell, 1995
+ Copyright (C) Jeremy Allison 1994-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
@@ -23,7 +22,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
extern int Protocol;
extern BOOL case_sensitive;
extern int smb_read_error;
@@ -38,275 +36,390 @@ extern pstring global_myname;
set correctly for the type of call.
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_trans2_replies(char *outbuf, int bufsize, char *params,
- int paramsize, char *pdata, int datasize)
+
+static int send_trans2_replies(char *outbuf, int bufsize, char *params, int paramsize, char *pdata, int datasize)
{
- /* As we are using a protocol > LANMAN1 then the max_send
- variable must have been set in the sessetupX call.
- This takes precedence over the max_xmit field in the
- global struct. These different max_xmit variables should
- be merged as this is now too confusing */
-
- extern int max_send;
- int data_to_send = datasize;
- int params_to_send = paramsize;
- int useable_space;
- char *pp = params;
- char *pd = pdata;
- int params_sent_thistime, data_sent_thistime, total_sent_thistime;
- int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
- int data_alignment_offset = 0;
-
- /* Initially set the wcnt area to be 10 - this is true for all
- trans2 replies */
- set_message(outbuf,10,0,True);
-
- /* If there genuinely are no parameters or data to send just send
- the empty packet */
- if(params_to_send == 0 && data_to_send == 0)
- {
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_trans2_replies: send_smb failed.\n");
- return 0;
- }
-
- /* When sending params and data ensure that both are nicely aligned */
- /* Only do this alignment when there is also data to send - else
- can cause NT redirector problems. */
- if (((params_to_send % 4) != 0) && (data_to_send != 0))
- data_alignment_offset = 4 - (params_to_send % 4);
-
- /* Space is bufsize minus Netbios over TCP header minus SMB header */
- /* The alignment_offset is to align the param bytes on an even byte
- boundary. NT 4.0 Beta needs this to work correctly. */
- useable_space = bufsize - ((smb_buf(outbuf)+
- alignment_offset+data_alignment_offset) -
- outbuf);
-
- /* useable_space can never be more than max_send minus the
- alignment offset. */
- useable_space = MIN(useable_space,
- max_send - (alignment_offset+data_alignment_offset));
-
-
- while (params_to_send || data_to_send)
- {
- /* Calculate whether we will totally or partially fill this packet */
- total_sent_thistime = params_to_send + data_to_send +
- alignment_offset + data_alignment_offset;
- /* We can never send more than useable_space */
- /*
- * Note that 'useable_space' does not include the alignment offsets,
- * but we must include the alignment offsets in the calculation of
- * the length of the data we send over the wire, as the alignment offsets
- * are sent here. Fix from Marc_Jacobsen@hp.com.
- */
- total_sent_thistime = MIN(total_sent_thistime, useable_space+
- alignment_offset + data_alignment_offset);
-
- set_message(outbuf, 10, total_sent_thistime, True);
-
- /* Set total params and data to be sent */
- SSVAL(outbuf,smb_tprcnt,paramsize);
- SSVAL(outbuf,smb_tdrcnt,datasize);
-
- /* Calculate how many parameters and data we can fit into
- this packet. Parameters get precedence */
-
- params_sent_thistime = MIN(params_to_send,useable_space);
- data_sent_thistime = useable_space - params_sent_thistime;
- data_sent_thistime = MIN(data_sent_thistime,data_to_send);
-
- SSVAL(outbuf,smb_prcnt, params_sent_thistime);
-
- /* smb_proff is the offset from the start of the SMB header to the
- parameter bytes, however the first 4 bytes of outbuf are
- the Netbios over TCP header. Thus use smb_base() to subtract
- them from the calculation */
-
- SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
-
- if(params_sent_thistime == 0)
- SSVAL(outbuf,smb_prdisp,0);
- else
- /* Absolute displacement of param bytes sent in this packet */
- SSVAL(outbuf,smb_prdisp,pp - params);
-
- SSVAL(outbuf,smb_drcnt, data_sent_thistime);
- if(data_sent_thistime == 0)
- {
- SSVAL(outbuf,smb_droff,0);
- SSVAL(outbuf,smb_drdisp, 0);
- }
- else
- {
- /* The offset of the data bytes is the offset of the
- parameter bytes plus the number of parameters being sent this time */
- SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
- smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
- SSVAL(outbuf,smb_drdisp, pd - pdata);
- }
-
- /* Copy the param bytes into the packet */
- if(params_sent_thistime)
- memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
- /* Copy in the data bytes */
- if(data_sent_thistime)
- memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
- data_alignment_offset,pd,data_sent_thistime);
-
- DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
- params_sent_thistime, data_sent_thistime, useable_space));
- DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
- params_to_send, data_to_send, paramsize, datasize));
-
- /* Send the packet */
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("send_trans2_replies: send_smb failed.\n");
-
- pp += params_sent_thistime;
- pd += data_sent_thistime;
-
- params_to_send -= params_sent_thistime;
- data_to_send -= data_sent_thistime;
-
- /* Sanity check */
- if(params_to_send < 0 || data_to_send < 0)
- {
- DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
- params_to_send, data_to_send));
- return -1;
- }
- }
-
- return 0;
-}
+ /* As we are using a protocol > LANMAN1 then the max_send
+ variable must have been set in the sessetupX call.
+ This takes precedence over the max_xmit field in the
+ global struct. These different max_xmit variables should
+ be merged as this is now too confusing */
+
+ extern int max_send;
+ int data_to_send = datasize;
+ int params_to_send = paramsize;
+ int useable_space;
+ char *pp = params;
+ char *pd = pdata;
+ int params_sent_thistime, data_sent_thistime, total_sent_thistime;
+ int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
+ int data_alignment_offset = 0;
+
+ /* Initially set the wcnt area to be 10 - this is true for all
+ trans2 replies */
+ set_message(outbuf,10,0,True);
+
+ /* If there genuinely are no parameters or data to send just send
+ the empty packet */
+
+ if(params_to_send == 0 && data_to_send == 0) {
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_trans2_replies: send_smb failed.");
+ return 0;
+ }
+
+ /* When sending params and data ensure that both are nicely aligned */
+ /* Only do this alignment when there is also data to send - else
+ can cause NT redirector problems. */
+
+ if (((params_to_send % 4) != 0) && (data_to_send != 0))
+ data_alignment_offset = 4 - (params_to_send % 4);
+
+ /* Space is bufsize minus Netbios over TCP header minus SMB header */
+ /* The alignment_offset is to align the param bytes on an even byte
+ boundary. NT 4.0 Beta needs this to work correctly. */
+
+ useable_space = bufsize - ((smb_buf(outbuf)+ alignment_offset+data_alignment_offset) - outbuf);
+
+ /* useable_space can never be more than max_send minus the alignment offset. */
+
+ useable_space = MIN(useable_space, max_send - (alignment_offset+data_alignment_offset));
+
+
+ while (params_to_send || data_to_send) {
+ /* Calculate whether we will totally or partially fill this packet */
+
+ total_sent_thistime = params_to_send + data_to_send + alignment_offset + data_alignment_offset;
+
+ /* We can never send more than useable_space */
+ /*
+ * Note that 'useable_space' does not include the alignment offsets,
+ * but we must include the alignment offsets in the calculation of
+ * the length of the data we send over the wire, as the alignment offsets
+ * are sent here. Fix from Marc_Jacobsen@hp.com.
+ */
+
+ total_sent_thistime = MIN(total_sent_thistime, useable_space+ alignment_offset + data_alignment_offset);
+
+ set_message(outbuf, 10, total_sent_thistime, True);
+
+ /* Set total params and data to be sent */
+ SSVAL(outbuf,smb_tprcnt,paramsize);
+ SSVAL(outbuf,smb_tdrcnt,datasize);
+
+ /* Calculate how many parameters and data we can fit into
+ this packet. Parameters get precedence */
+
+ params_sent_thistime = MIN(params_to_send,useable_space);
+ data_sent_thistime = useable_space - params_sent_thistime;
+ data_sent_thistime = MIN(data_sent_thistime,data_to_send);
+
+ SSVAL(outbuf,smb_prcnt, params_sent_thistime);
+
+ /* smb_proff is the offset from the start of the SMB header to the
+ parameter bytes, however the first 4 bytes of outbuf are
+ the Netbios over TCP header. Thus use smb_base() to subtract
+ them from the calculation */
+ SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
+
+ if(params_sent_thistime == 0)
+ SSVAL(outbuf,smb_prdisp,0);
+ else
+ /* Absolute displacement of param bytes sent in this packet */
+ SSVAL(outbuf,smb_prdisp,pp - params);
+
+ SSVAL(outbuf,smb_drcnt, data_sent_thistime);
+ if(data_sent_thistime == 0) {
+ SSVAL(outbuf,smb_droff,0);
+ SSVAL(outbuf,smb_drdisp, 0);
+ } else {
+ /* The offset of the data bytes is the offset of the
+ parameter bytes plus the number of parameters being sent this time */
+ SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
+ smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
+ SSVAL(outbuf,smb_drdisp, pd - pdata);
+ }
+
+ /* Copy the param bytes into the packet */
+
+ if(params_sent_thistime)
+ memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+
+ /* Copy in the data bytes */
+
+ if(data_sent_thistime)
+ memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
+ data_alignment_offset,pd,data_sent_thistime);
+
+ DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
+ params_sent_thistime, data_sent_thistime, useable_space));
+ DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
+ params_to_send, data_to_send, paramsize, datasize));
+
+ /* Send the packet */
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("send_trans2_replies: send_smb failed.");
+
+ pp += params_sent_thistime;
+ pd += data_sent_thistime;
+
+ params_to_send -= params_sent_thistime;
+ data_to_send -= data_sent_thistime;
+
+ /* Sanity check */
+
+ if(params_to_send < 0 || data_to_send < 0) {
+ DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
+ params_to_send, data_to_send));
+ return -1;
+ }
+ }
+
+ return 0;
+}
/****************************************************************************
- reply to a TRANSACT2_OPEN
+ Reply to a TRANSACT2_OPEN.
****************************************************************************/
-static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
- int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *params = *pparams;
- int16 open_mode = SVAL(params, 2);
- int16 open_attr = SVAL(params,6);
- BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
+ char *params = *pparams;
+ int16 open_mode;
+ int16 open_attr;
+ BOOL oplock_request;
#if 0
- BOOL return_additional_info = BITSETW(params,0);
- int16 open_sattr = SVAL(params, 4);
- time_t open_time = make_unix_date3(params+8);
+ BOOL return_additional_info;
+ int16 open_sattr;
+ time_t open_time;
#endif
- int16 open_ofun = SVAL(params,12);
- int32 open_size = IVAL(params,14);
- char *pname = &params[28];
- int16 namelen = strlen(pname)+1;
+ int16 open_ofun;
+ int32 open_size;
+ char *pname;
+ int16 namelen;
- pstring fname;
- mode_t unixmode;
- SMB_OFF_T size=0;
- int fmode=0,mtime=0,rmode;
- SMB_INO_T inode = 0;
- SMB_STRUCT_STAT sbuf;
- int smb_action = 0;
- BOOL bad_path = False;
- files_struct *fsp;
+ pstring fname;
+ mode_t unixmode;
+ SMB_OFF_T size=0;
+ int fmode=0,mtime=0,rmode;
+ SMB_INO_T inode = 0;
+ SMB_STRUCT_STAT sbuf;
+ int smb_action = 0;
+ BOOL bad_path = False;
+ files_struct *fsp;
+
+ /*
+ * Ensure we have enough parameters to perform the operation.
+ */
+
+ if (total_params < 29)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ open_mode = SVAL(params, 2);
+ open_attr = SVAL(params,6);
+ oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
+#if 0
+ return_additional_info = BITSETW(params,0);
+ open_sattr = SVAL(params, 4);
+ open_time = make_unix_date3(params+8);
+#endif
+ open_ofun = SVAL(params,12);
+ open_size = IVAL(params,14);
+ pname = &params[28];
+ namelen = strlen(pname)+1;
- StrnCpy(fname,pname,namelen);
+ StrnCpy(fname,pname,namelen);
- DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
- fname,open_mode, open_attr, open_ofun, open_size));
+ DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
+ fname,open_mode, open_attr, open_ofun, open_size));
- if (IS_IPC(conn)) {
- return(ERROR(ERRSRV,ERRaccess));
- }
+ if (IS_IPC(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
- /* XXXX we need to handle passed times, sattr and flags */
+ /* XXXX we need to handle passed times, sattr and flags */
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- unixmode = unix_mode(conn,open_attr | aARCH, fname);
+ if (!check_name(fname,conn)) {
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ unixmode = unix_mode(conn,open_attr | aARCH, fname);
- fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
+ fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
+ oplock_request, &rmode,&smb_action);
- if (!fsp)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(conn,fname,&sbuf);
- mtime = sbuf.st_mtime;
- inode = sbuf.st_ino;
- if (fmode & aDIR) {
- close_file(fsp,False);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Realloc the size of parameters and data we will return */
- params = Realloc(*pparams, 28);
- if( params == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- memset((char *)params,'\0',28);
- SSVAL(params,0,fsp->fnum);
- SSVAL(params,2,fmode);
- put_dos_date2(params,4, mtime);
- SIVAL(params,8, (uint32)size);
- SSVAL(params,12,rmode);
-
- if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- }
-
- SSVAL(params,18,smb_action);
- /*
- * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
- */
- SIVAL(params,20,inode);
+ if (!fsp) {
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ size = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ mtime = sbuf.st_mtime;
+ inode = sbuf.st_ino;
+ if (fmode & aDIR) {
+ close_file(fsp,False);
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
+
+ /* Realloc the size of parameters and data we will return */
+ params = Realloc(*pparams, 28);
+ if( params == NULL )
+ return(ERROR_DOS(ERRDOS,ERRnomem));
+ *pparams = params;
+
+ memset((char *)params,'\0',28);
+ SSVAL(params,0,fsp->fnum);
+ SSVAL(params,2,fmode);
+ put_dos_date2(params,4, mtime);
+ SIVAL(params,8, (uint32)size);
+ SSVAL(params,12,rmode);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn)))
+ smb_action |= EXTENDED_OPLOCK_GRANTED;
+
+ SSVAL(params,18,smb_action);
+
+ /*
+ * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
+ */
+ SIVAL(params,20,inode);
- /* Send the required number of replies */
- send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
+ /* Send the required number of replies */
+ send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
- return -1;
+ return -1;
}
/*********************************************************
-* Routine to check if a given string matches exactly.
-* as a special case a mask of "." does NOT match. That
-* is required for correct wildcard semantics
-* Case can be significant or not.
+ Routine to check if a given string matches exactly.
+ as a special case a mask of "." does NOT match. That
+ is required for correct wildcard semantics
+ Case can be significant or not.
**********************************************************/
+
static BOOL exact_match(char *str,char *mask, BOOL case_sig)
{
- if (mask[0] == '.' && mask[1] == 0) return False;
- if (case_sig) return strcmp(str,mask)==0;
+ if (mask[0] == '.' && mask[1] == 0)
+ return False;
+ if (case_sig)
+ return strcmp(str,mask)==0;
return strcasecmp(str,mask) == 0;
}
/****************************************************************************
- get a level dependent lanman2 dir entry.
+ Return the filetype for UNIX extensions.
****************************************************************************/
+
+static uint32 unix_filetype(mode_t mode)
+{
+ if(S_ISREG(mode))
+ return UNIX_TYPE_FILE;
+ else if(S_ISDIR(mode))
+ return UNIX_TYPE_DIR;
+#ifdef S_ISLNK
+ else if(S_ISLNK(mode))
+ return UNIX_TYPE_SYMLINK;
+#endif
+#ifdef S_ISCHR
+ else if(S_ISCHR(mode))
+ return UNIX_TYPE_CHARDEV;
+#endif
+#ifdef S_ISBLK
+ else if(S_ISBLK(mode))
+ return UNIX_TYPE_BLKDEV;
+#endif
+#ifdef S_ISFIFO
+ else if(S_ISFIFO(mode))
+ return UNIX_TYPE_FIFO;
+#endif
+#ifdef S_ISSOCK
+ else if(S_ISSOCK(mode))
+ return UNIX_TYPE_SOCKET;
+#endif
+
+ DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
+ return UNIX_TYPE_UNKNOWN;
+}
+
+/****************************************************************************
+ Return the major devicenumber for UNIX extensions.
+****************************************************************************/
+
+static uint32 unix_dev_major(SMB_DEV_T dev)
+{
+#if defined(HAVE_DEVICE_MAJOR_FN)
+ return (uint32)major(dev);
+#else
+ return (uint32)(dev >> 8);
+#endif
+}
+
+/****************************************************************************
+ Return the minor devicenumber for UNIX extensions.
+****************************************************************************/
+
+static uint32 unix_dev_minor(SMB_DEV_T dev)
+{
+#if defined(HAVE_DEVICE_MINOR_FN)
+ return (uint32)minor(dev);
+#else
+ return (uint32)(dev & 0xff);
+#endif
+}
+
+/****************************************************************************
+ Map wire perms onto standard UNIX permissions. Obey share restrictions.
+****************************************************************************/
+
+static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *pst, uint32 perms)
+{
+ mode_t ret = 0;
+
+ if (perms == SMB_MODE_NO_CHANGE)
+ return pst->st_mode;
+
+ ret |= ((perms & UNIX_X_OTH ) ? S_IXOTH : 0);
+ ret |= ((perms & UNIX_W_OTH ) ? S_IWOTH : 0);
+ ret |= ((perms & UNIX_R_OTH ) ? S_IROTH : 0);
+ ret |= ((perms & UNIX_X_GRP ) ? S_IXGRP : 0);
+ ret |= ((perms & UNIX_W_GRP ) ? S_IWGRP : 0);
+ ret |= ((perms & UNIX_R_GRP ) ? S_IRGRP : 0);
+ ret |= ((perms & UNIX_X_USR ) ? S_IXUSR : 0);
+ ret |= ((perms & UNIX_W_USR ) ? S_IWUSR : 0);
+ ret |= ((perms & UNIX_R_USR ) ? S_IRUSR : 0);
+#ifdef S_ISVTX
+ ret |= ((perms & UNIX_STICKY ) ? S_ISVTX : 0);
+#endif
+#ifdef S_ISGID
+ ret |= ((perms & UNIX_SET_GID ) ? S_ISGID : 0);
+#endif
+#ifdef S_ISUID
+ ret |= ((perms & UNIX_SET_UID ) ? S_ISVTX : 0);
+#endif
+
+ if (VALID_STAT(*pst) && S_ISDIR(pst->st_mode)) {
+ ret &= lp_dir_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_dir_mode(SNUM(conn));
+ } else {
+ /* Apply mode mask */
+ ret &= lp_create_mask(SNUM(conn));
+ /* Add in force bits */
+ ret |= lp_force_create_mode(SNUM(conn));
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ Get a level dependent lanman2 dir entry.
+****************************************************************************/
+
static BOOL get_lanman2_dir_entry(connection_struct *conn,
char *path_mask,int dirtype,int info_level,
int requires_resume_key,
@@ -315,975 +428,1093 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
BOOL *out_of_space, BOOL *got_exact_match,
int *last_name_off)
{
- char *dname;
- BOOL found = False;
- SMB_STRUCT_STAT sbuf;
- pstring mask;
- pstring pathreal;
- pstring fname;
- char *p, *pdata = *ppdata;
- uint32 reskey=0;
- int prev_dirpos=0;
- int mode=0;
- SMB_OFF_T size = 0;
- uint32 len;
- time_t mdate=0, adate=0, cdate=0;
- char *nameptr;
- BOOL was_8_3;
- int nt_extmode; /* Used for NT connections instead of mode */
- BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
-
- *fname = 0;
- *out_of_space = False;
- *got_exact_match = False;
-
- if (!conn->dirptr)
- return(False);
-
- p = strrchr(path_mask,'/');
- if(p != NULL)
- {
- if(p[1] == '\0')
- pstrcpy(mask,"*.*");
- else
- pstrcpy(mask, p+1);
- }
- else
- pstrcpy(mask, path_mask);
-
- while (!found)
- {
- BOOL got_match;
-
- /* Needed if we run out of space */
- prev_dirpos = TellDir(conn->dirptr);
- dname = ReadDirName(conn->dirptr);
-
- /*
- * Due to bugs in NT client redirectors we are not using
- * resume keys any more - set them to zero.
- * Check out the related comments in findfirst/findnext.
- * JRA.
- */
-
- reskey = 0;
-
- DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
- (long)conn->dirptr,TellDir(conn->dirptr)));
+ char *dname;
+ BOOL found = False;
+ SMB_STRUCT_STAT sbuf;
+ pstring mask;
+ pstring pathreal;
+ pstring fname;
+ char *p, *pdata = *ppdata;
+ uint32 reskey=0;
+ int prev_dirpos=0;
+ int mode=0;
+ SMB_OFF_T size = 0;
+ SMB_OFF_T allocation_size = 0;
+ uint32 len;
+ time_t mdate=0, adate=0, cdate=0;
+ char *nameptr;
+ BOOL was_8_3;
+ int nt_extmode; /* Used for NT connections instead of mode */
+ BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+
+ *fname = 0;
+ *out_of_space = False;
+ *got_exact_match = False;
+
+ if (!conn->dirptr)
+ return(False);
+
+ p = strrchr(path_mask,'/');
+ if(p != NULL) {
+ if(p[1] == '\0')
+ pstrcpy(mask,"*.*");
+ else
+ pstrcpy(mask, p+1);
+ } else
+ pstrcpy(mask, path_mask);
+
+ while (!found) {
+ BOOL got_match;
+
+ /* Needed if we run out of space */
+ prev_dirpos = TellDir(conn->dirptr);
+ dname = ReadDirName(conn->dirptr);
+
+ /*
+ * Due to bugs in NT client redirectors we are not using
+ * resume keys any more - set them to zero.
+ * Check out the related comments in findfirst/findnext.
+ * JRA.
+ */
+
+ reskey = 0;
+
+ DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
+ (long)conn->dirptr,TellDir(conn->dirptr)));
- if (!dname)
- return(False);
-
- pstrcpy(fname,dname);
-
- if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive))) {
- got_match = mask_match(fname, mask, case_sensitive);
- }
-
- if(!got_match && !is_8_3(fname, False)) {
-
- /*
- * It turns out that NT matches wildcards against
- * both long *and* short names. This may explain some
- * of the wildcard wierdness from old DOS clients
- * that some people have been seeing.... JRA.
- */
-
- pstring newname;
- pstrcpy( newname, fname);
- name_map_mangle( newname, True, False, SNUM(conn));
- if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
- got_match = mask_match(newname, mask, case_sensitive);
- }
-
- if(got_match)
- {
- BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
- if (dont_descend && !isdots)
- continue;
+ if (!dname)
+ return(False);
+
+ pstrcpy(fname,dname);
+
+ if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
+ got_match = mask_match(fname, mask, case_sensitive);
+
+ if(!got_match && !is_8_3(fname, False)) {
+
+ /*
+ * It turns out that NT matches wildcards against
+ * both long *and* short names. This may explain some
+ * of the wildcard wierdness from old DOS clients
+ * that some people have been seeing.... JRA.
+ */
+
+ pstring newname;
+ pstrcpy( newname, fname);
+ name_map_mangle( newname, True, False, SNUM(conn));
+ if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
+ got_match = mask_match(newname, mask, case_sensitive);
+ }
+
+ if(got_match) {
+ BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
+ if (dont_descend && !isdots)
+ continue;
- pstrcpy(pathreal,conn->dirpath);
- if(needslash)
- pstrcat(pathreal,"/");
- pstrcat(pathreal,dname);
- if (vfs_stat(conn,pathreal,&sbuf) != 0)
- {
- /* Needed to show the msdfs symlinks as directories */
- if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
- || !is_msdfs_link(conn, pathreal, NULL, NULL))
- {
- DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
- pathreal,strerror(errno)));
- continue;
- }
- else
- {
- DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
- sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
- }
- }
-
- mode = dos_mode(conn,pathreal,&sbuf);
-
- if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
- DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
- continue;
- }
-
- size = sbuf.st_size;
- mdate = sbuf.st_mtime;
- adate = sbuf.st_atime;
- cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
-
- if (lp_dos_filetime_resolution(SNUM(conn))) {
- cdate &= ~1;
- mdate &= ~1;
- adate &= ~1;
- }
-
- if(mode & aDIR)
- size = 0;
-
- DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
+ pstrcpy(pathreal,conn->dirpath);
+ if(needslash)
+ pstrcat(pathreal,"/");
+ pstrcat(pathreal,dname);
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ if (vfs_lstat(conn,pathreal,&sbuf) != 0) {
+ DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n",
+ pathreal,strerror(errno)));
+ continue;
+ }
+ } else if (vfs_stat(conn,pathreal,&sbuf) != 0) {
+ /* Needed to show the msdfs symlinks as directories */
+ if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
+ || !is_msdfs_link(conn, pathreal, NULL, NULL)) {
+ DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
+ pathreal,strerror(errno)));
+ continue;
+ } else {
+ DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
+ sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
+ }
+ }
+
+ mode = dos_mode(conn,pathreal,&sbuf);
+
+ if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
+ DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
+ continue;
+ }
+
+ size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
+ mdate = sbuf.st_mtime;
+ adate = sbuf.st_atime;
+ cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+
+ if (lp_dos_filetime_resolution(SNUM(conn))) {
+ cdate &= ~1;
+ mdate &= ~1;
+ adate &= ~1;
+ }
+
+ if(mode & aDIR)
+ size = 0;
+
+ DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
- found = True;
- }
- }
-
- name_map_mangle(fname,False,True,SNUM(conn));
-
- p = pdata;
- nameptr = p;
-
- nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
-
- switch (info_level)
- {
- case 1:
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- put_dos_date2(p,l1_fdateCreation,cdate);
- put_dos_date2(p,l1_fdateLastAccess,adate);
- put_dos_date2(p,l1_fdateLastWrite,mdate);
- SIVAL(p,l1_cbFile,(uint32)size);
- SIVAL(p,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
- SSVAL(p,l1_attrFile,mode);
- SCVAL(p,l1_cchName,strlen(fname));
- pstrcpy(p + l1_achName, fname);
- nameptr = p + l1_achName;
- p += l1_achName + strlen(fname) + 1;
- break;
-
- case 2:
- /* info_level 2 */
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- put_dos_date2(p,l2_fdateCreation,cdate);
- put_dos_date2(p,l2_fdateLastAccess,adate);
- put_dos_date2(p,l2_fdateLastWrite,mdate);
- SIVAL(p,l2_cbFile,(uint32)size);
- SIVAL(p,l2_cbFileAlloc,SMB_ROUNDUP(size,1024));
- SSVAL(p,l2_attrFile,mode);
- SIVAL(p,l2_cbList,0); /* No extended attributes */
- SCVAL(p,l2_cchName,strlen(fname));
- pstrcpy(p + l2_achName, fname);
- nameptr = p + l2_achName;
- p += l2_achName + strlen(fname) + 1;
- break;
-
- case 3:
- SIVAL(p,0,reskey);
- put_dos_date2(p,4,cdate);
- put_dos_date2(p,8,adate);
- put_dos_date2(p,12,mdate);
- SIVAL(p,16,(uint32)size);
- SIVAL(p,20,SMB_ROUNDUP(size,1024));
- SSVAL(p,24,mode);
- SIVAL(p,26,4);
- CVAL(p,30) = strlen(fname);
- pstrcpy(p+31, fname);
- nameptr = p+31;
- p += 31 + strlen(fname) + 1;
- break;
-
- case 4:
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- SIVAL(p,0,33+strlen(fname)+1);
- put_dos_date2(p,4,cdate);
- put_dos_date2(p,8,adate);
- put_dos_date2(p,12,mdate);
- SIVAL(p,16,(uint32)size);
- SIVAL(p,20,SMB_ROUNDUP(size,1024));
- SSVAL(p,24,mode);
- CVAL(p,32) = strlen(fname);
- pstrcpy(p + 33, fname);
- nameptr = p+33;
- p += 33 + strlen(fname) + 1;
- break;
-
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- was_8_3 = is_8_3(fname, True);
- len = 94+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,size);
- SOFF_T(p,8,size);
- p += 16;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- SIVAL(p,0,0); p += 4;
- if (!was_8_3) {
- fstrcpy(p+2,fname);
- if(!name_map_mangle(p+2,True,True,SNUM(conn)))
- (p+2)[12] = 0;
- strupper(p+2);
- SSVAL(p, 0, strlen(p+2));
- } else {
- SSVAL(p,0,0);
- *(p+2) = 0;
- }
- p += 2 + 24;
- /* nameptr = p; */
- pstrcpy(p,fname); p += strlen(p);
- p = pdata + len;
- break;
-
- case SMB_FIND_FILE_DIRECTORY_INFO:
- len = 64+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,size);
- SOFF_T(p,8,size);
- p += 16;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- pstrcpy(p,fname);
- p = pdata + len;
- break;
-
+ found = True;
+ }
+ }
+
+ name_map_mangle(fname,False,True,SNUM(conn));
+
+ p = pdata;
+ nameptr = p;
+
+ nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
+
+ switch (info_level) {
+ case 1:
+ if(requires_resume_key) {
+ SIVAL(p,0,reskey);
+ p += 4;
+ }
+ put_dos_date2(p,l1_fdateCreation,cdate);
+ put_dos_date2(p,l1_fdateLastAccess,adate);
+ put_dos_date2(p,l1_fdateLastWrite,mdate);
+ SIVAL(p,l1_cbFile,(uint32)size);
+ SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
+ SSVAL(p,l1_attrFile,mode);
+ SCVAL(p,l1_cchName,strlen(fname));
+ pstrcpy(p + l1_achName, fname);
+ nameptr = p + l1_achName;
+ p += l1_achName + strlen(fname) + 1;
+ break;
+
+ case 2:
+ if(requires_resume_key) {
+ SIVAL(p,0,reskey);
+ p += 4;
+ }
+ put_dos_date2(p,l2_fdateCreation,cdate);
+ put_dos_date2(p,l2_fdateLastAccess,adate);
+ put_dos_date2(p,l2_fdateLastWrite,mdate);
+ SIVAL(p,l2_cbFile,(uint32)size);
+ SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
+ SSVAL(p,l2_attrFile,mode);
+ SIVAL(p,l2_cbList,0); /* No extended attributes */
+ SCVAL(p,l2_cchName,strlen(fname));
+ pstrcpy(p + l2_achName, fname);
+ nameptr = p + l2_achName;
+ p += l2_achName + strlen(fname) + 1;
+ break;
+
+ case 3:
+ SIVAL(p,0,reskey);
+ put_dos_date2(p,4,cdate);
+ put_dos_date2(p,8,adate);
+ put_dos_date2(p,12,mdate);
+ SIVAL(p,16,(uint32)size);
+ SIVAL(p,20,(uint32)allocation_size);
+ SSVAL(p,24,mode);
+ SIVAL(p,26,4);
+ SCVAL(p,30,strlen(fname));
+ pstrcpy(p+31, fname);
+ nameptr = p+31;
+ p += 31 + strlen(fname) + 1;
+ break;
+
+ case 4:
+ if(requires_resume_key) {
+ SIVAL(p,0,reskey);
+ p += 4;
+ }
+ SIVAL(p,0,33+strlen(fname)+1);
+ put_dos_date2(p,4,cdate);
+ put_dos_date2(p,8,adate);
+ put_dos_date2(p,12,mdate);
+ SIVAL(p,16,(uint32)size);
+ SIVAL(p,20,(uint32)allocation_size);
+ SSVAL(p,24,mode);
+ SCVAL(p,32,strlen(fname));
+ pstrcpy(p + 33, fname);
+ nameptr = p+33;
+ p += 33 + strlen(fname) + 1;
+ break;
+
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+ was_8_3 = is_8_3(fname, True);
+ len = 94+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
+ SIVAL(p,0,reskey); p += 4;
+ put_long_date(p,cdate); p += 8;
+ put_long_date(p,adate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
+ SIVAL(p,0,nt_extmode); p += 4;
+ SIVAL(p,0,strlen(fname)); p += 4;
+ SIVAL(p,0,0); p += 4;
+ if (!was_8_3) {
+ fstrcpy(p+2,fname);
+ if(!name_map_mangle(p+2,True,True,SNUM(conn)))
+ (p+2)[12] = 0;
+ strupper(p+2);
+ SSVAL(p, 0, strlen(p+2));
+ } else {
+ SSVAL(p,0,0);
+ *(p+2) = 0;
+ }
+ p += 2 + 24;
+ /* nameptr = p; */
+ pstrcpy(p,fname); p += strlen(p);
+ p = pdata + len;
+ break;
+
+ case SMB_FIND_FILE_DIRECTORY_INFO:
+ len = 64+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
+ SIVAL(p,0,reskey); p += 4;
+ put_long_date(p,cdate); p += 8;
+ put_long_date(p,adate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
+ SIVAL(p,0,nt_extmode); p += 4;
+ SIVAL(p,0,strlen(fname)); p += 4;
+ pstrcpy(p,fname);
+ p = pdata + len;
+ break;
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- len = 68+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SOFF_T(p,0,size);
- SOFF_T(p,8,size);
- p += 16;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- SIVAL(p,0,0); p += 4;
- pstrcpy(p,fname);
- p = pdata + len;
- break;
-
- case SMB_FIND_FILE_NAMES_INFO:
- len = 12+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- pstrcpy(p,fname);
- p = pdata + len;
- break;
-
- default:
- return(False);
- }
-
-
- if (PTR_DIFF(p,pdata) > space_remaining) {
- /* Move the dirptr back to prev_dirpos */
- SeekDir(conn->dirptr, prev_dirpos);
- *out_of_space = True;
- DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
- return False; /* Not finished - just out of space */
- }
-
- /* Setup the last_filename pointer, as an offset from base_data */
- *last_name_off = PTR_DIFF(nameptr,base_data);
- /* Advance the data pointer to the next slot */
- *ppdata = p;
-
- return(found);
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ len = 68+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
+ SIVAL(p,0,reskey); p += 4;
+ put_long_date(p,cdate); p += 8;
+ put_long_date(p,adate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ put_long_date(p,mdate); p += 8;
+ SOFF_T(p,0,size);
+ SOFF_T(p,8,allocation_size);
+ p += 16;
+ SIVAL(p,0,nt_extmode); p += 4;
+ SIVAL(p,0,strlen(fname)); p += 4;
+ SIVAL(p,0,0); p += 4;
+ pstrcpy(p,fname);
+ p = pdata + len;
+ break;
+
+ case SMB_FIND_FILE_NAMES_INFO:
+ len = 12+strlen(fname);
+ len = (len + 3) & ~3;
+ SIVAL(p,0,len); p += 4;
+ SIVAL(p,0,reskey); p += 4;
+ SIVAL(p,0,strlen(fname)); p += 4;
+ pstrcpy(p,fname);
+ p = pdata + len;
+ break;
+
+ /* CIFS UNIX Extension. */
+
+ case SMB_FIND_FILE_UNIX:
+ len = 108+strlen(fname)+1; /* (length of SMB_QUERY_FILE_UNIX_BASIC = 100)+4+4+strlen(fname)*/
+ /* +1 to be sure to transmit the termination of fname */
+ len = (len + 3) & ~3;
+
+ SIVAL(p,0,len); p+= 4; /* Offset from this structure to the beginning of the next one */
+ SIVAL(p,0,reskey); p+= 4; /* Used for continuing search. */
+
+ /* Begin of SMB_QUERY_FILE_UNIX_BASIC */
+ SOFF_T(p,0,sbuf.st_size); /* 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,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
+#endif
+ p+= 8;
+
+ put_long_date(p,sbuf.st_ctime); /* Creation Time 64 Bit */
+ put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
+ put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
+ p+= 24;
+
+ SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ SIVAL(p,0,sbuf.st_gid); /* group id of owner */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ SIVAL(p,0,unix_filetype(sbuf.st_mode));
+ p+= 4;
+
+ SIVAL(p,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ SIVAL(p,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ SINO_T(p,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
+ p+= 8;
+
+ SIVAL(p,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ SIVAL(p,0,sbuf.st_nlink); /* number of hard links */
+ SIVAL(p,4,0);
+ p+= 8;
+
+ /* End of SMB_QUERY_FILE_UNIX_BASIC */
+ pstrcpy(p,fname);
+ p=pdata+len;
+
+ break;
+
+ default:
+ return(False);
+ }
+
+
+ if (PTR_DIFF(p,pdata) > space_remaining) {
+ /* Move the dirptr back to prev_dirpos */
+ SeekDir(conn->dirptr, prev_dirpos);
+ *out_of_space = True;
+ DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
+ return False; /* Not finished - just out of space */
+ }
+
+ /* Setup the last_filename pointer, as an offset from base_data */
+ *last_name_off = PTR_DIFF(nameptr,base_data);
+ /* Advance the data pointer to the next slot */
+ *ppdata = p;
+
+ return(found);
}
-
/****************************************************************************
Reply to a TRANS2_FINDFIRST.
****************************************************************************/
-static int call_trans2findfirst(connection_struct *conn,
- char *inbuf, char *outbuf, int bufsize,
- char **pparams, char **ppdata)
+static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- /* We must be careful here that we don't return more than the
- allowed number of data bytes. If this means returning fewer than
- maxentries then so be it. We assume that the redirector has
- enough room for the fixed number of parameter bytes it has
- requested. */
- uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *params = *pparams;
- char *pdata = *ppdata;
- int dirtype = SVAL(params,0);
- int maxentries = SVAL(params,2);
- BOOL close_after_first = BITSETW(params+4,0);
- BOOL close_if_end = BITSETW(params+4,1);
- BOOL requires_resume_key = BITSETW(params+4,2);
- int info_level = SVAL(params,6);
- pstring directory;
- pstring mask;
- char *p, *wcard;
- int last_name_off=0;
- int dptr_num = -1;
- int numentries = 0;
- int i;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
- int space_remaining;
- BOOL bad_path = False;
- SMB_STRUCT_STAT sbuf;
-
- *directory = *mask = 0;
-
- DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
- dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
- info_level, max_data_bytes));
+ /* We must be careful here that we don't return more than the
+ allowed number of data bytes. If this means returning fewer than
+ maxentries then so be it. We assume that the redirector has
+ enough room for the fixed number of parameter bytes it has
+ requested. */
+ uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ int dirtype;
+ int maxentries;
+ BOOL close_after_first;
+ BOOL close_if_end;
+ BOOL requires_resume_key;
+ int info_level;
+ pstring directory;
+ pstring mask;
+ char *p, *wcard;
+ int last_name_off=0;
+ int dptr_num = -1;
+ int numentries = 0;
+ int i;
+ BOOL finished = False;
+ BOOL dont_descend = False;
+ BOOL out_of_space = False;
+ int space_remaining;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+
+ if (total_params < 12)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ *directory = *mask = 0;
+
+ dirtype = SVAL(params,0);
+ maxentries = SVAL(params,2);
+ close_after_first = BITSETW(params+4,0);
+ close_if_end = BITSETW(params+4,1);
+ requires_resume_key = BITSETW(params+4,2);
+ info_level = SVAL(params,6);
+
+ DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, \
+close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
+ dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
+ info_level, max_data_bytes));
- switch (info_level)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- case SMB_FIND_FILE_DIRECTORY_INFO:
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- case SMB_FIND_FILE_NAMES_INFO:
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- pstrcpy(directory, params + 12); /* Complete directory path with
- wildcard mask appended */
-
- RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
-
- DEBUG(5,("path=%s\n",directory));
-
- unix_convert(directory,conn,0,&bad_path,&sbuf);
- if(!check_name(directory,conn)) {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
+ switch (info_level) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case SMB_FIND_FILE_DIRECTORY_INFO:
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ case SMB_FIND_FILE_NAMES_INFO:
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+ break;
+ case SMB_FIND_FILE_UNIX:
+ if (!lp_unix_extensions())
+ return(ERROR_DOS(ERRDOS,ERRunknownlevel));
+ break;
+ default:
+ return(ERROR_DOS(ERRDOS,ERRunknownlevel));
+ }
+
+ pstrcpy(directory, params + 12); /* Complete directory path with wildcard mask appended */
+
+ RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+
+ DEBUG(5,("path=%s\n",directory));
+
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+ if(!check_name(directory,conn)) {
+ set_bad_path_error(errno, bad_path);
#if 0
- /* Ugly - NT specific hack - maybe not needed ? (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
+ /* Ugly - NT specific hack - maybe not needed ? (JRA) */
+ if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && (get_remote_arch() == RA_WINNT)) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbaddirectory;
+ }
#endif
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
-
- p = strrchr(directory,'/');
- if(p == NULL) {
- pstrcpy(mask,directory);
- pstrcpy(directory,"./");
- } else {
- pstrcpy(mask,p+1);
- *p = 0;
- }
-
- DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
-
- pdata = Realloc(*ppdata, max_data_bytes + 1024);
- if( pdata == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
-
- /* Realloc the params space */
- params = Realloc(*pparams, 10);
- if( params == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
- return(UNIXERROR(ERRDOS,ERRbadfile));
-
- /* Save the wildcard match and attribs we are using on this directory -
- needed as lanman2 assumes these are being saved between calls */
-
- if(!(wcard = strdup(mask))) {
- dptr_close(&dptr_num);
- return(ERROR(ERRDOS,ERRnomem));
- }
-
- dptr_set_wcard(dptr_num, wcard);
- dptr_set_attr(dptr_num, dirtype);
-
- DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
-
- /* We don't need to check for VOL here as this is returned by
- a different TRANS2 call. */
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ p = strrchr(directory,'/');
+ if(p == NULL) {
+ pstrcpy(mask,directory);
+ pstrcpy(directory,"./");
+ } else {
+ pstrcpy(mask,p+1);
+ *p = 0;
+ }
+
+ DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
+
+ pdata = Realloc(*ppdata, max_data_bytes + 1024);
+ if( pdata == NULL )
+ return(ERROR_DOS(ERRDOS,ERRnomem));
+ *ppdata = pdata;
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
+
+ /* Realloc the params space */
+ params = Realloc(*pparams, 10);
+ if( params == NULL )
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
+
+ dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
+ if (dptr_num < 0)
+ return(UNIXERROR(ERRDOS,ERRbadfile));
+
+ /* Save the wildcard match and attribs we are using on this directory -
+ needed as lanman2 assumes these are being saved between calls */
+
+ if(!(wcard = strdup(mask))) {
+ dptr_close(&dptr_num);
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ }
+
+ dptr_set_wcard(dptr_num, wcard);
+ dptr_set_attr(dptr_num, dirtype);
+
+ DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
+
+ /* We don't need to check for VOL here as this is returned by
+ a different TRANS2 call. */
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
- dont_descend = True;
+ DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n", conn->dirpath,lp_dontdescend(SNUM(conn))));
+
+ if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
+ dont_descend = True;
- p = pdata;
- space_remaining = max_data_bytes;
- out_of_space = False;
-
- for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
- {
- BOOL got_exact_match = False;
-
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_name_off);
- }
-
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
-
- /*
- * As an optimisation if we know we aren't looking
- * for a wildcard name (ie. the name matches the wildcard exactly)
- * then we can finish on any (first) match.
- * This speeds up large directory searches. JRA.
- */
-
- if(got_exact_match)
- finished = True;
-
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ p = pdata;
+ space_remaining = max_data_bytes;
+ out_of_space = False;
+
+ for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
+ BOOL got_exact_match = False;
+
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+
+ if (space_remaining < DIRLEN_GUESS && numentries > 0) {
+ out_of_space = True;
+ finished = False;
+ } else {
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+ &last_name_off);
+ }
+
+ if (finished && out_of_space)
+ finished = False;
+
+ if (!finished && !out_of_space)
+ numentries++;
+
+ /*
+ * As an optimisation if we know we aren't looking
+ * for a wildcard name (ie. the name matches the wildcard exactly)
+ * then we can finish on any (first) match.
+ * This speeds up large directory searches. JRA.
+ */
+
+ if(got_exact_match)
+ finished = True;
+
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
- /* Check if we can close the dirptr */
- if(close_after_first || (finished && close_if_end))
- {
- DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
- dptr_close(&dptr_num);
- }
-
- /*
- * If there are no matching entries we must return ERRDOS/ERRbadfile -
- * from observation of NT.
- */
-
- if(numentries == 0)
- {
- dptr_close(&dptr_num);
- return(ERROR(ERRDOS,ERRbadfile));
- }
-
- /* At this point pdata points to numentries directory entries. */
-
- /* Set up the return parameter block */
- SSVAL(params,0,dptr_num);
- SSVAL(params,2,numentries);
- SSVAL(params,4,finished);
- SSVAL(params,6,0); /* Never an EA error */
- SSVAL(params,8,last_name_off);
-
- send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
-
- if ((! *directory) && dptr_path(dptr_num))
- slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
-
- DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask, directory, dirtype, numentries ) );
-
- /*
- * Force a name mangle here to ensure that the
- * mask as an 8.3 name is top of the mangled cache.
- * The reasons for this are subtle. Don't remove
- * this code unless you know what you are doing
- * (see PR#13758). JRA.
- */
-
- if(!is_8_3( mask, False))
- name_map_mangle(mask, True, True, SNUM(conn));
-
- return(-1);
-}
+ /* Check if we can close the dirptr */
+
+ if(close_after_first || (finished && close_if_end)) {
+ DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
+ dptr_close(&dptr_num);
+ }
+
+ /*
+ * If there are no matching entries we must return ERRDOS/ERRbadfile -
+ * from observation of NT.
+ */
+
+ if(numentries == 0) {
+ dptr_close(&dptr_num);
+ return ERROR_DOS(ERRDOS,ERRbadfile);
+ }
+
+ /* At this point pdata points to numentries directory entries. */
+
+ /* Set up the return parameter block */
+ SSVAL(params,0,dptr_num);
+ SSVAL(params,2,numentries);
+ SSVAL(params,4,finished);
+ SSVAL(params,6,0); /* Never an EA error */
+ SSVAL(params,8,last_name_off);
+
+ send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
+ if ((! *directory) && dptr_path(dptr_num))
+ slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
+
+ DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
+ smb_fn_name(CVAL(inbuf,smb_com)),
+ mask, directory, dirtype, numentries ) );
+
+ /*
+ * Force a name mangle here to ensure that the
+ * mask as an 8.3 name is top of the mangled cache.
+ * The reasons for this are subtle. Don't remove
+ * this code unless you know what you are doing
+ * (see PR#13758). JRA.
+ */
+
+ if(!is_8_3( mask, False))
+ name_map_mangle(mask, True, True, SNUM(conn));
+
+ return(-1);
+}
/****************************************************************************
- reply to a TRANS2_FINDNEXT
+ Reply to a TRANS2_FINDNEXT.
****************************************************************************/
-static int call_trans2findnext(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- /* We must be careful here that we don't return more than the
- allowed number of data bytes. If this means returning fewer than
- maxentries then so be it. We assume that the redirector has
- enough room for the fixed number of parameter bytes it has
- requested. */
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *params = *pparams;
- char *pdata = *ppdata;
- int dptr_num = SVAL(params,0);
- int maxentries = SVAL(params,2);
- uint16 info_level = SVAL(params,4);
- uint32 resume_key = IVAL(params,6);
- BOOL close_after_request = BITSETW(params+10,0);
- BOOL close_if_end = BITSETW(params+10,1);
- BOOL requires_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
- pstring resume_name;
- pstring mask;
- pstring directory;
- char *p;
- uint16 dirtype;
- int numentries = 0;
- int i, last_name_off=0;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
- int space_remaining;
-
- *mask = *directory = *resume_name = 0;
-
- pstrcpy( resume_name, params+12);
-
- DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
+ /* We must be careful here that we don't return more than the
+ allowed number of data bytes. If this means returning fewer than
+ maxentries then so be it. We assume that the redirector has
+ enough room for the fixed number of parameter bytes it has
+ requested. */
+ int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ int dptr_num;
+ int maxentries;
+ uint16 info_level;
+ uint32 resume_key;
+ BOOL close_after_request;
+ BOOL close_if_end;
+ BOOL requires_resume_key;
+ BOOL continue_bit;
+ pstring resume_name;
+ pstring mask;
+ pstring directory;
+ char *p;
+ uint16 dirtype;
+ int numentries = 0;
+ int i, last_name_off=0;
+ BOOL finished = False;
+ BOOL dont_descend = False;
+ BOOL out_of_space = False;
+ int space_remaining;
+
+ if (total_params < 12)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ dptr_num = SVAL(params,0);
+ maxentries = SVAL(params,2);
+ info_level = SVAL(params,4);
+ resume_key = IVAL(params,6);
+ close_after_request = BITSETW(params+10,0);
+ close_if_end = BITSETW(params+10,1);
+ requires_resume_key = BITSETW(params+10,2);
+ continue_bit = BITSETW(params+10,3);
+
+ *mask = *directory = *resume_name = 0;
+
+ pstrcpy( resume_name, params+12);
+
+ DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
close_after_request=%d, close_if_end = %d requires_resume_key = %d \
resume_key = %d resume name = %s continue=%d level = %d\n",
- dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
- requires_resume_key, resume_key, resume_name, continue_bit, info_level));
-
- switch (info_level)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- case SMB_FIND_FILE_DIRECTORY_INFO:
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- case SMB_FIND_FILE_NAMES_INFO:
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- pdata = Realloc( *ppdata, max_data_bytes + 1024);
- if(pdata == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
-
- /* Realloc the params space */
- params = Realloc(*pparams, 6*SIZEOFWORD);
- if( params == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- /* Check that the dptr is valid */
- if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
- return(ERROR(ERRDOS,ERRnofiles));
-
- string_set(&conn->dirpath,dptr_path(dptr_num));
-
- /* Get the wildcard mask from the dptr */
- if((p = dptr_wcard(dptr_num))== NULL) {
- DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
- return (ERROR(ERRDOS,ERRnofiles));
- }
- pstrcpy(mask, p);
- pstrcpy(directory,conn->dirpath);
-
- /* Get the attr mask from the dptr */
- dirtype = dptr_attr(dptr_num);
-
- DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
- dptr_num, mask, dirtype,
- (long)conn->dirptr,
- TellDir(conn->dirptr)));
-
- /* We don't need to check for VOL here as this is returned by
- a different TRANS2 call. */
-
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
- dont_descend = True;
+ dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
+ requires_resume_key, resume_key, resume_name, continue_bit, info_level));
+
+ switch (info_level) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case SMB_FIND_FILE_DIRECTORY_INFO:
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ case SMB_FIND_FILE_NAMES_INFO:
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+ break;
+ case SMB_FIND_FILE_UNIX:
+ if (!lp_unix_extensions())
+ return(ERROR_DOS(ERRDOS,ERRunknownlevel));
+ break;
+ default:
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ pdata = Realloc( *ppdata, max_data_bytes + 1024);
+ if(pdata == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ *ppdata = pdata;
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
+
+ /* Realloc the params space */
+ params = Realloc(*pparams, 6*SIZEOFWORD);
+ if( params == NULL )
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
+
+ /* Check that the dptr is valid */
+ if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
+ return ERROR_DOS(ERRDOS,ERRnofiles);
+
+ string_set(&conn->dirpath,dptr_path(dptr_num));
+
+ /* Get the wildcard mask from the dptr */
+ if((p = dptr_wcard(dptr_num))== NULL) {
+ DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
+ return ERROR_DOS(ERRDOS,ERRnofiles);
+ }
+ pstrcpy(mask, p);
+ pstrcpy(directory,conn->dirpath);
+
+ /* Get the attr mask from the dptr */
+ dirtype = dptr_attr(dptr_num);
+
+ DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
+ dptr_num, mask, dirtype, (long)conn->dirptr, TellDir(conn->dirptr)));
+
+ /* We don't need to check for VOL here as this is returned by
+ a different TRANS2 call. */
+
+ DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
+ if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
+ dont_descend = True;
- p = pdata;
- space_remaining = max_data_bytes;
- out_of_space = False;
-
- /*
- * Seek to the correct position. We no longer use the resume key but
- * depend on the last file name instead.
- */
- if(requires_resume_key && *resume_name && !continue_bit)
- {
- /*
- * Fix for NT redirector problem triggered by resume key indexes
- * changing between directory scans. We now return a resume key of 0
- * and instead look for the filename to continue from (also given
- * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
- * findfirst/findnext (as is usual) then the directory pointer
- * should already be at the correct place. Check this by scanning
- * backwards looking for an exact (ie. case sensitive) filename match.
- * If we get to the beginning of the directory and haven't found it then scan
- * forwards again looking for a match. JRA.
- */
-
- int current_pos, start_pos;
- char *dname = NULL;
- void *dirptr = conn->dirptr;
- start_pos = TellDir(dirptr);
- for(current_pos = start_pos; current_pos >= 0; current_pos--)
- {
- DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
-
- SeekDir(dirptr, current_pos);
- dname = ReadDirName(dirptr);
-
- /*
- * Remember, name_map_mangle is called by
- * get_lanman2_dir_entry(), so the resume name
- * could be mangled. Ensure we do the same
- * here.
- */
-
- if(dname != NULL)
- name_map_mangle( dname, False, True, SNUM(conn));
-
- if(dname && strcsequal( resume_name, dname))
- {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
- }
- }
-
- /*
- * Scan forward from start if not found going backwards.
- */
-
- if(current_pos < 0)
- {
- DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
- SeekDir(dirptr, start_pos);
- for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
- {
- /*
- * Remember, name_map_mangle is called by
- * get_lanman2_dir_entry(), so the resume name
- * could be mangled. Ensure we do the same
- * here.
- */
-
- if(dname != NULL)
- name_map_mangle( dname, False, True, SNUM(conn));
-
- if(dname && strcsequal( resume_name, dname))
- {
- SeekDir(dirptr, current_pos+1);
- DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
- break;
- }
- } /* end for */
- } /* end if current_pos */
- } /* end if requires_resume_key && !continue_bit */
-
- for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
- {
- BOOL got_exact_match = False;
-
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_name_off);
- }
-
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
-
- /*
- * As an optimisation if we know we aren't looking
- * for a wildcard name (ie. the name matches the wildcard exactly)
- * then we can finish on any (first) match.
- * This speeds up large directory searches. JRA.
- */
-
- if(got_exact_match)
- finished = True;
-
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ p = pdata;
+ space_remaining = max_data_bytes;
+ out_of_space = False;
+
+ /*
+ * Seek to the correct position. We no longer use the resume key but
+ * depend on the last file name instead.
+ */
+
+ if(requires_resume_key && *resume_name && !continue_bit) {
+
+ /*
+ * Fix for NT redirector problem triggered by resume key indexes
+ * changing between directory scans. We now return a resume key of 0
+ * and instead look for the filename to continue from (also given
+ * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
+ * findfirst/findnext (as is usual) then the directory pointer
+ * should already be at the correct place. Check this by scanning
+ * backwards looking for an exact (ie. case sensitive) filename match.
+ * If we get to the beginning of the directory and haven't found it then scan
+ * forwards again looking for a match. JRA.
+ */
+
+ int current_pos, start_pos;
+ char *dname = NULL;
+ void *dirptr = conn->dirptr;
+ start_pos = TellDir(dirptr);
+
+ for(current_pos = start_pos; current_pos >= 0; current_pos--) {
+ DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
+
+ SeekDir(dirptr, current_pos);
+ dname = ReadDirName(dirptr);
+
+ /*
+ * Remember, name_map_mangle is called by
+ * get_lanman2_dir_entry(), so the resume name
+ * could be mangled. Ensure we do the same
+ * here.
+ */
+
+ if(dname != NULL)
+ name_map_mangle( dname, False, True, SNUM(conn));
+
+ if(dname && strcsequal( resume_name, dname)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
+ }
+ }
+
+ /*
+ * Scan forward from start if not found going backwards.
+ */
+
+ if(current_pos < 0) {
+ DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
+ SeekDir(dirptr, start_pos);
+ for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos)) {
+
+ /*
+ * Remember, name_map_mangle is called by
+ * get_lanman2_dir_entry(), so the resume name
+ * could be mangled. Ensure we do the same
+ * here.
+ */
+
+ if(dname != NULL)
+ name_map_mangle( dname, False, True, SNUM(conn));
+
+ if(dname && strcsequal( resume_name, dname)) {
+ SeekDir(dirptr, current_pos+1);
+ DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
+ break;
+ }
+ } /* end for */
+ } /* end if current_pos */
+ } /* end if requires_resume_key && !continue_bit */
+
+ for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
+ BOOL got_exact_match = False;
+
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+
+ if (space_remaining < DIRLEN_GUESS && numentries > 0) {
+ out_of_space = True;
+ finished = False;
+ } else {
+ finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space, &got_exact_match,
+ &last_name_off);
+ }
+
+ if (finished && out_of_space)
+ finished = False;
+
+ if (!finished && !out_of_space)
+ numentries++;
+
+ /*
+ * As an optimisation if we know we aren't looking
+ * for a wildcard name (ie. the name matches the wildcard exactly)
+ * then we can finish on any (first) match.
+ * This speeds up large directory searches. JRA.
+ */
+
+ if(got_exact_match)
+ finished = True;
+
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
- /* Check if we can close the dirptr */
- if(close_after_request || (finished && close_if_end))
- {
- DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
- dptr_close(&dptr_num); /* This frees up the saved mask */
- }
+ /* Check if we can close the dirptr */
+ if(close_after_request || (finished && close_if_end)) {
+ DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
+ dptr_close(&dptr_num); /* This frees up the saved mask */
+ }
- /* Set up the return parameter block */
- SSVAL(params,0,numentries);
- SSVAL(params,2,finished);
- SSVAL(params,4,0); /* Never an EA error */
- SSVAL(params,6,last_name_off);
+ /* Set up the return parameter block */
+ SSVAL(params,0,numentries);
+ SSVAL(params,2,finished);
+ SSVAL(params,4,0); /* Never an EA error */
+ SSVAL(params,6,last_name_off);
- send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
+ send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
- if ((! *directory) && dptr_path(dptr_num))
- slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
+ if ((! *directory) && dptr_path(dptr_num))
+ slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
- DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask, directory, dirtype, numentries ) );
+ DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
+ smb_fn_name(CVAL(inbuf,smb_com)),
+ mask, directory, dirtype, numentries ) );
- return(-1);
+ return(-1);
}
/****************************************************************************
- reply to a TRANS2_QFSINFO (query filesystem info)
+ Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
-static int call_trans2qfsinfo(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, char **ppdata)
+static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *pdata = *ppdata;
- char *params = *pparams;
- uint16 info_level = SVAL(params,0);
- int data_len;
- SMB_STRUCT_STAT st;
- char *vname = volume_label(SNUM(conn));
- int snum = SNUM(conn);
- char *fstype = lp_fstype(SNUM(conn));
-
- DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
-
- if(vfs_stat(conn,".",&st)!=0) {
- DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
- return (ERROR(ERRSRV,ERRinvdevice));
- }
-
- pdata = Realloc(*ppdata, max_data_bytes + 1024);
- if ( pdata == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *ppdata = pdata;
- memset((char *)pdata,'\0',max_data_bytes + 1024);
-
- switch (info_level)
- {
- case 1:
- {
- SMB_BIG_UINT dfree,dsize,bsize;
- data_len = 18;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
- SIVAL(pdata,l1_idFileSystem,st.st_dev);
- SIVAL(pdata,l1_cSectorUnit,bsize/512);
- SIVAL(pdata,l1_cUnit,dsize);
- SIVAL(pdata,l1_cUnitAvail,dfree);
- SSVAL(pdata,l1_cbSector,512);
- DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
- (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
- (unsigned int)dfree, 512));
- break;
- }
- case 2:
- {
- /* Return volume name */
- int volname_len = MIN(strlen(vname),11);
- data_len = l2_vol_szVolLabel + volname_len + 1;
- /*
- * Add volume serial number - hash of a combination of
- * the called hostname and the service name.
- */
- SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
- SCVAL(pdata,l2_vol_cch,volname_len);
- StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
- DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
- (unsigned)st.st_ctime, volname_len,
- pdata+l2_vol_szVolLabel));
- break;
- }
- case SMB_QUERY_FS_ATTRIBUTE_INFO:
- {
- int fstype_len;
- SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- FILE_DEVICE_IS_MOUNTED|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
+ int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
+ char *pdata = *ppdata;
+ char *params = *pparams;
+ uint16 info_level;
+ int data_len;
+ SMB_STRUCT_STAT st;
+ char *vname = volume_label(SNUM(conn));
+ int snum = SNUM(conn);
+ char *fstype = lp_fstype(SNUM(conn));
+
+ if (total_params < 2)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ info_level = SVAL(params,0);
+ DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+
+ if(vfs_stat(conn,".",&st)!=0) {
+ DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
+ return ERROR_DOS(ERRSRV,ERRinvdevice);
+ }
+
+ pdata = Realloc(*ppdata, max_data_bytes + 1024);
+ if ( pdata == NULL )
+ return ERROR_DOS(ERRDOS,ERRnomem);
+
+ *ppdata = pdata;
+ memset((char *)pdata,'\0',max_data_bytes + 1024);
+
+ switch (info_level) {
+ case 1:
+ {
+ SMB_BIG_UINT dfree,dsize,bsize;
+ data_len = 18;
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SIVAL(pdata,l1_idFileSystem,st.st_dev);
+ SIVAL(pdata,l1_cSectorUnit,bsize/512);
+ SIVAL(pdata,l1_cUnit,dsize);
+ SIVAL(pdata,l1_cUnitAvail,dfree);
+ SSVAL(pdata,l1_cbSector,512);
+ DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
+ (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
+ (unsigned int)dfree, 512));
+ break;
+ }
+
+ case 2:
+ {
+ /* Return volume name */
+ int volname_len = MIN(strlen(vname),11);
+ data_len = l2_vol_szVolLabel + volname_len + 1;
+ /*
+ * Add volume serial number - hash of a combination of
+ * the called hostname and the service name.
+ */
+ SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
+ SCVAL(pdata,l2_vol_cch,volname_len);
+ StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
+ DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
+ (unsigned)st.st_ctime, volname_len,
+ pdata+l2_vol_szVolLabel));
+ break;
+ }
+
+ case SMB_QUERY_FS_ATTRIBUTE_INFO:
+ case SMB_FS_ATTRIBUTE_INFORMATION:
+ {
+ int fstype_len;
+ SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
+ (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
#if 0 /* Old code. JRA. */
- SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
- SIVAL(pdata,0,0x700FF);
+ SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
+ SIVAL(pdata,0,0x700FF);
#endif /* Old code. */
- SIVAL(pdata,4,255); /* Max filename component length */
- fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
- SIVAL(pdata,8,fstype_len);
- data_len = 12 + fstype_len;
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
- break;
- }
- case SMB_QUERY_FS_LABEL_INFO:
- data_len = 4 + strlen(vname);
- SIVAL(pdata,0,strlen(vname));
- pstrcpy(pdata+4,vname);
- break;
- case SMB_QUERY_FS_VOLUME_INFO:
-
- /*
- * Add volume serial number - hash of a combination of
- * the called hostname and the service name.
- */
- SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
- (str_checksum(local_machine)<<16));
-
- /* NT4 always serves this up as unicode but expects it to be
- * delivered as ascii! (tridge && JRA)
- */
- if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
- data_len = 18 + strlen(vname);
- SIVAL(pdata,12,strlen(vname));
- pstrcpy(pdata+18,vname);
- } else {
- int vnamelen;
-
- vnamelen = dos_PutUniCode(pdata+18, vname, sizeof(pstring), False);
- data_len = 18 + vnamelen;
- SIVAL(pdata,12,vnamelen);
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
- }
-
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
- (int)strlen(vname),vname));
- break;
- case SMB_QUERY_FS_SIZE_INFO:
- {
- SMB_BIG_UINT dfree,dsize,bsize;
- data_len = 24;
- conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
- SBIG_UINT(pdata,0,dsize);
- SBIG_UINT(pdata,8,dfree);
- SIVAL(pdata,16,bsize/512);
- SIVAL(pdata,20,512);
- break;
- }
- case SMB_QUERY_FS_DEVICE_INFO:
- data_len = 8;
- SIVAL(pdata,0,0); /* dev type */
- SIVAL(pdata,4,0); /* characteristics */
- break;
- case SMB_MAC_QUERY_FS_INFO:
- /*
- * Thursby MAC extension... ONLY on NTFS filesystems
- * once we do streams then we don't need this
- */
- if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
- data_len = 88;
- SIVAL(pdata,84,0x100); /* Don't support mac... */
- break;
- }
- /* drop through */
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
-
- send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
-
- DEBUG( 4, ( "%s info_level = %d\n",
- smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
-
- return -1;
+ SIVAL(pdata,4,255); /* Max filename component length */
+ /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
+ and will think we can't do long filenames */
+ fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
+ SIVAL(pdata,8,fstype_len);
+ data_len = 12 + fstype_len;
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ break;
+ }
+
+ case SMB_QUERY_FS_LABEL_INFO:
+ case SMB_FS_LABEL_INFORMATION:
+ data_len = 4 + strlen(vname);
+ SIVAL(pdata,0,strlen(vname));
+ pstrcpy(pdata+4,vname);
+ break;
+
+ case SMB_QUERY_FS_VOLUME_INFO:
+ case SMB_FS_VOLUME_INFORMATION:
+ /*
+ * Add volume serial number - hash of a combination of
+ * the called hostname and the service name.
+ */
+ SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
+ (str_checksum(local_machine)<<16));
+
+ /* NT4 always serves this up as unicode but expects it to be
+ * delivered as ascii! (tridge && JRA)
+ */
+ if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
+ data_len = 18 + strlen(vname);
+ SIVAL(pdata,12,strlen(vname));
+ pstrcpy(pdata+18,vname);
+ } else {
+ int vnamelen;
+
+ vnamelen = dos_PutUniCode(pdata+18, vname, sizeof(pstring), False);
+ data_len = 18 + vnamelen;
+ SIVAL(pdata,12,vnamelen);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ }
+
+ DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
+ (int)strlen(vname),vname));
+ break;
+
+ case SMB_QUERY_FS_SIZE_INFO:
+ case SMB_FS_SIZE_INFORMATION:
+ {
+ SMB_BIG_UINT dfree,dsize,bsize;
+ data_len = 24;
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SBIG_UINT(pdata,0,dsize);
+ SBIG_UINT(pdata,8,dfree);
+ SIVAL(pdata,16,bsize/512);
+ SIVAL(pdata,20,512);
+ break;
+ }
+
+ case SMB_FS_FULL_SIZE_INFORMATION:
+ {
+ SMB_BIG_UINT dfree,dsize,bsize;
+ data_len = 32;
+ conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
+ SBIG_UINT(pdata,0,dsize);
+ SBIG_UINT(pdata,8,dsize);
+ SBIG_UINT(pdata,16,dfree);
+ SIVAL(pdata,24,bsize/512);
+ SIVAL(pdata,28,512);
+ break;
+ }
+
+ case SMB_QUERY_FS_DEVICE_INFO:
+ case SMB_FS_DEVICE_INFORMATION:
+ data_len = 8;
+ SIVAL(pdata,0,0); /* dev type */
+ SIVAL(pdata,4,0); /* characteristics */
+ break;
+
+ case SMB_FS_OBJECTID_INFORMATION:
+ data_len = 64;
+ break;
+
+ /*
+ * Query the version and capabilities of the CIFS UNIX extensions
+ * in use.
+ */
+
+ case SMB_QUERY_CIFS_UNIX_INFO:
+
+ if (!lp_unix_extensions())
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+
+ data_len = 12;
+ SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
+ SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
+ SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
+ break;
+
+ case SMB_MAC_QUERY_FS_INFO:
+ /*
+ * Thursby MAC extension... ONLY on NTFS filesystems
+ * once we do streams then we don't need this
+ */
+ if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
+ data_len = 88;
+ SIVAL(pdata,84,0x100); /* Don't support mac... */
+ break;
+ }
+ /* drop through */
+ default:
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
+
+ DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
+
+ return -1;
}
/****************************************************************************
- reply to a TRANS2_SETFSINFO (set filesystem info)
+ Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
-static int call_trans2setfsinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- /* Just say yes we did it - there is nothing that
- can be set here so it doesn't matter. */
- int outsize;
- DEBUG(3,("call_trans2setfsinfo\n"));
+ /* Just say yes we did it - there is nothing that
+ can be set here so it doesn't matter. */
+ int outsize;
+ DEBUG(3,("call_trans2setfsinfo\n"));
+
+ if (!CAN_WRITE(conn))
+ return(ERROR_DOS(ERRSRV,ERRaccess));
- if (!CAN_WRITE(conn))
- return(ERROR(ERRSRV,ERRaccess));
+ outsize = set_message(outbuf,10,0,True);
- outsize = set_message(outbuf,10,0,True);
+ return outsize;
+}
+
+/****************************************************************************
+ Utility function to set bad path error.
+****************************************************************************/
- return outsize;
+void set_bad_path_error(int err, BOOL bad_path)
+{
+ if((err == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
}
/****************************************************************************
@@ -1291,11 +1522,8 @@ static int call_trans2setfsinfo(connection_struct *conn,
file name or file id).
****************************************************************************/
-static int call_trans2qfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams,char **ppdata,
- int total_data)
+static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
@@ -1304,10 +1532,12 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
uint16 info_level;
int mode=0;
SMB_OFF_T size=0;
+ SMB_OFF_T allocation_size=0;
unsigned int data_size;
SMB_STRUCT_STAT sbuf;
pstring fname1;
char *fname;
+ char *fullpathname;
char *p;
int l;
SMB_OFF_T pos = 0;
@@ -1316,7 +1546,12 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
time_t c_time;
if (tran_call == TRANSACT2_QFILEINFO) {
- files_struct *fsp = file_fsp(params,0);
+ files_struct *fsp;
+
+ 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));
@@ -1329,14 +1564,22 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
*/
fname = fsp->fsp_name;
unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+ if (!check_name(fname,conn)) {
+ DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (vfs_lstat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
+ } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1361,6 +1604,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
} else {
/* qpathinfo */
+ if (total_params < 6)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
info_level = SVAL(params,0);
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
@@ -1371,16 +1617,29 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ if (!check_name(fname,conn)) {
+ DEBUG(3,("call_trans2qfilepathinfo: check_name of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (vfs_lstat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_lstat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
}
+ } else if (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: vfs_stat of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
}
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+
DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
fname,info_level,tran_call,total_data));
@@ -1391,7 +1650,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
p++;
l = strlen(p);
mode = dos_mode(conn,fname,&sbuf);
+ fullpathname = fname;
size = sbuf.st_size;
+ allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
if (mode & aDIR)
size = 0;
@@ -1400,19 +1661,19 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
params = Realloc(*pparams,2);
if ( params == NULL )
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
*pparams = params;
memset((char *)params,'\0',2);
data_size = max_data_bytes + 1024;
pdata = Realloc(*ppdata, data_size);
if ( pdata == NULL )
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
*ppdata = pdata;
if (total_data > 0 && IVAL(pdata,0) == total_data) {
/* uggh, EAs for OS2 */
DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERReasnotsupported));
+ return ERROR_DOS(ERRDOS,ERReasnotsupported);
}
memset((char *)pdata,'\0',data_size);
@@ -1434,7 +1695,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
SIVAL(pdata,l1_cbFile,(uint32)size);
- SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
+ SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
break;
@@ -1445,7 +1706,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_dos_date2(pdata,4,sbuf.st_atime);
put_dos_date2(pdata,8,sbuf.st_mtime);
SIVAL(pdata,12,(uint32)size);
- SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
+ SIVAL(pdata,16,(uint32)allocation_size);
SIVAL(pdata,20,mode);
break;
@@ -1455,7 +1716,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case 6:
- return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
+ return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
case SMB_FILE_BASIC_INFORMATION:
case SMB_QUERY_FILE_BASIC_INFO:
@@ -1489,12 +1750,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_FILE_STANDARD_INFORMATION:
case SMB_QUERY_FILE_STANDARD_INFO:
- data_size = 22;
- SOFF_T(pdata,0,size);
+ data_size = 24;
+ /* Fake up allocation size. */
+ SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = 0;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
+ SCVAL(pdata,20,0);
+ SCVAL(pdata,21,(mode&aDIR)?1:0);
break;
case SMB_FILE_EA_INFORMATION:
@@ -1541,9 +1803,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
case SMB_FILE_ALLOCATION_INFORMATION:
- case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
+ data_size = 8;
+ SOFF_T(pdata,0,allocation_size);
+ break;
+
case SMB_QUERY_FILE_END_OF_FILEINFO:
+ case SMB_FILE_END_OF_FILE_INFORMATION:
data_size = 8;
SOFF_T(pdata,0,size);
break;
@@ -1555,11 +1821,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
SIVAL(pdata,32,mode);
pdata += 40;
- SOFF_T(pdata,0,size);
+ SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,size);
SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = delete_pending;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
+ SCVAL(pdata,20,delete_pending);
+ SCVAL(pdata,21,(mode&aDIR)?1:0);
pdata += 24;
SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
pdata += 8; /* index number */
@@ -1608,7 +1874,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_FILE_DISPOSITION_INFORMATION:
data_size = 1;
- CVAL(pdata,0) = delete_pending;
+ SCVAL(pdata,0,delete_pending);
break;
case SMB_FILE_POSITION_INFORMATION:
@@ -1668,7 +1934,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,0,0); /* ??? */
SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
SOFF_T(pdata,8,size);
- SIVAL(pdata,16,0x20); /* ??? */
+ SIVAL(pdata,16,allocation_size);
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
}
@@ -1686,7 +1952,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SOFF_T(pdata,32,(SMB_OFF_T)0x20); /* Allocation size. */
+ SOFF_T(pdata,32,allocation_size); /* Allocation size. */
SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
@@ -1703,20 +1969,112 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/*
* NT4 server just returns "invalid query" to this - if we try to answer
* it then NTws gets a BSOD! (tridge).
+ * W2K seems to want this. JRA.
*/
case SMB_QUERY_FILE_STREAM_INFO:
+ if (get_remote_arch() != RA_WIN2K)
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
data_size = 24 + l;
SIVAL(pdata,0,pos);
SIVAL(pdata,4,size);
- SIVAL(pdata,12,size);
+ SIVAL(pdata,12,allocation_size);
SIVAL(pdata,20,l);
pstrcpy(pdata+24,fname);
break;
#endif
+ /*
+ * CIFS UNIX Extensions.
+ */
+
+ case SMB_QUERY_FILE_UNIX_BASIC:
+
+ DEBUG(4,("call_trans2qfilepathinfo: st_mode=%o\n",(int)sbuf.st_mode));
+
+ SOFF_T(pdata,0,sbuf.st_size); /* 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,sbuf.st_size); /* Number of bytes used on disk - 64 Bit */
+#endif
+ pdata += 8;
+
+ put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
+ put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
+ put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
+ pdata += 24;
+
+ SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
+ SIVAL(pdata,4,0);
+ pdata += 8;
+
+ SIVAL(pdata,0,sbuf.st_gid); /* group id of owner */
+ SIVAL(pdata,4,0);
+ pdata += 8;
+
+ SIVAL(pdata,0,unix_filetype(sbuf.st_mode));
+ pdata += 4;
+
+ SIVAL(pdata,0,unix_dev_major(sbuf.st_rdev)); /* Major device number if type is device */
+ SIVAL(pdata,4,0);
+ pdata += 8;
+
+ SIVAL(pdata,0,unix_dev_minor(sbuf.st_rdev)); /* Minor device number if type is device */
+ SIVAL(pdata,4,0);
+ pdata += 8;
+
+ SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino); /* inode number */
+ pdata += 8;
+
+ SIVAL(pdata,0, unix_perms_to_wire(sbuf.st_mode)); /* Standard UNIX file permissions */
+ SIVAL(pdata,4,0);
+ pdata += 8;
+
+ SIVAL(pdata,0,sbuf.st_nlink); /* number of hard links */
+ SIVAL(pdata,4,0);
+ pdata += 8+1;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+
+ {
+ int i;
+ DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
+
+ for (i=0; i<100; i++)
+ DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
+ DEBUG(4,("\n"));
+ }
+
+ break;
+
+ case SMB_QUERY_FILE_UNIX_LINK:
+ {
+ pstring buffer;
+ int len;
+
+#ifdef S_ISLNK
+ if(!S_ISLNK(sbuf.st_mode))
+ return(UNIXERROR(ERRSRV,ERRbadlink));
+#else
+ return(UNIXERROR(ERRDOS,ErrNotALink));
+#endif
+ len = conn->vfs_ops.readlink(conn,dos_to_unix(fullpathname,False), buffer, sizeof(pstring)-1); /* read link */
+ if (len == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ buffer[len] = 0;
+ unix_to_dos(buffer,True);
+ pstrcpy(pdata,buffer); /* write '\0' terminated string */
+ pdata += strlen(buffer)+1;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+
+ break;
+ }
+
default:
- return(ERROR(ERRDOS,ERRunknownlevel));
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
@@ -1725,619 +2083,906 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
/****************************************************************************
- reply to a TRANS2_SETFILEINFO (set file info by fileid)
+ Deal with the internal needs of setting the delete on close flag. Note that
+ as the tdb locking is recursive, it is safe to call this from within
+ open_file_shared. JRA.
****************************************************************************/
-static int call_trans2setfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **pparams,
- char **ppdata, int total_data)
+
+NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
{
- char *params = *pparams;
- char *pdata = *ppdata;
- uint16 tran_call = SVAL(inbuf, smb_setup0);
- uint16 info_level;
- int mode=0;
- SMB_OFF_T size=0;
- struct utimbuf tvs;
- SMB_STRUCT_STAT sbuf;
- pstring fname1;
- char *fname = NULL;
- int fd = -1;
- BOOL bad_path = False;
- files_struct *fsp = NULL;
-
- if (tran_call == TRANSACT2_SETFILEINFO) {
- fsp = file_fsp(params,0);
- info_level = SVAL(params,2);
-
- if(fsp && (fsp->is_directory || fsp->stat_open)) {
- /*
- * This is actually a SETFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
- fname = fsp->fsp_name;
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- } else if (fsp && fsp->print_file) {
- /*
- * Doing a DELETE_ON_CLOSE should cancel a print job.
- */
- if (((info_level == SMB_SET_FILE_DISPOSITION_INFO)||(info_level == SMB_FILE_DISPOSITION_INFORMATION)) &&
- CVAL(pdata,0)) {
- fsp->share_mode = FILE_DELETE_ON_CLOSE;
-
- DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
- fsp->fsp_name ));
-
- SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
- return(-1);
- }
- } else {
- /*
- * Original code - this is an open file.
- */
- CHECK_FSP(fsp,conn);
-
- fname = fsp->fsp_name;
- fd = fsp->fd;
-
- if (vfs_fstat(fsp,fd,&sbuf) != 0) {
- DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
- }
- } else {
- /* set path info */
- info_level = SVAL(params,0);
- fname = fname1;
- pstrcpy(fname,&params[6]);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if(!check_name(fname, conn))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
-
- if(!VALID_STAT(sbuf)) {
- DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- }
-
- if (!CAN_WRITE(conn))
- return(ERROR(ERRSRV,ERRaccess));
-
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
- tran_call,fname,info_level,total_data));
-
- /* Realloc the parameter and data sizes */
- params = Realloc(*pparams,2);
- if(params == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- SSVAL(params,0,0);
-
- size = sbuf.st_size;
- tvs.modtime = sbuf.st_mtime;
- tvs.actime = sbuf.st_atime;
- mode = dos_mode(conn,fname,&sbuf);
-
- if (total_data > 4 && IVAL(pdata,0) == total_data) {
- /* uggh, EAs for OS2 */
- DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERReasnotsupported));
- }
-
- switch (info_level)
- {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
- {
- /* access time */
- tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
-
- /* write time */
- tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
-
- mode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
- break;
- }
-
- /* XXXX um, i don't think this is right.
- it's also not in the cifs6.txt spec.
- */
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- tvs.actime = make_unix_date2(pdata+8);
- tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
-
- /* XXXX nor this. not in cifs6.txt, either. */
- case SMB_INFO_QUERY_ALL_EAS:
- tvs.actime = make_unix_date2(pdata+8);
- tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
-
- case SMB_SET_FILE_BASIC_INFO:
- case 1004:
- {
- /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
- time_t write_time;
- time_t changed_time;
-
- /* Ignore create time at offset pdata. */
-
- /* access time */
- tvs.actime = interpret_long_date(pdata+8);
-
- write_time = interpret_long_date(pdata+16);
- changed_time = interpret_long_date(pdata+24);
-
- tvs.modtime = MIN(write_time, changed_time);
-
- /* Prefer a defined time to an undefined one. */
- if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
- tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
- ? changed_time
- : write_time);
-
- /* attributes */
- mode = IVAL(pdata,32);
- break;
- }
+ /*
+ * Only allow delete on close for writable shares.
+ */
- case SMB_FILE_ALLOCATION_INFORMATION:
- case SMB_SET_FILE_ALLOCATION_INFO:
- {
- int ret = -1;
- size = IVAL(pdata,0);
+ if (delete_on_close && !CAN_WRITE(fsp->conn)) {
+ DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ /*
+ * Only allow delete on close for files/directories opened with delete intent.
+ */
+
+ if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
+ DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if(fsp->is_directory) {
+ fsp->directory_delete_on_close = delete_on_close;
+ DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ } else if(fsp->stat_open) {
+
+ DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+
+ } else {
+
+ files_struct *iterate_fsp;
+
+ /*
+ * Modify the share mode entry for all files open
+ * on this device and inode to tell other smbds we have
+ * changed the delete on close flag. This will be noticed
+ * in the close code, the last closer will delete the file
+ * if flag is set.
+ */
+
+ DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+
+ if (lock_share_entry_fsp(fsp) == False)
+ return NT_STATUS_ACCESS_DENIED;
+
+ if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
+ DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
+ fsp->fsp_name ));
+ unlock_share_entry_fsp(fsp);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /*
+ * Release the lock.
+ */
+
+ unlock_share_entry_fsp(fsp);
+
+ /*
+ * Go through all files we have open on the same device and
+ * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+ * Other smbd's that have this file open will look in the share_mode on close.
+ * take care of this (rare) case in close_file(). See the comment there.
+ * NB. JRA. We don't really need to do this anymore - all should be taken
+ * care of in the share_mode changes in the tdb.
+ */
+
+ for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
+ iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
+ fsp->delete_on_close = delete_on_close;
+
+ /*
+ * Set the delete on close flag in the fsp.
+ */
+ fsp->delete_on_close = delete_on_close;
+
+ DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Returns true if this pathname is within the share, and thus safe.
+****************************************************************************/
+
+static int ensure_link_is_safe(connection_struct *conn, const char *link_dest_in, char *link_dest_out)
+{
+#ifdef PATH_MAX
+ char resolved_name[PATH_MAX+1];
+#else
+ pstring resolved_name;
+#endif
+ pstring link_dest;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+
+ pstrcpy(link_dest, link_dest_in);
+ unix_convert(link_dest,conn,0,&bad_path,&sbuf);
+
+ if (conn->vfs_ops.realpath(conn,dos_to_unix(link_dest,False),resolved_name) == NULL)
+ return -1;
+
+ pstrcpy(link_dest, unix_to_dos(resolved_name,False));
+
+ if (*link_dest != '/') {
+ /* Relative path. */
+ pstrcpy(link_dest_out, conn->connectpath);
+ pstrcat(link_dest_out, "/");
+ pstrcat(link_dest_out, link_dest);
+ } else {
+ pstrcpy(link_dest_out, link_dest);
+ }
+
+ /*
+ * Check if the link is within the share.
+ */
+
+ if (strncmp(conn->connectpath, link_dest_out, strlen(conn->connectpath))) {
+ errno = EACCES;
+ return -1;
+ }
+ return 0;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_SETFILEINFO (set file info by fileid).
+****************************************************************************/
+
+static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
+{
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 tran_call = SVAL(inbuf, smb_setup0);
+ uint16 info_level;
+ int dosmode = 0;
+ SMB_OFF_T size=0;
+ struct utimbuf tvs;
+ SMB_STRUCT_STAT sbuf;
+ pstring fname1;
+ char *fname = NULL;
+ int fd = -1;
+ BOOL bad_path = False;
+ files_struct *fsp = NULL;
+ uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
+ gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
+ mode_t unixmode = 0;
+
+ if (tran_call == TRANSACT2_SETFILEINFO) {
+
+ if (total_params < 4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ fsp = file_fsp(params,0);
+ info_level = SVAL(params,2);
+
+ if(fsp && (fsp->is_directory || fsp->stat_open)) {
+ /*
+ * This is actually a SETFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ fname = fsp->fsp_name;
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
+ DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+ } else if (fsp && fsp->print_file) {
+ /*
+ * Doing a DELETE_ON_CLOSE should cancel a print job.
+ */
+ if (((info_level == SMB_SET_FILE_DISPOSITION_INFO)||(info_level == SMB_FILE_DISPOSITION_INFORMATION)) &&
+ CVAL(pdata,0)) {
+ fsp->share_mode = FILE_DELETE_ON_CLOSE;
+
+ DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
+ fsp->fsp_name ));
+
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ CHECK_FSP(fsp,conn);
+
+ fname = fsp->fsp_name;
+ fd = fsp->fd;
+
+ if (vfs_fstat(fsp,fd,&sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
+ return(UNIXERROR(ERRDOS,ERRbadfid));
+ }
+ }
+ } else {
+ /* set path info */
+ if (total_params < 6)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ info_level = SVAL(params,0);
+ fname = fname1;
+ pstrcpy(fname,&params[6]);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if(!check_name(fname, conn)) {
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+
+ /*
+ * For CIFS UNIX extensions the target name may not exist.
+ */
+
+ if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
+
+ DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+ }
+
+ if (!CAN_WRITE(conn))
+ return ERROR_DOS(ERRSRV,ERRaccess);
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+
+ if (VALID_STAT(sbuf))
+ unixmode = sbuf.st_mode;
+
+ DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
+ tran_call,fname,info_level,total_data));
+
+ /* Realloc the parameter and data sizes */
+ params = Realloc(*pparams,2);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
+
+ SSVAL(params,0,0);
+
+ size = sbuf.st_size;
+ tvs.modtime = sbuf.st_mtime;
+ tvs.actime = sbuf.st_atime;
+ dosmode = dos_mode(conn,fname,&sbuf);
+ unixmode = sbuf.st_mode;
+
+ set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
+ set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
+
+ if (total_data > 4 && IVAL(pdata,0) == total_data) {
+ /* uggh, EAs for OS2 */
+ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
+ return ERROR_DOS(ERRDOS,ERReasnotsupported);
+ }
+
+ switch (info_level) {
+ case SMB_INFO_STANDARD:
+ case SMB_INFO_QUERY_EA_SIZE:
+ {
+ if (total_data < l1_cbFile+4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ /* access time */
+ tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
+
+ /* write time */
+ tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
+
+ dosmode = SVAL(pdata,l1_attrFile);
+ size = IVAL(pdata,l1_cbFile);
+ break;
+ }
+
+ /* XXXX um, i don't think this is right.
+ it's also not in the cifs6.txt spec.
+ */
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ if (total_data < 28)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ tvs.actime = make_unix_date2(pdata+8);
+ tvs.modtime = make_unix_date2(pdata+12);
+ size = IVAL(pdata,16);
+ dosmode = IVAL(pdata,24);
+ break;
+
+ /* XXXX nor this. not in cifs6.txt, either. */
+ case SMB_INFO_QUERY_ALL_EAS:
+ if (total_data < 28)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ tvs.actime = make_unix_date2(pdata+8);
+ tvs.modtime = make_unix_date2(pdata+12);
+ size = IVAL(pdata,16);
+ dosmode = IVAL(pdata,24);
+ break;
+
+ case SMB_SET_FILE_BASIC_INFO:
+ case SMB_FILE_BASIC_INFORMATION:
+ {
+ /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
+ time_t write_time;
+ time_t changed_time;
+
+ if (total_data < 36)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ /* Ignore create time at offset pdata. */
+
+ /* access time */
+ tvs.actime = interpret_long_date(pdata+8);
+
+ write_time = interpret_long_date(pdata+16);
+ changed_time = interpret_long_date(pdata+24);
+
+ tvs.modtime = MIN(write_time, changed_time);
+
+ /* Prefer a defined time to an undefined one. */
+ if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+ tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
+ ? changed_time
+ : write_time);
+
+ /* attributes */
+ dosmode = IVAL(pdata,32);
+ break;
+ }
+
+ case SMB_FILE_ALLOCATION_INFORMATION:
+ case SMB_SET_FILE_ALLOCATION_INFO:
+ {
+ int ret = -1;
+ SMB_OFF_T allocation_size;
+
+ if (total_data < 8)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ allocation_size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
- size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+ allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return(ERROR(ERRDOS,ERRunknownlevel));
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
- fname, (double)size ));
+ DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
+ fname, (double)allocation_size ));
- if(size != sbuf.st_size) {
+ if(allocation_size != sbuf.st_size) {
+ SMB_STRUCT_STAT new_sbuf;
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
- fname, (double)size ));
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
+ fname, (double)allocation_size ));
- if (fd == -1) {
- files_struct *new_fsp = NULL;
- int access_mode = 0;
- int action = 0;
+ if (fd == -1) {
+ files_struct *new_fsp = NULL;
+ int access_mode = 0;
+ int action = 0;
- if(global_oplock_break) {
- /* Queue this file modify as we are the process of an oplock break. */
+ if(global_oplock_break) {
+ /* Queue this file modify as we are the process of an oplock break. */
- DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
- DEBUGADD(2,( "in oplock break state.\n"));
+ DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
+ DEBUGADD(2,( "in oplock break state.\n"));
- push_oplock_pending_smb_message(inbuf, length);
- return -1;
- }
+ push_oplock_pending_smb_message(inbuf, length);
+ return -1;
+ }
+
+ new_fsp = open_file_shared(conn, fname, &sbuf,
+ SET_OPEN_MODE(DOS_OPEN_RDWR),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
- new_fsp = open_file_shared(conn, fname, &sbuf,
- SET_OPEN_MODE(DOS_OPEN_RDWR),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
-
- if (new_fsp == NULL)
- return(UNIXERROR(ERRDOS,ERRbadpath));
- ret = vfs_allocate_file_space(new_fsp, size);
- close_file(new_fsp,True);
- } else {
- ret = vfs_allocate_file_space(fsp, size);
- }
- if (ret == -1)
- return allocate_space_error(inbuf, outbuf, errno);
-
- sbuf.st_size = size;
- }
-
- break;
- }
+ if (new_fsp == NULL)
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ ret = vfs_allocate_file_space(new_fsp, allocation_size);
+ if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
+ ret = -1;
+ }
+ close_file(new_fsp,True);
+ } else {
+ ret = vfs_allocate_file_space(fsp, allocation_size);
+ if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
+ ret = -1;
+ }
+ }
+ if (ret == -1)
+ return ERROR_NT(NT_STATUS_DISK_FULL);
- case SMB_FILE_END_OF_FILE_INFORMATION:
- case SMB_SET_FILE_END_OF_FILE_INFO:
- {
- size = IVAL(pdata,0);
+ /* Allocate can trucate size... */
+ size = new_sbuf.st_size;
+ }
+
+ break;
+ }
+
+ case SMB_FILE_END_OF_FILE_INFORMATION:
+ case SMB_SET_FILE_END_OF_FILE_INFO:
+ {
+ if (total_data < 8)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
- size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+ size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return(ERROR(ERRDOS,ERRunknownlevel));
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
- break;
- }
+ DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
+ break;
+ }
- case SMB_FILE_DISPOSITION_INFORMATION:
- case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
- {
- BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
+ case SMB_FILE_DISPOSITION_INFORMATION:
+ case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
+ {
+ BOOL delete_on_close;
+ NTSTATUS status;
- if (tran_call != TRANSACT2_SETFILEINFO)
- return(ERROR(ERRDOS,ERRunknownlevel));
+ if (total_data < 1)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
- if (fsp == NULL)
- return(UNIXERROR(ERRDOS,ERRbadfid));
+ delete_on_close = (CVAL(pdata,0) ? True : False);
- /*
- * Only allow delete on close for files/directories opened with delete intent.
- */
+ if (tran_call != TRANSACT2_SETFILEINFO)
+ return(ERROR_DOS(ERRDOS,ERRunknownlevel));
- if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
- DEBUG(10,("call_trans2setfilepathinfo: file %s delete on close flag set but delete access denied.\n",
- fsp->fsp_name ));
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ if (fsp == NULL)
+ return(UNIXERROR(ERRDOS,ERRbadfid));
- if(fsp->is_directory) {
- fsp->directory_delete_on_close = delete_on_close;
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
- } else if(fsp->stat_open) {
+ status = set_delete_on_close_internal(fsp, delete_on_close);
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ return ERROR_NT(status);
- } else {
+ break;
+ }
- files_struct *iterate_fsp;
+ /*
+ * CIFS UNIX extensions.
+ */
- /*
- * Modify the share mode entry for all files open
- * on this device and inode to tell other smbds we have
- * changed the delete on close flag. This will be noticed
- * in the close code, the last closer will delete the file
- * if flag is set.
- */
+ case SMB_SET_FILE_UNIX_BASIC:
+ {
+ uint32 raw_unixmode;
- DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+ if (total_data < 100)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
- if (lock_share_entry_fsp(fsp) == False)
- return(ERROR(ERRDOS,ERRnoaccess));
+ size=IVAL(pdata,0); /* first 8 Bytes are size */
+#ifdef LARGE_SMB_OFF_T
+ size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+#endif /* LARGE_SMB_OFF_T */
+ pdata+=24; /* ctime & st_blocks are not changed */
+ tvs.actime = interpret_long_date(pdata); /* access_time */
+ tvs.modtime = interpret_long_date(pdata+8); /* modification_time */
+ pdata+=16;
+ set_owner = (uid_t)IVAL(pdata,0);
+ pdata += 8;
+ set_grp = (gid_t)IVAL(pdata,0);
+ pdata += 8;
+ raw_unixmode = IVAL(pdata,28);
+ unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
+ dosmode = 0; /* Ensure dos mode change doesn't override this. */
+
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
+size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
+ fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
+
+ if (!VALID_STAT(sbuf)) {
+
+ /*
+ * The only valid use of this is to create character and block
+ * devices, and named pipes. This is deprecated (IMHO) and
+ * a new info level should be used for mknod. JRA.
+ */
+
+#if !defined(HAVE_MAKEDEV_FN)
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+#else /* HAVE_MAKEDEV_FN */
+ uint32 file_type = IVAL(pdata,0);
+ uint32 dev_major = IVAL(pdata,4);
+ uint32 dev_minor = IVAL(pdata,12);
+
+ uid_t myuid = geteuid();
+ gid_t mygid = getegid();
+ SMB_DEV_T dev;
+
+ if (tran_call == TRANSACT2_SETFILEINFO)
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+
+ if (raw_unixmode == SMB_MODE_NO_CHANGE)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ dev = makedev(dev_major, dev_minor);
+
+ /* We can only create as the owner/group we are. */
+
+ if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE))
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+
+ if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
+ file_type != UNIX_TYPE_FIFO)
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
+0%o for file %s\n", (double)dev, unixmode, fname ));
+
+ /* Ok - do the mknod. */
+ if (conn->vfs_ops.mknod(conn,dos_to_unix(fname,False), unixmode, dev) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+#endif /* HAVE_MAKEDEV_FN */
- if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
- DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close flag for file %s\n",
- fsp->fsp_name ));
- unlock_share_entry_fsp(fsp);
- return(ERROR(ERRDOS,ERRnoaccess));
}
/*
- * Release the lock.
+ * Deal with the UNIX specific mode set.
*/
- unlock_share_entry_fsp(fsp);
+ if (raw_unixmode != SMB_MODE_NO_CHANGE) {
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
+ unixmode, fname ));
+ if (vfs_chmod(conn,fname,unixmode) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
/*
- * Go through all files we have open on the same device and
- * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
- * Other smbd's that have this file open will look in the share_mode on close.
- * take care of this (rare) case in close_file(). See the comment there.
- * NB. JRA. We don't really need to do this anymore - all should be taken
- * care of in the share_mode changes in the tdb.
+ * Deal with the UNIX specific uid set.
*/
- for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
- iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
- fsp->delete_on_close = delete_on_close;
+ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) {
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n",
+ (unsigned int)set_owner, fname ));
+ if (vfs_chown(conn,fname,set_owner, (gid_t)-1) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
/*
- * Set the delete on close flag in the fsp.
+ * Deal with the UNIX specific gid set.
*/
- fsp->delete_on_close = delete_on_close;
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) {
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n",
+ (unsigned int)set_owner, fname ));
+ if (vfs_chown(conn,fname,(uid_t)-1, set_grp) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ break;
+ }
+
+ case SMB_SET_FILE_UNIX_LINK:
+ {
+ pstring link_dest;
+ /* Set a symbolic link. */
+ /* Don't allow this if follow links is false. */
+
+ if (!lp_symlinks(SNUM(conn)))
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ /* Disallow if already exists. */
+ if (VALID_STAT(sbuf))
+ return(ERROR_DOS(ERRDOS,ERRbadpath));
+
+ pstrcpy(link_dest, pdata);
+
+ if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ dos_to_unix(link_dest, True);
+ dos_to_unix(fname, True);
+
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
+ fname, link_dest ));
+
+ if (conn->vfs_ops.symlink(conn,link_dest,fname) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
}
- break;
+ case SMB_SET_FILE_UNIX_HLINK:
+ {
+ pstring link_dest;
+
+ /* Set a hard link. */
+
+ /* Disallow if already exists. */
+ if (VALID_STAT(sbuf))
+ return(ERROR_DOS(ERRDOS,ERRbadpath));
+
+ pstrcpy(link_dest, pdata);
+
+ if (ensure_link_is_safe(conn, link_dest, link_dest) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ dos_to_unix(link_dest, True);
+ dos_to_unix(fname, True);
+
+ DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
+ fname, link_dest ));
+
+ if (conn->vfs_ops.link(conn,link_dest,fname) != 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+
+ default:
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
- default:
- {
- return(ERROR(ERRDOS,ERRunknownlevel));
+ /* get some defaults (no modifications) if any info is zero or -1. */
+ if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
+ tvs.actime = sbuf.st_atime;
+
+ if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+ tvs.modtime = sbuf.st_mtime;
+
+ DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
+ DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
+ DEBUG(6,("size: %.0f ", (double)size));
+ DEBUG(6,("dosmode: %x\n" , dosmode));
+
+ if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
+ (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
+ (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
+ (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
+ /*
+ * Only do this test if we are not explicitly
+ * changing the size of a file.
+ */
+ if (!size)
+ size = sbuf.st_size;
}
- }
-
- /* get some defaults (no modifications) if any info is zero or -1. */
- if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
- tvs.actime = sbuf.st_atime;
-
- if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
- tvs.modtime = sbuf.st_mtime;
-
- DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
- DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
- DEBUG(6,("size: %.0f ", (double)size));
- DEBUG(6,("mode: %x\n" , mode));
-
- if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
- (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
- (info_level == 1019) ||
- (info_level == 1020))) {
- /*
- * Only do this test if we are not explicitly
- * changing the size of a file.
- */
- if (!size)
- size = sbuf.st_size;
- }
-
- /* Try and set the times, size and mode of this file -
- if they are different from the current values
- */
- if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
- if(fsp != NULL) {
- /*
- * This was a setfileinfo on an open file.
- * NT does this a lot. It's actually pointless
- * setting the time here, as it will be overwritten
- * on the next write, so we save the request
- * away and will set it on file code. JRA.
- */
-
- if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
- DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
- ctime(&tvs.modtime) ));
- fsp->pending_modtime = tvs.modtime;
- }
-
- } else {
-
- DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
-
- if(file_utime(conn, fname, &tvs)!=0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
-
- /* check the mode isn't different, before changing it */
- if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
-
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
- fname, mode ));
-
- if(file_chmod(conn, fname, mode, NULL)) {
- DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
-
- if(size != sbuf.st_size) {
-
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
- fname, (double)size ));
-
- if (fd == -1) {
- files_struct *new_fsp = NULL;
- int access_mode = 0;
- int action = 0;
-
- if(global_oplock_break) {
- /* Queue this file modify as we are the process of an oplock break. */
-
- DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
- DEBUGADD(2,( "in oplock break state.\n"));
-
- push_oplock_pending_smb_message(inbuf, length);
- return -1;
- }
-
- new_fsp = open_file_shared(conn, fname, &sbuf,
- SET_OPEN_MODE(DOS_OPEN_RDWR),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
+
+ /*
+ * Try and set the times, size and mode of this file -
+ * if they are different from the current values
+ */
+
+ if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
+ if(fsp != NULL) {
+ /*
+ * This was a setfileinfo on an open file.
+ * NT does this a lot. It's actually pointless
+ * setting the time here, as it will be overwritten
+ * on the next write, so we save the request
+ * away and will set it on file code. JRA.
+ */
+
+ if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
+ DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
+ ctime(&tvs.modtime) ));
+ fsp->pending_modtime = tvs.modtime;
+ }
+
+ } else {
+
+ DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
+
+ if(file_utime(conn, fname, &tvs)!=0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ /* check the mode isn't different, before changing it */
+ if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
+
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
+ fname, dosmode ));
+
+ if(file_chmod(conn, fname, dosmode, NULL)) {
+ DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ }
+
+ if(size != sbuf.st_size) {
+
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
+ fname, (double)size ));
+
+ if (fd == -1) {
+ files_struct *new_fsp = NULL;
+ int access_mode = 0;
+ int action = 0;
+
+ if(global_oplock_break) {
+ /* Queue this file modify as we are the process of an oplock break. */
+
+ DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
+ DEBUGADD(2,( "in oplock break state.\n"));
+
+ push_oplock_pending_smb_message(inbuf, length);
+ return -1;
+ }
+
+ new_fsp = open_file_shared(conn, fname, &sbuf,
+ SET_OPEN_MODE(DOS_OPEN_RDWR),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
- if (new_fsp == NULL)
- return(UNIXERROR(ERRDOS,ERRbadpath));
- vfs_set_filelen(new_fsp, size);
- close_file(new_fsp,True);
- } else {
- vfs_set_filelen(fsp, size);
- }
- }
-
- SSVAL(params,0,0);
-
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
-
- return(-1);
+ if (new_fsp == NULL)
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ vfs_set_filelen(new_fsp, size);
+ close_file(new_fsp,True);
+ } else {
+ vfs_set_filelen(fsp, size);
+ }
+ }
+
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
}
/****************************************************************************
- reply to a TRANS2_MKDIR (make directory with extended attributes).
+ Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/
-static int call_trans2mkdir(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *params = *pparams;
- pstring directory;
- int ret = -1;
- SMB_STRUCT_STAT sbuf;
- BOOL bad_path = False;
+ char *params = *pparams;
+ pstring directory;
+ int ret = -1;
+ SMB_STRUCT_STAT sbuf;
+ BOOL bad_path = False;
+
+ if (!CAN_WRITE(conn))
+ return ERROR_DOS(ERRSRV,ERRaccess);
- if (!CAN_WRITE(conn))
- return(ERROR(ERRSRV,ERRaccess));
+ if (total_params < 4)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
- pstrcpy(directory, &params[4]);
+ pstrcpy(directory, &params[4]);
- DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
+ DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- unix_convert(directory,conn,0,&bad_path,&sbuf);
- if (check_name(directory,conn))
- ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+ if (check_name(directory,conn))
+ ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
- if(ret < 0)
- {
- DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Realloc the parameter and data sizes */
- params = Realloc(*pparams,2);
- if(params == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- SSVAL(params,0,0);
-
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ if(ret < 0) {
+ DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
+ set_bad_path_error(errno, bad_path);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ /* Realloc the parameter and data sizes */
+ params = Realloc(*pparams,2);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
+
+ SSVAL(params,0,0);
+
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
- return(-1);
+ return(-1);
}
/****************************************************************************
- reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
- We don't actually do this - we just send a null response.
+ Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
+ We don't actually do this - we just send a null response.
****************************************************************************/
-static int call_trans2findnotifyfirst(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- static uint16 fnf_handle = 257;
- char *params = *pparams;
- uint16 info_level = SVAL(params,4);
-
- DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
-
- switch (info_level)
- {
- case 1:
- case 2:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- /* Realloc the parameter and data sizes */
- params = Realloc(*pparams,6);
- if(params == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
-
- SSVAL(params,0,fnf_handle);
- SSVAL(params,2,0); /* No changes */
- SSVAL(params,4,0); /* No EA errors */
-
- fnf_handle++;
-
- if(fnf_handle == 0)
- fnf_handle = 257;
-
- send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
+ static uint16 fnf_handle = 257;
+ char *params = *pparams;
+ uint16 info_level;
+
+ if (total_params < 6)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ info_level = SVAL(params,4);
+ DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
+
+ switch (info_level) {
+ case 1:
+ case 2:
+ break;
+ default:
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ }
+
+ /* Realloc the parameter and data sizes */
+ params = Realloc(*pparams,6);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
+
+ SSVAL(params,0,fnf_handle);
+ SSVAL(params,2,0); /* No changes */
+ SSVAL(params,4,0); /* No EA errors */
+
+ fnf_handle++;
+
+ if(fnf_handle == 0)
+ fnf_handle = 257;
+
+ send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
- return(-1);
+ return(-1);
}
/****************************************************************************
- reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
- changes). Currently this does nothing.
+ Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
+ changes). Currently this does nothing.
****************************************************************************/
-static int call_trans2findnotifynext(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, char **ppdata)
+
+static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *params = *pparams;
+ char *params = *pparams;
- DEBUG(3,("call_trans2findnotifynext\n"));
+ DEBUG(3,("call_trans2findnotifynext\n"));
- /* Realloc the parameter and data sizes */
- params = Realloc(*pparams,4);
- if(params == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
+ /* Realloc the parameter and data sizes */
+ params = Realloc(*pparams,4);
+ if(params == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *pparams = params;
- SSVAL(params,0,0); /* No changes */
- SSVAL(params,2,0); /* No EA errors */
+ SSVAL(params,0,0); /* No changes */
+ SSVAL(params,2,0); /* No EA errors */
- send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
- return(-1);
+ return(-1);
}
/****************************************************************************
- reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>
+ Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char** pparams, char** ppdata)
+
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *params = *pparams;
- enum remote_arch_types ra_type = get_remote_arch();
- BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
- pstring pathname;
- int reply_size = 0;
- int max_referral_level = SVAL(params,0);
-
-
- DEBUG(10,("call_trans2getdfsreferral\n"));
-
- if(!lp_host_msdfs())
- return(ERROR(ERRDOS,ERRbadfunc));
-
- /* if pathname is in UNICODE, convert to DOS */
- /* NT always sends in UNICODE, may not set UNICODE flag */
- if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
- {
- unistr_to_dos(pathname, &params[2], sizeof(pathname));
- DEBUG(10,("UNICODE referral for %s\n",pathname));
- }
- else
- pstrcpy(pathname,&params[2]);
-
- if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
- return(ERROR(ERRDOS,ERRbadfile));
+ char *params = *pparams;
+ enum remote_arch_types ra_type = get_remote_arch();
+ BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
+ pstring pathname;
+ int reply_size = 0;
+ int max_referral_level;
+
+ DEBUG(10,("call_trans2getdfsreferral\n"));
+
+ if (total_params < 2)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ max_referral_level = SVAL(params,0);
+
+ if(!lp_host_msdfs())
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+
+ /* if pathname is in UNICODE, convert to DOS */
+ /* NT always sends in UNICODE, may not set UNICODE flag */
+ if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS)) {
+ unistr_to_dos(pathname, &params[2], sizeof(pathname));
+ DEBUG(10,("UNICODE referral for %s\n",pathname));
+ } else
+ pstrcpy(pathname,&params[2]);
+
+ if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
+ return ERROR_DOS(ERRDOS,ERRbadfile);
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
- FLAGS2_DFS_PATHNAMES);
- send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS | FLAGS2_DFS_PATHNAMES);
+ send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
- return(-1);
+ return(-1);
}
#define LMCAT_SPL 0x53
@@ -2347,38 +2992,35 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/
-static int call_trans2ioctl(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char** pparams, char** ppdata)
+static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data)
{
- char *pdata = *ppdata;
- files_struct *fsp = file_fsp(inbuf,smb_vwv15);
-
- if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
- (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
- pdata = Realloc(*ppdata, 32);
- if(pdata == NULL) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *ppdata = pdata;
-
- SSVAL(pdata,0,fsp->print_jobid); /* Job number */
- StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
- StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
- send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
- return(-1);
- } else {
- DEBUG(2,("Unknown TRANS2_IOCTL\n"));
- return(ERROR(ERRSRV,ERRerror));
- }
+ char *pdata = *ppdata;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv15);
+
+ if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
+ (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ pdata = Realloc(*ppdata, 32);
+ if(pdata == NULL)
+ return ERROR_DOS(ERRDOS,ERRnomem);
+ *ppdata = pdata;
+
+ SSVAL(pdata,0,fsp->print_jobid); /* Job number */
+ StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
+ send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
+ return(-1);
+ } else {
+ DEBUG(2,("Unknown TRANS2_IOCTL\n"));
+ return ERROR_DOS(ERRSRV,ERRerror);
+ }
}
/****************************************************************************
Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
-int reply_findclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_findclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
int dptr_num=SVALS(inbuf,smb_vwv0);
@@ -2400,8 +3042,7 @@ int reply_findclose(connection_struct *conn,
Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
-int reply_findnclose(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_findnclose(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
int dptr_num= -1;
@@ -2427,8 +3068,7 @@ int reply_findnclose(connection_struct *conn,
Reply to a SMBtranss2 - just ignore it!
****************************************************************************/
-int reply_transs2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+int reply_transs2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
START_PROFILE(SMBtranss2);
DEBUG(4,("Ignoring transs2 of length %d\n",length));
@@ -2437,10 +3077,10 @@ int reply_transs2(connection_struct *conn,
}
/****************************************************************************
- reply to a SMBtrans2
+ Reply to a SMBtrans2.
****************************************************************************/
-int reply_trans2(connection_struct *conn,
- char *inbuf,char *outbuf,int length,int bufsize)
+
+int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
unsigned int total_params = SVAL(inbuf, smb_tpscnt);
@@ -2474,7 +3114,7 @@ int reply_trans2(connection_struct *conn,
if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
&& (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
END_PROFILE(SMBtrans2);
- return(ERROR(ERRSRV,ERRaccess));
+ return ERROR_DOS(ERRSRV,ERRaccess);
}
outsize = set_message(outbuf,0,0,True);
@@ -2498,7 +3138,7 @@ int reply_trans2(connection_struct *conn,
DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
DEBUG(2,("Transaction is %d\n",tran_call));
END_PROFILE(SMBtrans2);
- return(ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
}
@@ -2510,12 +3150,10 @@ int reply_trans2(connection_struct *conn,
if ((total_params && !params) || (total_data && !data)) {
DEBUG(2,("Out of memory in reply_trans2\n"));
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBtrans2);
- return(ERROR(ERRDOS,ERRnomem));
+ return ERROR_DOS(ERRDOS,ERRnomem);
}
/* Copy the param and data bytes sent with this request into
@@ -2536,7 +3174,7 @@ int reply_trans2(connection_struct *conn,
of the parameter/data bytes */
outsize = set_message(outbuf,0,0,True);
if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_trans2: send_smb failed.\n");
+ exit_server("reply_trans2: send_smb failed.");
while (num_data_sofar < total_data ||
num_params_sofar < total_params) {
@@ -2552,12 +3190,10 @@ int reply_trans2(connection_struct *conn,
else
DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
(smb_read_error == READ_ERROR) ? "error" : "timeout" ));
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBtrans2);
- return(ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
/* Revise total_params and total_data in case
@@ -2577,112 +3213,100 @@ int reply_trans2(connection_struct *conn,
}
if (Protocol >= PROTOCOL_NT1) {
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
}
/* Now we must call the relevant TRANS2 function */
switch(tran_call) {
case TRANSACT2_OPEN:
START_PROFILE_NESTED(Trans2_open);
- outsize = call_trans2open(conn,
- inbuf, outbuf, bufsize,
- &params, &data);
+ outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_open);
break;
case TRANSACT2_FINDFIRST:
START_PROFILE_NESTED(Trans2_findfirst);
- outsize = call_trans2findfirst(conn, inbuf, outbuf,
- bufsize, &params, &data);
+ outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findfirst);
break;
case TRANSACT2_FINDNEXT:
START_PROFILE_NESTED(Trans2_findnext);
- outsize = call_trans2findnext(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
+ outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnext);
break;
case TRANSACT2_QFSINFO:
START_PROFILE_NESTED(Trans2_qfsinfo);
- outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
- length, bufsize, &params,
- &data);
+ outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
- outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
+ outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
case TRANSACT2_QPATHINFO:
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);
- outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data, total_data);
+ outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_qpathinfo);
break;
case TRANSACT2_SETPATHINFO:
case TRANSACT2_SETFILEINFO:
START_PROFILE_NESTED(Trans2_setpathinfo);
- outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data,
- total_data);
+ outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_setpathinfo);
break;
case TRANSACT2_FINDNOTIFYFIRST:
START_PROFILE_NESTED(Trans2_findnotifyfirst);
- outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
+ outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnotifyfirst);
break;
case TRANSACT2_FINDNOTIFYNEXT:
START_PROFILE_NESTED(Trans2_findnotifynext);
- outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
+ outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_findnotifynext);
break;
case TRANSACT2_MKDIR:
START_PROFILE_NESTED(Trans2_mkdir);
- outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
- bufsize, &params, &data);
+ outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_mkdir);
break;
case TRANSACT2_GET_DFS_REFERRAL:
START_PROFILE_NESTED(Trans2_get_dfs_referral);
- outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
- bufsize, &params, &data);
+ outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_get_dfs_referral);
break;
case TRANSACT2_IOCTL:
START_PROFILE_NESTED(Trans2_ioctl);
- outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
- bufsize,&params,&data);
+ outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
+ &params, total_params, &data, total_data);
END_PROFILE_NESTED(Trans2_ioctl);
break;
default:
/* Error in request */
DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBtrans2);
- return (ERROR(ERRSRV,ERRerror));
+ return ERROR_DOS(ERRSRV,ERRerror);
}
/* As we do not know how many data packets will need to be
@@ -2692,10 +3316,8 @@ int reply_trans2(connection_struct *conn,
an error packet.
*/
- if(params)
- free(params);
- if(data)
- free(data);
+ SAFE_FREE(params);
+ SAFE_FREE(data);
END_PROFILE(SMBtrans2);
return outsize; /* If a correct response was needed the
call_trans2xxx calls have already sent
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index 54ced5a8239..5204f36ad6e 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -21,16 +21,14 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* what user is current? */
extern struct current_user current_user;
/****************************************************************************
- Become the guest user.
+ Become the guest user without changing the security context stack.
****************************************************************************/
-BOOL become_guest(void)
+BOOL change_to_guest(void)
{
static struct passwd *pass=NULL;
static uid_t guest_uid = (uid_t)-1;
@@ -84,10 +82,11 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
}
/****************************************************************************
- Become the user of a connection number.
+ Become the user of a connection number without changing the security context
+ stack, but modify the currnet_user entries.
****************************************************************************/
-BOOL become_user(connection_struct *conn, uint16 vuid)
+BOOL change_to_user(connection_struct *conn, uint16 vuid)
{
user_struct *vuser = get_valid_user_struct(vuid);
int snum;
@@ -98,7 +97,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
NT_USER_TOKEN *token = NULL;
if (!conn) {
- DEBUG(2,("Connection not open\n"));
+ DEBUG(2,("change_to_user: Connection not open\n"));
return(False);
}
@@ -111,12 +110,12 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
(current_user.uid == conn->uid)) {
- DEBUG(4,("Skipping become_user - already user\n"));
+ DEBUG(4,("change_to_user: Skipping user change - already user\n"));
return(True);
} else if ((current_user.conn == conn) &&
(vuser != 0) && (current_user.vuid == vuid) &&
(current_user.uid == vuser->uid)) {
- DEBUG(4,("Skipping become_user - already user\n"));
+ DEBUG(4,("change_to_user: Skipping user change - already user\n"));
return(True);
}
@@ -135,7 +134,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
token = conn->nt_user_token;
} else {
if (!vuser) {
- DEBUG(2,("Invalid vuid used %d\n",vuid));
+ DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid));
return(False);
}
uid = vuser->uid;
@@ -182,7 +181,7 @@ BOOL become_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);
+ token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL);
must_free_token = True;
}
@@ -198,21 +197,22 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
current_user.conn = conn;
current_user.vuid = vuid;
- DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
+ DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
return(True);
}
/****************************************************************************
- Unbecome the user of a connection number.
+ Go back to being root without changing the security context stack,
+ but modify the current_user entries.
****************************************************************************/
-BOOL unbecome_user(void )
+BOOL change_to_root_user(void)
{
set_root_sec_ctx();
- DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
+ DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n",
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
current_user.conn = NULL;
@@ -224,16 +224,13 @@ BOOL unbecome_user(void )
/****************************************************************************
Become the user of an authenticated connected named pipe.
When this is called we are currently running as the connection
- user.
+ user. Doesn't modify current_user.
****************************************************************************/
BOOL become_authenticated_pipe_user(pipes_struct *p)
{
- BOOL res = push_sec_ctx();
-
- if (!res) {
+ if (!push_sec_ctx())
return False;
- }
set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token);
@@ -244,19 +241,93 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
/****************************************************************************
Unbecome the user of an authenticated connected named pipe.
When this is called we are running as the authenticated pipe
- user and need to go back to being the connection user.
+ user and need to go back to being the connection user. Doesn't modify
+ current_user.
****************************************************************************/
-BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
+BOOL unbecome_authenticated_pipe_user(void)
{
return pop_sec_ctx();
}
-/* Temporarily become a root user. Must match with unbecome_root(). */
+/****************************************************************************
+ Utility functions used by become_xxx/unbecome_xxx.
+****************************************************************************/
+
+struct conn_ctx {
+ connection_struct *conn;
+ uint16 vuid;
+};
+
+/* A stack of current_user connection contexts. */
+
+static struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH];
+static int conn_ctx_stack_ndx;
+
+static void push_conn_ctx(void)
+{
+ struct conn_ctx *ctx_p;
+
+ /* Check we don't overflow our stack */
+
+ if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
+ DEBUG(0, ("Connection context stack overflow!\n"));
+ smb_panic("Connection context stack overflow!\n");
+ }
+
+ /* Store previous user context */
+ ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
+
+ ctx_p->conn = current_user.conn;
+ ctx_p->vuid = current_user.vuid;
+
+ DEBUG(3, ("push_conn_ctx(%u) : conn_ctx_stack_ndx = %d\n",
+ (unsigned int)ctx_p->vuid, conn_ctx_stack_ndx ));
+
+ conn_ctx_stack_ndx++;
+}
+
+static void pop_conn_ctx(void)
+{
+ struct conn_ctx *ctx_p;
+
+ /* Check for stack underflow. */
+
+ if (conn_ctx_stack_ndx == 0) {
+ DEBUG(0, ("Connection context stack underflow!\n"));
+ smb_panic("Connection context stack underflow!\n");
+ }
+
+ conn_ctx_stack_ndx--;
+ ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
+
+ current_user.conn = ctx_p->conn;
+ current_user.vuid = ctx_p->vuid;
+
+ ctx_p->conn = NULL;
+ ctx_p->vuid = UID_FIELD_INVALID;
+}
+
+void init_conn_ctx(void)
+{
+ int i;
+
+ /* Initialise connection context stack */
+ for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) {
+ conn_ctx_stack[i].conn = NULL;
+ conn_ctx_stack[i].vuid = UID_FIELD_INVALID;
+ }
+}
+
+/****************************************************************************
+ Temporarily become a root user. Must match with unbecome_root(). Saves and
+ restores the connection context.
+****************************************************************************/
void become_root(void)
{
push_sec_ctx();
+ push_conn_ctx();
set_root_sec_ctx();
}
@@ -265,6 +336,104 @@ void become_root(void)
void unbecome_root(void)
{
pop_sec_ctx();
+ pop_conn_ctx();
+}
+
+/****************************************************************************
+ Push the current security context then force a change via change_to_user().
+ Saves and restores the connection context.
+****************************************************************************/
+
+BOOL become_user(connection_struct *conn, uint16 vuid)
+{
+ if (!push_sec_ctx())
+ return False;
+
+ push_conn_ctx();
+
+ if (!change_to_user(conn, vuid)) {
+ pop_sec_ctx();
+ pop_conn_ctx();
+ return False;
+ }
+
+ return True;
+}
+
+BOOL unbecome_user(void)
+{
+ pop_sec_ctx();
+ pop_conn_ctx();
+ return True;
+}
+
+/*****************************************************************
+ Convert the suplimentary SIDs returned in a netlogon into UNIX
+ group gid_t's. Add to the total group array.
+*****************************************************************/
+
+void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok)
+{
+ int total_groups;
+ int current_n_groups = *n_groups;
+ gid_t *final_groups = NULL;
+ size_t i;
+ NT_USER_TOKEN *ptok = *pptok;
+ NT_USER_TOKEN *new_tok = NULL;
+
+ if (!ptok || (ptok->num_sids == 0))
+ return;
+
+ new_tok = dup_nt_token(ptok);
+ if (!new_tok) {
+ DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n"));
+ return;
+ }
+ /* Leave the allocated space but empty the number of SIDs. */
+ new_tok->num_sids = 0;
+
+ total_groups = current_n_groups + ptok->num_sids;
+
+ final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t));
+ if (!final_groups) {
+ DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n"));
+ delete_nt_token(&new_tok);
+ return;
+ }
+
+ memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t));
+ for (i = 0; i < ptok->num_sids; i++) {
+ enum SID_NAME_USE sid_type;
+ gid_t new_grp;
+
+ if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) {
+ /*
+ * Don't add the gid_t if it is already in the current group
+ * list. Some UNIXen don't like the same group more than once.
+ */
+ int j;
+
+ for (j = 0; j < current_n_groups; j++)
+ if (final_groups[j] == new_grp)
+ break;
+
+ if ( j == current_n_groups) {
+ /* Group not already present. */
+ final_groups[current_n_groups++] = new_grp;
+ }
+ } else {
+ /* SID didn't map. Copy to the new token to be saved. */
+ sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]);
+ }
+ }
+
+ SAFE_FREE(*pp_groups);
+ *pp_groups = final_groups;
+ *n_groups = current_n_groups;
+
+ /* Replace the old token with the truncated one. */
+ delete_nt_token(&ptok);
+ *pptok = new_tok;
}
/*****************************************************************
@@ -282,7 +451,7 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
*name_type = SID_NAME_UNKNOWN;
if (!winbind_lookup_name(name, psid, name_type) || (*name_type != SID_NAME_USER) ) {
- BOOL ret;
+ BOOL ret = False;
DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name));
@@ -382,16 +551,22 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE
DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
{
+ uid_t low, high;
fstring sid;
- if (!winbind_uid_to_sid(psid, uid)) {
- DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
+ if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) {
+ if (winbind_uid_to_sid(psid, uid)) {
- return local_uid_to_sid(psid, uid);
+ DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)uid, sid_to_string(sid, psid)));
+
+ return psid;
+ }
}
- DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_to_string(sid, psid) ));
+ local_uid_to_sid(psid, uid);
+
+ DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
return psid;
}
@@ -404,16 +579,22 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
{
+ gid_t low, high;
fstring sid;
- if (!winbind_gid_to_sid(psid, gid)) {
- DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
+ if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) {
+ if (winbind_gid_to_sid(psid, gid)) {
- return local_gid_to_sid(psid, gid);
+ DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
+ (unsigned int)gid, sid_to_string(sid, psid)));
+
+ return psid;
+ }
}
- DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_to_string(sid,psid) ));
+ local_gid_to_sid(psid, gid);
+
+ DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
return psid;
}
@@ -520,7 +701,7 @@ BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
return False;
}
- DEBUG(10,("gid_to_uid: winbindd %s -> %u\n",
+ DEBUG(10,("sid_to_gid: winbindd %s -> %u\n",
sid_to_string(sid_str, psid),
(unsigned int)*pgid ));
diff --git a/source/smbd/utmp.c b/source/smbd/utmp.c
index f79cd43c5b1..92e001cd036 100644
--- a/source/smbd/utmp.c
+++ b/source/smbd/utmp.c
@@ -127,7 +127,7 @@ Notes:
#endif
/****************************************************************************
-obtain/release a small number (0 upwards) unique within and across smbds
+ Obtain/release a small number (0 upwards) unique within and across smbds.
****************************************************************************/
/*
* Need a "small" number to represent this connection, unique within this
@@ -154,8 +154,9 @@ obtain/release a small number (0 upwards) unique within and across smbds
*/
/****************************************************************************
-Default paths to various {u,w}tmp{,x} files
+ Default paths to various {u,w}tmp{,x} files.
****************************************************************************/
+
#ifdef HAVE_UTMPX_H
static const char *ux_pathname =
@@ -260,9 +261,11 @@ static void uw_pathname(pstring fname, const char *uw_name, const char *uw_defau
}
#ifndef HAVE_PUTUTLINE
+
/****************************************************************************
-Update utmp file directly. No subroutine interface: probably a BSD system.
+ Update utmp file directly. No subroutine interface: probably a BSD system.
****************************************************************************/
+
static void pututline_my(pstring uname, struct utmp *u, BOOL claim)
{
DEBUG(1,("pututline_my: not yet implemented\n"));
@@ -271,10 +274,12 @@ static void pututline_my(pstring uname, struct utmp *u, BOOL claim)
#endif /* HAVE_PUTUTLINE */
#ifndef HAVE_UPDWTMP
+
/****************************************************************************
-Update wtmp file directly. No subroutine interface: probably a BSD system.
-Credit: Michail Vidiassov <master@iaas.msu.ru>
+ Update wtmp file directly. No subroutine interface: probably a BSD system.
+ Credit: Michail Vidiassov <master@iaas.msu.ru>
****************************************************************************/
+
static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
{
int fd;
@@ -294,8 +299,8 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
* man page appears not to specify (hints non-NULL)
* A correspondent suggest at least ut_name should be NULL
*/
- memset((char *)&(u->ut_name), '\0', sizeof(u->ut_name));
- memset((char *)&(u->ut_host), '\0', sizeof(u->ut_host));
+ memset((char *)&u->ut_name, '\0', sizeof(u->ut_name));
+ memset((char *)&u->ut_host, '\0', sizeof(u->ut_host));
}
/* Stolen from logwtmp function in libutil.
* May be more locking/blocking is needed?
@@ -311,9 +316,10 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
#endif /* HAVE_UPDWTMP */
/****************************************************************************
-Update via utmp/wtmp (not utmpx/wtmpx)
+ Update via utmp/wtmp (not utmpx/wtmpx).
****************************************************************************/
-static void utmp_nox_update(struct utmp *u, const char *host, BOOL claim)
+
+static void utmp_nox_update(struct utmp *u, BOOL claim)
{
pstring uname, wname;
#if defined(PUTUTLINE_RETURNS_UTMP)
@@ -369,21 +375,41 @@ static void utmp_nox_update(struct utmp *u, const char *host, BOOL claim)
}
/****************************************************************************
-Update via utmpx/wtmpx (preferred) or via utmp/wtmp
+ Copy a string in the utmp structure.
****************************************************************************/
+
+static void utmp_strcpy(char *dest, const char *src, size_t n)
+{
+ size_t len = 0;
+
+ memset(dest, '\0', n);
+ if (src)
+ len = strlen(src);
+ if (len >= n) {
+ memcpy(dest, src, n);
+ } else {
+ if (len)
+ memcpy(dest, src, len);
+ }
+}
+
+/****************************************************************************
+ Update via utmpx/wtmpx (preferred) or via utmp/wtmp.
+****************************************************************************/
+
static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
{
#if !defined(HAVE_UTMPX_H)
/* No utmpx stuff. Drop to non-x stuff */
- utmp_nox_update(u, hostname, claim);
+ utmp_nox_update(u, claim);
#elif !defined(HAVE_PUTUTXLINE)
/* Odd. Have utmpx.h but no "pututxline()". Drop to non-x stuff */
DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n"));
- utmp_nox_update(u, hostname, claim);
+ utmp_nox_update(u, claim);
#elif !defined(HAVE_GETUTMPX)
/* Odd. Have utmpx.h but no "getutmpx()". Drop to non-x stuff */
DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n"));
- utmp_nox_update(u, hostname, claim);
+ utmp_nox_update(u, claim);
#else
pstring uname, wname;
struct utmpx ux, *uxrc;
@@ -391,10 +417,12 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
getutmpx(u, &ux);
#if defined(HAVE_UX_UT_SYSLEN)
- if (hostname) ux.ut_syslen = strlen(hostname) + 1; /* include end NULL */
- else ux.ut_syslen = 0;
+ if (hostname)
+ ux.ut_syslen = strlen(hostname) + 1; /* include end NULL */
+ else
+ ux.ut_syslen = 0;
#endif
- safe_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host)-1);
+ utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));
uw_pathname(uname, "utmpx", ux_pathname);
uw_pathname(wname, "wtmpx", wx_pathname);
@@ -407,7 +435,7 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
* Drop to non-x method. (E.g. RH6 has good defaults in "utmp.h".)
*/
if ((strlen(uname) == 0) || (strlen(wname) == 0)) {
- utmp_nox_update(u, hostname, claim);
+ utmp_nox_update(u, claim);
} else {
utmpxname(uname);
setutxent();
@@ -424,8 +452,9 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
#if defined(HAVE_UT_UT_ID)
/****************************************************************************
-encode the unique connection number into "ut_id"
+ Encode the unique connection number into "ut_id".
****************************************************************************/
+
static int ut_id_encode(int i, char *fourbyte)
{
int nbase;
@@ -467,9 +496,9 @@ static BOOL sys_utmp_fill(struct utmp *u,
* rather than to try to detect and optimise.
*/
#if defined(HAVE_UT_UT_USER)
- safe_strcpy(u->ut_user, username, sizeof(u->ut_user)-1);
+ utmp_strcpy(u->ut_user, username, sizeof(u->ut_user));
#elif defined(HAVE_UT_UT_NAME)
- safe_strcpy(u->ut_name, username, sizeof(u->ut_name)-1);
+ utmp_strcpy(u->ut_name, username, sizeof(u->ut_name));
#endif
/*
@@ -485,7 +514,7 @@ static BOOL sys_utmp_fill(struct utmp *u,
id_str, sizeof(u->ut_line)));
return False;
}
- memcpy(u->ut_line, id_str, sizeof(u->ut_line));
+ utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
#if defined(HAVE_UT_UT_PID)
u->ut_pid = sys_getpid();
@@ -508,7 +537,7 @@ static BOOL sys_utmp_fill(struct utmp *u,
#endif
#if defined(HAVE_UT_UT_HOST)
- safe_strcpy(u->ut_host, hostname, sizeof(u->ut_host)-1);
+ utmp_strcpy(u->ut_host, hostname, sizeof(u->ut_host));
#endif
#if defined(HAVE_UT_UT_ADDR)
@@ -529,8 +558,9 @@ static BOOL sys_utmp_fill(struct utmp *u,
}
/****************************************************************************
-close a connection
+ Close a connection.
****************************************************************************/
+
void sys_utmp_yield(const char *username, const char *hostname,
const char *id_str, int id_num)
{
@@ -553,8 +583,9 @@ void sys_utmp_yield(const char *username, const char *hostname,
}
/****************************************************************************
-claim a entry in whatever utmp system the OS uses
+ Claim a entry in whatever utmp system the OS uses.
****************************************************************************/
+
void sys_utmp_claim(const char *username, const char *hostname,
const char *id_str, int id_num)
{
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 8e579634249..7d84e8756eb 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -559,6 +559,62 @@ int vfswrap_utime(connection_struct *conn, char *path, struct utimbuf *times)
return result;
}
+/*********************************************************************
+ A version of ftruncate that will write the space on disk if strict
+ allocate is set.
+**********************************************************************/
+
+static int strict_allocate_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
+{
+ struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
+ SMB_STRUCT_STAT st;
+ SMB_OFF_T currpos = vfs_ops->lseek(fsp, fd, 0, SEEK_CUR);
+ unsigned char zero_space[4096];
+ SMB_OFF_T space_to_write = len - st.st_size;
+
+ if (currpos == -1)
+ return -1;
+
+ if (vfs_ops->fstat(fsp, fd, &st) == -1)
+ return -1;
+
+#ifdef S_ISFIFO
+ if (S_ISFIFO(st.st_mode))
+ return 0;
+#endif
+
+ if (st.st_size == len)
+ return 0;
+
+ /* Shrink - just ftruncate. */
+ if (st.st_size > len)
+ return sys_ftruncate(fd, len);
+
+ /* Write out the real space on disk. */
+ if (vfs_ops->lseek(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
+ return -1;
+
+ space_to_write = len - st.st_size;
+
+ memset(zero_space, '\0', sizeof(zero_space));
+ while ( space_to_write > 0) {
+ SMB_OFF_T retlen;
+ SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
+
+ retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
+ if (retlen <= 0)
+ return -1;
+
+ space_to_write -= retlen;
+ }
+
+ /* Seek to where we were */
+ if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
+ return -1;
+
+ return 0;
+}
+
int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
{
int result = -1;
@@ -569,13 +625,21 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
START_PROFILE(syscall_ftruncate);
+ if (lp_strict_allocate(SNUM(fsp->conn))) {
+ result = strict_allocate_ftruncate(fsp, fd, len);
+ END_PROFILE(syscall_ftruncate);
+ return result;
+ }
+
/* we used to just check HAVE_FTRUNCATE_EXTEND and only use
sys_ftruncate if the system supports it. Then I discovered that
you can have some filesystems that support ftruncate
expansion and some that don't! On Linux fat can't do
ftruncate extend but ext2 can. */
+
result = sys_ftruncate(fd, len);
- if (result == 0) goto done;
+ if (result == 0)
+ goto done;
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
extend a file with ftruncate. Provide alternate implementation
@@ -589,7 +653,7 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
size in which case the ftruncate above should have
succeeded or shorter, in which case seek to len - 1 and
write 1 byte of zero */
- if (vfs_ops->fstat(fsp, fd, &st) < 0) {
+ if (vfs_ops->fstat(fsp, fd, &st) == -1) {
goto done;
}
@@ -610,19 +674,17 @@ int vfswrap_ftruncate(files_struct *fsp, int fd, SMB_OFF_T len)
goto done;
}
- if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1) {
+ if (vfs_ops->lseek(fsp, fd, len-1, SEEK_SET) != len -1)
goto done;
- }
- if (vfs_ops->write(fsp, fd, &c, 1)!=1) {
+ if (vfs_ops->write(fsp, fd, &c, 1)!=1)
goto done;
- }
/* Seek to where we were */
- if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos) {
+ if (vfs_ops->lseek(fsp, fd, currpos, SEEK_SET) != currpos)
goto done;
- }
result = 0;
+
done:
END_PROFILE(syscall_ftruncate);
@@ -672,6 +734,51 @@ int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_
return result;
}
+int vfswrap_link(connection_struct *conn, const char *oldpath, const char *newpath)
+{
+ int result;
+
+ START_PROFILE(syscall_link);
+
+#ifdef VFS_CHECK_NULL
+ if ((oldpath == NULL) || (newpath == NULL))
+ smb_panic("NULL pointer passed to vfswrap_link()\n");
+#endif
+ result = sys_link(oldpath, newpath);
+ END_PROFILE(syscall_link);
+ return result;
+}
+
+int vfswrap_mknod(connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
+{
+ int result;
+
+ START_PROFILE(syscall_mknod);
+
+#ifdef VFS_CHECK_NULL
+ if (pathname == NULL)
+ smb_panic("NULL pointer passed to vfswrap_mknod()\n");
+#endif
+ result = sys_mknod(pathname, mode, dev);
+ END_PROFILE(syscall_mknod);
+ return result;
+}
+
+char *vfswrap_realpath(connection_struct *conn, const char *path, char *resolved_path)
+{
+ char *result;
+
+ START_PROFILE(syscall_realpath);
+
+#ifdef VFS_CHECK_NULL
+ if ((path == NULL) || (resolved_path == NULL))
+ smb_panic("NULL pointer passed to vfswrap_realpath()\n");
+#endif
+ result = sys_realpath(path, resolved_path);
+ END_PROFILE(syscall_realpath);
+ return result;
+}
+
size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc)
{
size_t result;
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 8d049b51c4a..229880c9f15 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
/* Some structures to help us initialise the vfs operations table */
struct vfs_syminfo {
@@ -74,6 +72,9 @@ struct vfs_ops default_vfs_ops = {
vfswrap_lock,
vfswrap_symlink,
vfswrap_readlink,
+ vfswrap_link,
+ vfswrap_mknod,
+ vfswrap_realpath,
vfswrap_fget_nt_acl,
vfswrap_get_nt_acl,
@@ -240,6 +241,12 @@ static BOOL vfs_init_custom(connection_struct *conn)
if (conn->vfs_ops.readlink == NULL)
conn->vfs_ops.readlink = default_vfs_ops.readlink;
+ if (conn->vfs_ops.link == NULL)
+ conn->vfs_ops.link = default_vfs_ops.link;
+
+ if (conn->vfs_ops.mknod == NULL)
+ conn->vfs_ops.mknod = default_vfs_ops.mknod;
+
if (conn->vfs_ops.fget_nt_acl == NULL)
conn->vfs_ops.fget_nt_acl = default_vfs_ops.fget_nt_acl;
@@ -350,10 +357,10 @@ char *vfs_getwd(connection_struct *conn, char *unix_path)
}
/*******************************************************************
- Check if a vfs file exists.
+ Check if an object exists in the vfs.
********************************************************************/
-BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
+BOOL vfs_object_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_STAT st;
@@ -362,9 +369,26 @@ BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
ZERO_STRUCTP(sbuf);
- if (vfs_stat(conn,fname,sbuf) != 0)
+ if (vfs_stat(conn,fname,sbuf) == -1)
return(False);
+ return True;
+}
+/*******************************************************************
+ Check if a file exists in the vfs.
+********************************************************************/
+
+BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
+{
+ SMB_STRUCT_STAT st;
+
+ if (!sbuf)
+ sbuf = &st;
+
+ ZERO_STRUCTP(sbuf);
+
+ if (vfs_stat(conn,fname,sbuf) == -1)
+ return False;
return(S_ISREG(sbuf->st_mode));
}
@@ -399,19 +423,21 @@ ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N)
{
- size_t total=0;
- ssize_t ret;
+ size_t total=0;
+ ssize_t ret;
- while (total < N)
- {
- ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
+ while (total < N) {
+ ret = fsp->conn->vfs_ops.write(fsp,fsp->fd,buffer + total,N - total);
- if (ret == -1) return -1;
- if (ret == 0) return total;
+ if (ret == -1)
+ return -1;
+ if (ret == 0)
+ return total;
- total += ret;
- }
- return (ssize_t)total;
+ total += ret;
+ }
+
+ return (ssize_t)total;
}
/****************************************************************************
@@ -424,11 +450,11 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
{
int ret;
SMB_STRUCT_STAT st;
- struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
+ connection_struct *conn = fsp->conn;
+ struct vfs_ops *vfs_ops = &conn->vfs_ops;
+ SMB_OFF_T space_avail;
+ SMB_BIG_UINT bsize,dfree,dsize;
- if (!lp_strict_allocate(SNUM(fsp->conn)))
- return vfs_set_filelen(fsp, len);
-
release_level_2_oplocks_on_change(fsp);
/*
@@ -450,47 +476,30 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
fsp->fsp_name, (double)st.st_size ));
+ flush_write_cache(fsp, SIZECHANGE_FLUSH);
if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, len)) != -1) {
set_filelen_write_cache(fsp, len);
}
return ret;
}
- /* Grow - we need to write out the space.... */
- {
- static unsigned char zero_space[65536];
-
- SMB_OFF_T start_pos = st.st_size;
- SMB_OFF_T len_to_write = len - st.st_size;
- SMB_OFF_T retlen;
+ /* Grow - we need to test if we have enough space. */
- DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f\n",
- fsp->fsp_name, (double)st.st_size ));
+ if (!lp_strict_allocate(SNUM(fsp->conn)))
+ return 0;
- if ((retlen = vfs_ops->lseek(fsp, fsp->fd, start_pos, SEEK_SET)) != start_pos)
- return -1;
+ len -= st.st_size;
+ len /= 1024; /* Len is now number of 1k blocks needed. */
+ space_avail = (SMB_OFF_T)conn->vfs_ops.disk_free(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
- while ( len_to_write > 0) {
- SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),len_to_write);
-
- retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
- if (retlen <= 0) {
- /* Write fail - return to original size. */
- int save_errno = errno;
- fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, st.st_size);
- errno = save_errno;
- DEBUG(10,("vfs_allocate_file_space: file %s, grow. write fail %s\n",
- fsp->fsp_name, strerror(errno) ));
- return -1;
- }
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %lu, space avail = %lu\n",
+ fsp->fsp_name, (double)st.st_size, (unsigned long)len, (unsigned long)space_avail ));
- DEBUG(10,("vfs_allocate_file_space: file %s, grow. wrote %.0f\n",
- fsp->fsp_name, (double)retlen ));
-
- len_to_write -= retlen;
- }
- set_filelen_write_cache(fsp, len);
+ if (len > space_avail) {
+ errno = ENOSPC;
+ return -1;
}
+
return 0;
}
@@ -505,6 +514,8 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
int ret;
release_level_2_oplocks_on_change(fsp);
+ DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
+ flush_write_cache(fsp, SIZECHANGE_FLUSH);
if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1)
set_filelen_write_cache(fsp, len);
@@ -696,7 +707,7 @@ static void array_promote(char *array,int elsize,int element)
memcpy(p,array + element * elsize, elsize);
memmove(array + elsize,array,elsize*element);
memcpy(array,p,elsize);
- free(p);
+ SAFE_FREE(p);
}
/*******************************************************************
diff --git a/source/smbwrapper/shared.c b/source/smbwrapper/shared.c
index 5a9f6882981..a10ef05bfca 100644
--- a/source/smbwrapper/shared.c
+++ b/source/smbwrapper/shared.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
static int shared_fd;
static char *variables;
static int shared_size;
diff --git a/source/smbwrapper/smbsh.c b/source/smbwrapper/smbsh.c
index 8f3e0b70b44..ecf47a7ee08 100644
--- a/source/smbwrapper/smbsh.c
+++ b/source/smbwrapper/smbsh.c
@@ -21,6 +21,8 @@
#include "includes.h"
+extern BOOL AllowDebugChange;
+
static void smbsh_usage(void)
{
printf("smbsh [options]\n\n");
@@ -45,7 +47,14 @@ int main(int argc, char *argv[])
extern FILE *dbf;
dbf = stdout;
+
+ AllowDebugChange = False;
+ DEBUGLEVEL = 0;
+
charset_initialise();
+ lp_load(CONFIGFILE,True,False,False);
+ codepage_initialise(lp_client_code_page());
+
smbw_setup_shared();
while ((opt = getopt(argc, argv, "W:U:R:d:P:l:hL:")) != EOF) {
@@ -64,6 +73,7 @@ int main(int argc, char *argv[])
break;
case 'd':
smbw_setshared("DEBUG", optarg);
+ DEBUGLEVEL = atoi(optarg);
break;
case 'U':
p = strchr(optarg,'%');
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 89cc6b84d9f..8f60707f0b5 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -29,7 +29,7 @@ static struct smbw_server *smbw_srvs;
struct bitmap *smbw_file_bmap;
extern pstring global_myname;
-extern int DEBUGLEVEL;
+extern BOOL AllowDebugChange;
fstring smbw_prefix = SMBW_PREFIX;
@@ -60,6 +60,7 @@ void smbw_init(void)
smbw_busy++;
DEBUGLEVEL = 0;
+ AllowDebugChange = False;
setup_logging("smbsh",True);
dbf = stderr;
@@ -73,7 +74,7 @@ void smbw_init(void)
exit(1);
}
- charset_initialize();
+ charset_initialise();
in_client = True;
@@ -84,8 +85,7 @@ void smbw_init(void)
}
lp_load(servicesf,True,False,False);
-
- charset_initialize();
+ codepage_initialise(lp_client_code_page());
get_myname(global_myname);
@@ -280,17 +280,17 @@ static char *smbw_find_workgroup(void)
for (i=0;i<count;i++) {
static fstring name;
- if (name_status_find(0x1d, ip_list[i], name)) {
+ if (name_status_find("*", 0, 0x1d, ip_list[i], name)) {
slprintf(server, sizeof(server), "%s#1D", name);
if (smbw_server(server, "IPC$")) {
smbw_setshared("WORKGROUP", name);
- free(ip_list);
+ SAFE_FREE(ip_list);
return name;
}
}
}
- free(ip_list);
+ SAFE_FREE(ip_list);
return p;
}
@@ -403,17 +403,7 @@ return a unix errno from a SMB error pair
*******************************************************/
int smbw_errno(struct cli_state *c)
{
- uint8 eclass;
- uint32 ecode;
- int ret;
-
- ret = cli_error(c, &eclass, &ecode, NULL);
-
- if (ret) {
- DEBUG(3,("smbw_error %d %d (0x%x) -> %d\n",
- (int)eclass, (int)ecode, (int)ecode, ret));
- }
- return ret;
+ return cli_errno(c);
}
/* Return a username and password given a server and share name */
@@ -619,9 +609,9 @@ struct smbw_server *smbw_server(char *server, char *share)
cli_shutdown(&c);
if (!srv) return NULL;
- if (srv->server_name) free(srv->server_name);
- if (srv->share_name) free(srv->share_name);
- free(srv);
+ SAFE_FREE(srv->server_name);
+ SAFE_FREE(srv->share_name);
+ SAFE_FREE(srv);
return NULL;
}
@@ -735,12 +725,10 @@ int smbw_open(const char *fname, int flags, mode_t mode)
}
if (file) {
if (file->f) {
- if (file->f->fname) {
- free(file->f->fname);
- }
- free(file->f);
+ SAFE_FREE(file->f->fname);
+ SAFE_FREE(file->f);
}
- free(file);
+ SAFE_FREE(file);
}
smbw_busy--;
return -1;
@@ -905,11 +893,11 @@ int smbw_close(int fd)
file->f->ref_count--;
if (file->f->ref_count == 0) {
- free(file->f->fname);
- free(file->f);
+ SAFE_FREE(file->f->fname);
+ SAFE_FREE(file->f);
}
ZERO_STRUCTP(file);
- free(file);
+ SAFE_FREE(file);
smbw_busy--;
@@ -1397,14 +1385,14 @@ static void smbw_srv_close(struct smbw_server *srv)
cli_shutdown(&srv->cli);
- free(srv->server_name);
- free(srv->share_name);
+ SAFE_FREE(srv->server_name);
+ SAFE_FREE(srv->share_name);
DLIST_REMOVE(smbw_srvs, srv);
ZERO_STRUCTP(srv);
- free(srv);
+ SAFE_FREE(srv);
smbw_busy--;
}
diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c
index 1600d65a9ef..a056a2ae752 100644
--- a/source/smbwrapper/smbw_dir.c
+++ b/source/smbwrapper/smbw_dir.c
@@ -28,7 +28,6 @@ extern fstring smbw_prefix;
static struct smbw_dir *smbw_dirs;
extern struct bitmap *smbw_file_bmap;
-extern int DEBUGLEVEL;
extern int smbw_busy;
@@ -64,12 +63,10 @@ free a smbw_dir structure and all entries
*******************************************************/
static void free_dir(struct smbw_dir *dir)
{
- if (dir->list) {
- free(dir->list);
- }
- if (dir->path) free(dir->path);
+ SAFE_FREE(dir->list);
+ SAFE_FREE(dir->path);
ZERO_STRUCTP(dir);
- free(dir);
+ SAFE_FREE(dir);
}
diff --git a/source/smbwrapper/smbw_stat.c b/source/smbwrapper/smbw_stat.c
index 926075c864f..cf2d19cdf09 100644
--- a/source/smbwrapper/smbw_stat.c
+++ b/source/smbwrapper/smbw_stat.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern int smbw_busy;
diff --git a/source/smbwrapper/wrapped.c b/source/smbwrapper/wrapped.c
index b8787a00c01..904ae68f928 100644
--- a/source/smbwrapper/wrapped.c
+++ b/source/smbwrapper/wrapped.c
@@ -462,6 +462,13 @@
#endif
#ifdef HAVE_UTIMES
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
int utimes(const char *name, const struct timeval *tvp)
{
if (smbw_path(name)) {
diff --git a/source/tdb/.cvsignore b/source/tdb/.cvsignore
index afd8da72c94..f03986b8a2c 100644
--- a/source/tdb/.cvsignore
+++ b/source/tdb/.cvsignore
@@ -1,3 +1,5 @@
+*.po
+*.po32
tdbtool
tdbtest
tdbtorture
diff --git a/source/tdb/Makefile b/source/tdb/Makefile
index 5945469737c..b29bedf92c7 100644
--- a/source/tdb/Makefile
+++ b/source/tdb/Makefile
@@ -19,5 +19,8 @@ tdbtool: tdbtool.o $(TDB_OBJ)
tdbtorture: tdbtorture.o $(TDB_OBJ)
$(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ)
+tdbdump: tdbdump.o $(TDB_OBJ)
+ $(CC) $(CFLAGS) -o tdbdump tdbdump.o $(TDB_OBJ)
+
clean:
rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm
diff --git a/source/tdb/README b/source/tdb/README
index fac3eacb4db..3715c685c20 100644
--- a/source/tdb/README
+++ b/source/tdb/README
@@ -60,7 +60,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
The hash size is advisory, use zero for a default value.
- return is NULL on error
+ Return is NULL on error, in which case errno is also set. Don't
+ try to call tdb_error or tdb_errname, just do strerror(errno).
possible tdb_flags are:
TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open
diff --git a/source/tdb/spinlock.c b/source/tdb/spinlock.c
index 0a68981ca2f..b00d115dde7 100644
--- a/source/tdb/spinlock.c
+++ b/source/tdb/spinlock.c
@@ -18,11 +18,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if STANDALONE
#if HAVE_CONFIG_H
#include <config.h>
#endif
+#if STANDALONE
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
@@ -384,11 +384,11 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
/* Write it out (appending to end) */
if (write(fd, rwlocks, size) != size) {
- free(rwlocks);
+ SAFE_FREE(rwlocks);
return -1;
}
smp_machine = this_is_smp();
- free(rwlocks);
+ SAFE_FREE(rwlocks);
return 0;
}
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index 7e6fd34fd7a..5a871e7fcc6 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -1,4 +1,4 @@
-/*
+ /*
Unix SMB/Netbios implementation.
Version 3.0
Samba database functions
@@ -56,6 +56,10 @@
#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
+
+/* NB assumes there is a local variable called "tdb" that is the
+ * current context, also takes doubly-parenthesized print-style
+ * argument. */
#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0)
/* lock offsets */
@@ -70,6 +74,11 @@
#define MAP_FAILED ((void *)-1)
#endif
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
#define BUCKET(hash) ((hash) % tdb->header.hash_size)
TDB_DATA tdb_null;
@@ -149,7 +158,10 @@ struct list_struct {
};
/* a byte range locking function - return 0 on success
- this functions locks/unlocks 1 byte at the specified offset */
+ this functions locks/unlocks 1 byte at the specified offset.
+
+ On error, errno is also set so that errors are passed back properly
+ through tdb_open(). */
static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
int rw_type, int lck_type, int probe)
{
@@ -157,8 +169,10 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
if (tdb->flags & TDB_NOLOCK)
return 0;
- if (tdb->read_only)
+ if (tdb->read_only) {
+ errno = EACCES;
return -1;
+ }
fl.l_type = rw_type;
fl.l_whence = SEEK_SET;
@@ -166,11 +180,12 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
fl.l_len = 1;
fl.l_pid = 0;
- if (fcntl(tdb->fd,lck_type,&fl)) {
+ if (fcntl(tdb->fd,lck_type,&fl) == -1) {
if (!probe) {
- TDB_LOG((tdb, 5,"tdb_brlock failed at offset %d rw_type=%d lck_type=%d\n",
- offset, rw_type, lck_type));
+ TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
+ tdb->fd, offset, rw_type, lck_type));
}
+ /* errno set by fcntl */
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
return 0;
@@ -190,9 +205,9 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype)
/* Since fcntl locks don't nest, we do a lock for the first one,
and simply bump the count for future ones */
if (tdb->locked[list+1].count == 0) {
- if (tdb->header.rwlocks) {
+ if (!tdb->read_only && tdb->header.rwlocks) {
if (tdb_spinlock(tdb, list, ltype)) {
- TDB_LOG((tdb, 0, "tdb_lock spinlock on list ltype=%d\n",
+ TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list ltype=%d\n",
list, ltype));
return -1;
}
@@ -221,7 +236,7 @@ static void tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype)
if (tdb->locked[list+1].count == 1) {
/* Down to last nested lock: unlock underneath */
- if (tdb->header.rwlocks)
+ if (!tdb->read_only && tdb->header.rwlocks)
tdb_spinunlock(tdb, list, ltype);
else
tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0);
@@ -333,7 +348,7 @@ static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len)
return TDB_ERRCODE(TDB_ERR_OOM, buf);
}
if (tdb_read(tdb, offset, buf, len, 0) == -1) {
- free(buf);
+ SAFE_FREE(buf);
return NULL;
}
return buf;
@@ -394,7 +409,6 @@ static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset,
&totalsize);
}
-#ifdef TDB_DEBUG
static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset)
{
struct list_struct rec;
@@ -415,7 +429,8 @@ static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset)
}
if (tailer != rec.rec_len + sizeof(rec)) {
- printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", tailer, rec.rec_len + sizeof(rec));
+ printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
+ (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec)));
}
return rec.next;
}
@@ -444,7 +459,6 @@ static void tdb_dump_chain(TDB_CONTEXT *tdb, int i)
void tdb_dump_all(TDB_CONTEXT *tdb)
{
- tdb_off off;
int i;
for (i=0;i<tdb->header.hash_size;i++) {
tdb_dump_chain(tdb, i);
@@ -456,12 +470,11 @@ void tdb_dump_all(TDB_CONTEXT *tdb)
void tdb_printfreelist(TDB_CONTEXT *tdb)
{
long total_free = 0;
- tdb_off offset, rec_ptr, last_ptr;
- struct list_struct rec, lastrec, newrec;
+ tdb_off offset, rec_ptr;
+ struct list_struct rec;
tdb_lock(tdb, -1, F_WRLCK);
- last_ptr = 0;
offset = FREELIST_TOP;
/* read in the freelist top */
@@ -486,11 +499,11 @@ void tdb_printfreelist(TDB_CONTEXT *tdb)
/* move to the next record */
rec_ptr = rec.next;
}
- printf("total rec_len = [0x%08x (%d)]\n", total_free, total_free );
+ printf("total rec_len = [0x%08x (%d)]\n", (int)total_free,
+ (int)total_free);
tdb_unlock(tdb, -1, F_WRLCK);
}
-#endif
/* Remove an element from the freelist. Must have alloc lock. */
static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next)
@@ -847,7 +860,7 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
ret = tdb_create_rwlocks(tdb->fd, hash_size);
fail:
- free(newdb);
+ SAFE_FREE(newdb);
return ret;
}
@@ -876,10 +889,10 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash,
return 0;
if (memcmp(key.dptr, k, key.dsize) == 0) {
- free(k);
+ SAFE_FREE(k);
return rec_ptr;
}
- free(k);
+ SAFE_FREE(k);
}
rec_ptr = r->next;
}
@@ -1187,10 +1200,10 @@ int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state)
/* They want us to terminate traversal */
unlock_record(tdb, tl.off);
tdb->travlocks.next = tl.next;
- free(key.dptr);
+ SAFE_FREE(key.dptr);
return count;
}
- free(key.dptr);
+ SAFE_FREE(key.dptr);
}
tdb->travlocks.next = tl.next;
if (ret < 0)
@@ -1240,8 +1253,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
tdb->travlocks.off = 0;
}
- if (k)
- free(k);
+ SAFE_FREE(k);
}
if (!tdb->travlocks.off) {
@@ -1359,161 +1371,221 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
ret = -1;
}
out:
- if (p)
- free(p);
+ SAFE_FREE(p);
tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
return ret;
}
+static int tdb_already_open(dev_t device,
+ ino_t ino)
+{
+ TDB_CONTEXT *i = NULL;
+
+ for (i = tdbs; i; i = i->next) {
+ if (i->device == device && i->inode == ino) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* open the database, creating it if necessary
The open_flags and mode are passed straight to the open call on the
database file. A flags value of O_WRONLY is invalid. The hash size
is advisory, use zero for a default value.
- return is NULL on error */
-TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
+ Return is NULL on error, in which case errno is also set. Don't
+ try to call tdb_error or tdb_errname, just do strerror(errno).
+
+ @param name may be NULL for internal databases. */
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode)
{
- TDB_CONTEXT tdb, *ret, *i;
+ return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL);
+}
+
+
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn)
+{
+ TDB_CONTEXT *tdb = NULL;
struct stat st;
int rev = 0, locked;
- memset(&tdb, 0, sizeof(tdb));
- tdb.fd = -1;
- tdb.name = NULL;
- tdb.map_ptr = NULL;
- tdb.lockedkeys = NULL;
- tdb.flags = tdb_flags;
- tdb.open_flags = open_flags;
-
- if ((open_flags & O_ACCMODE) == O_WRONLY)
+ if (!(tdb = calloc(1, sizeof *tdb))) {
+ /* Can't log this */
+ errno = ENOMEM;
goto fail;
+ }
+ tdb->fd = -1;
+ tdb->name = NULL;
+ tdb->map_ptr = NULL;
+ tdb->lockedkeys = NULL;
+ tdb->flags = tdb_flags;
+ tdb->open_flags = open_flags;
+ tdb->log_fn = log_fn;
+
+ if ((open_flags & O_ACCMODE) == O_WRONLY) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n",
+ name));
+ errno = EINVAL;
+ goto fail;
+ }
+
if (hash_size == 0)
hash_size = DEFAULT_HASH_SIZE;
if ((open_flags & O_ACCMODE) == O_RDONLY) {
- tdb.read_only = 1;
+ tdb->read_only = 1;
/* read only databases don't do locking or clear if first */
- tdb.flags |= TDB_NOLOCK;
- tdb.flags &= ~TDB_CLEAR_IF_FIRST;
+ tdb->flags |= TDB_NOLOCK;
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
}
/* internal databases don't mmap or lock, and start off cleared */
- if (tdb.flags & TDB_INTERNAL) {
- tdb.flags |= (TDB_NOLOCK | TDB_NOMMAP);
- tdb.flags &= ~TDB_CLEAR_IF_FIRST;
- tdb_new_database(&tdb, hash_size);
+ if (tdb->flags & TDB_INTERNAL) {
+ tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ tdb_new_database(tdb, hash_size);
goto internal;
}
- if ((tdb.fd = open(name, open_flags, mode)) == -1)
- goto fail;
+ if ((tdb->fd = open(name, open_flags, mode)) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: could not open file %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by open(2) */
+ }
/* ensure there is only one process initialising at once */
- if (tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1)
- goto fail;
+ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by tdb_brlock */
+ }
/* we need to zero database if we are the only one with it open */
- if ((locked = (tdb_brlock(&tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
+ if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
&& (tdb_flags & TDB_CLEAR_IF_FIRST)) {
open_flags |= O_CREAT;
- if (ftruncate(tdb.fd, 0) == -1)
- goto fail;
+ if (ftruncate(tdb->fd, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: "
+ "failed to truncate %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by ftruncate */
+ }
}
- if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header)
- || strcmp(tdb.header.magic_food, TDB_MAGIC_FOOD) != 0
- || (tdb.header.version != TDB_VERSION
- && !(rev = (tdb.header.version==TDB_BYTEREV(TDB_VERSION))))) {
+ if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
+ || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
+ || (tdb->header.version != TDB_VERSION
+ && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
/* its not a valid database - possibly initialise it */
- if (!(open_flags & O_CREAT) || tdb_new_database(&tdb, hash_size) == -1)
+ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
+ errno = EIO; /* ie bad format or something */
goto fail;
- rev = (tdb.flags & TDB_CONVERT);
+ }
+ rev = (tdb->flags & TDB_CONVERT);
}
if (!rev)
- tdb.flags &= ~TDB_CONVERT;
+ tdb->flags &= ~TDB_CONVERT;
else {
- tdb.flags |= TDB_CONVERT;
- convert(&tdb.header, sizeof(tdb.header));
+ tdb->flags |= TDB_CONVERT;
+ convert(&tdb->header, sizeof(tdb->header));
}
- if (fstat(tdb.fd, &st) == -1)
+ if (fstat(tdb->fd, &st) == -1)
goto fail;
/* Is it already in the open list? If so, fail. */
- for (i = tdbs; i; i = i->next) {
- if (i->device == st.st_dev && i->inode == st.st_ino) {
- errno = EBUSY;
- close(tdb.fd);
- return NULL;
- }
+ if (tdb_already_open(st.st_dev, st.st_ino)) {
+ TDB_LOG((tdb, 2, "tdb_open_ex: "
+ "%s (%d,%d) is already open in this process\n",
+ name, st.st_dev, st.st_ino));
+ errno = EBUSY;
+ goto fail;
}
- /* map the database and fill in the return structure */
- tdb.name = (char *)strdup(name);
- if (!tdb.name)
+ if (!(tdb->name = (char *)strdup(name))) {
+ errno = ENOMEM;
goto fail;
- tdb.map_size = st.st_size;
- tdb.device = st.st_dev;
- tdb.inode = st.st_ino;
- tdb.locked = calloc(tdb.header.hash_size+1, sizeof(tdb.locked[0]));
- if (!tdb.locked)
+ }
+
+ tdb->map_size = st.st_size;
+ tdb->device = st.st_dev;
+ tdb->inode = st.st_ino;
+ tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0]));
+ if (!tdb->locked) {
+ TDB_LOG((tdb, 2, "tdb_open_ex: "
+ "failed to allocate lock structure for %s\n",
+ name));
+ errno = ENOMEM;
goto fail;
- tdb_mmap(&tdb);
+ }
+ tdb_mmap(tdb);
if (locked) {
- tdb_clear_spinlocks(&tdb);
- if (tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1)
+ if (!tdb->read_only)
+ tdb_clear_spinlocks(tdb);
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: "
+ "failed to take ACTIVE_LOCK on %s: %s\n",
+ name, strerror(errno)));
goto fail;
+ }
}
/* leave this lock in place to indicate it's in use */
- if (tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
goto fail;
internal:
- if (!(ret = malloc(sizeof(tdb))))
+ /* Internal (memory-only) databases skip all the code above to
+ * do with disk files, and resume here by releasing their
+ * global lock and hooking into the active list. */
+ if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1)
goto fail;
- *ret = tdb;
- if (tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1)
- goto fail;
- ret->next = tdbs;
- tdbs = ret;
- return ret;
+ tdb->next = tdbs;
+ tdbs = tdb;
+ return tdb;
fail:
- if (tdb.map_ptr) {
- if (tdb.flags & TDB_INTERNAL)
- free(tdb.map_ptr);
+ { int save_errno = errno;
+
+ if (!tdb)
+ return NULL;
+
+ if (tdb->map_ptr) {
+ if (tdb->flags & TDB_INTERNAL)
+ SAFE_FREE(tdb->map_ptr);
else
- tdb_munmap(&tdb);
- }
- if (tdb.name)
- free(tdb.name);
- if (tdb.fd != -1)
- close(tdb.fd);
- if (tdb.locked)
- free(tdb.locked);
+ tdb_munmap(tdb);
+ }
+ SAFE_FREE(tdb->name);
+ if (tdb->fd != -1)
+ close(tdb->fd);
+ SAFE_FREE(tdb->locked);
+ SAFE_FREE(tdb);
+ errno = save_errno;
return NULL;
+ }
}
/* close a database */
int tdb_close(TDB_CONTEXT *tdb)
{
- TDB_CONTEXT **i;
+ TDB_CONTEXT **i = NULL;
int ret = 0;
if (tdb->map_ptr) {
if (tdb->flags & TDB_INTERNAL)
- free(tdb->map_ptr);
+ SAFE_FREE(tdb->map_ptr);
else
tdb_munmap(tdb);
}
- if (tdb->name)
- free(tdb->name);
+ SAFE_FREE(tdb->name);
if (tdb->fd != -1)
ret = close(tdb->fd);
- if (tdb->locked)
- free(tdb->locked);
- if (tdb->lockedkeys)
- free(tdb->lockedkeys);
+ SAFE_FREE(tdb->locked);
+ SAFE_FREE(tdb->lockedkeys);
/* Remove from contexts list */
for (i = &tdbs; *i; i = &(*i)->next) {
@@ -1524,7 +1596,7 @@ int tdb_close(TDB_CONTEXT *tdb)
}
memset(tdb, 0, sizeof(*tdb));
- free(tdb);
+ SAFE_FREE(tdb);
return ret;
}
@@ -1589,8 +1661,7 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
if (i < number) {
for ( j = 0; j < i; j++)
tdb_unlock(tdb, j, F_WRLCK);
- free(tdb->lockedkeys);
- tdb->lockedkeys = NULL;
+ SAFE_FREE(tdb->lockedkeys);
return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
}
return 0;
@@ -1602,8 +1673,7 @@ void tdb_unlockkeys(TDB_CONTEXT *tdb)
u32 i;
for (i = 0; i < tdb->lockedkeys[0]; i++)
tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK);
- free(tdb->lockedkeys);
- tdb->lockedkeys = NULL;
+ SAFE_FREE(tdb->lockedkeys);
}
/* lock/unlock one hash chain. This is meant to be used to reduce
@@ -1659,7 +1729,7 @@ fail:
/* reopen all tdb's */
int tdb_reopen_all(void)
{
- TDB_CONTEXT *tdb;
+ TDB_CONTEXT *tdb = NULL;
for (tdb=tdbs; tdb; tdb = tdb->next) {
if (tdb_reopen(tdb) != 0) return -1;
diff --git a/source/tdb/tdb.h b/source/tdb/tdb.h
index 4efe263ee85..9335725a2ac 100644
--- a/source/tdb/tdb.h
+++ b/source/tdb/tdb.h
@@ -99,10 +99,17 @@ typedef struct tdb_context {
} TDB_CONTEXT;
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
+typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...);
-TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
-void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...));
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn);
+
+int tdb_reopen(TDB_CONTEXT *tdb);
+int tdb_reopen_all(void);
+void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func);
enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
const char *tdb_errorstr(TDB_CONTEXT *tdb);
TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
@@ -121,7 +128,13 @@ void tdb_unlockall(TDB_CONTEXT *tdb);
/* Low level locking functions: use with care */
int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
+
+/* Debug functions. Not used in production. */
+void tdb_dump_all(TDB_CONTEXT *tdb);
+void tdb_printfreelist(TDB_CONTEXT *tdb);
+
extern TDB_DATA tdb_null;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/tdb/tdbtest.c b/source/tdb/tdbtest.c
index 2cc7e887297..80e9c8d07e6 100644
--- a/source/tdb/tdbtest.c
+++ b/source/tdb/tdbtest.c
@@ -23,12 +23,12 @@ static GDBM_FILE gdbm;
struct timeval tp1,tp2;
-static void start_timer()
+static void start_timer(void)
{
gettimeofday(&tp1,NULL);
}
-static double end_timer()
+static double end_timer(void)
{
gettimeofday(&tp2,NULL);
return((tp2.tv_sec - tp1.tv_sec) +
@@ -48,6 +48,7 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
+ fflush(stdout);
}
static void compare_db(void)
@@ -70,9 +71,9 @@ static void compare_db(void)
}
nextkey = tdb_nextkey(db, key);
- free(key.dptr);
- free(d.dptr);
- free(gd.dptr);
+ SAFE_FREE(key.dptr);
+ SAFE_FREE(d.dptr);
+ SAFE_FREE(gd.dptr);
key = nextkey;
}
@@ -91,9 +92,9 @@ static void compare_db(void)
}
gnextkey = gdbm_nextkey(gdbm, gkey);
- free(gkey.dptr);
- free(gd.dptr);
- free(d.dptr);
+ SAFE_FREE(gkey.dptr);
+ SAFE_FREE(gd.dptr);
+ SAFE_FREE(d.dptr);
gkey = gnextkey;
}
}
@@ -137,11 +138,11 @@ static void addrec_db(void)
}
} else {
data = tdb_fetch(db, key);
- if (data.dptr) free(data.dptr);
+ SAFE_FREE(data.dptr);
}
- free(k);
- free(d);
+ SAFE_FREE(k);
+ SAFE_FREE(d);
}
static void addrec_gdbm(void)
@@ -170,57 +171,51 @@ static void addrec_gdbm(void)
}
} else {
data = gdbm_fetch(gdbm, key);
- if (data.dptr) free(data.dptr);
+ SAFE_FREE(data.dptr);
}
- free(k);
- free(d);
+ SAFE_FREE(k);
+ SAFE_FREE(d);
}
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
#if 0
printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
#endif
- tdb_delete(db, key);
+ tdb_delete(tdb, key);
return 0;
}
-static void merge_test()
+static void merge_test(void)
{
- int klen, dlen;
- int i;
+ int i;
char keys[5][2];
- TDB_DATA key, data;
-
+ TDB_DATA key, data;
+
for (i = 0; i < 5; i++) {
sprintf(keys[i], "%d", i);
- key.dptr = keys[i];
- key.dsize = 2;
-
- data.dptr = "test";
- data.dsize = 4;
-
- if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
- fatal("tdb_store failed");
- }
+ key.dptr = keys[i];
+ key.dsize = 2;
+
+ data.dptr = "test";
+ data.dsize = 4;
+
+ if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
+ fatal("tdb_store failed");
+ }
}
key.dptr = keys[0];
tdb_delete(db, key);
- tdb_printfreelist(db);
key.dptr = keys[4];
tdb_delete(db, key);
- tdb_printfreelist(db);
key.dptr = keys[2];
tdb_delete(db, key);
- tdb_printfreelist(db);
key.dptr = keys[1];
tdb_delete(db, key);
- tdb_printfreelist(db);
key.dptr = keys[3];
tdb_delete(db, key);
- tdb_printfreelist(db);
}
int main(int argc, char *argv[])
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 8b396ca5a2a..d1c199849b3 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -1,3 +1,27 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba database functions
+ Copyright (C) Andrew Tridgell 1999-2000
+ Copyright (C) Paul `Rusty' Russell 2000
+ Copyright (C) Jeremy Allison 2000
+ Copyright (C) Andrew Esh 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
@@ -5,6 +29,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <time.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -13,7 +38,7 @@
/* a tdb tool for manipulating a tdb database */
-#define FSTRING_LEN 128
+#define FSTRING_LEN 256
typedef char fstring[FSTRING_LEN];
typedef struct connections_key {
@@ -36,11 +61,18 @@ typedef struct connections_data {
static TDB_CONTEXT *tdb;
-static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state);
static void print_asc(unsigned char *buf,int len)
{
int i;
+
+ /* We're probably printing ASCII strings so don't try to display
+ the trailing NULL character. */
+
+ if (buf[len - 1] == 0)
+ len--;
+
for (i=0;i<len;i++)
printf("%c",isprint(buf[i])?buf[i]:'.');
}
@@ -89,6 +121,7 @@ tdbtool:
store key data : store a record (replace)
show key : show a record by key
delete key : delete a record by key
+ list : print the database hash table and freelist
free : print the database freelist
1 | first : print the first record
n | next : print the next record
@@ -102,9 +135,40 @@ static void terror(char *why)
printf("%s\n", why);
}
+static char *get_token(int startover)
+{
+ static char tmp[1024];
+ static char *cont = NULL;
+ char *insert, *start;
+ char *k = strtok(NULL, " ");
+
+ if (!k)
+ return NULL;
+
+ if (startover)
+ start = tmp;
+ else
+ start = cont;
+
+ strcpy(start, k);
+ insert = start + strlen(start) - 1;
+ while (*insert == '\\') {
+ *insert++ = ' ';
+ k = strtok(NULL, " ");
+ if (!k)
+ break;
+ strcpy(insert, k);
+ insert = start + strlen(start) - 1;
+ }
+
+ /* Get ready for next call */
+ cont = start + strlen(start) + 1;
+ return start;
+}
+
static void create_tdb(void)
{
- char *tok = strtok(NULL, " ");
+ char *tok = get_token(1);
if (!tok) {
help();
return;
@@ -119,7 +183,7 @@ static void create_tdb(void)
static void open_tdb(void)
{
- char *tok = strtok(NULL, " ");
+ char *tok = get_token(1);
if (!tok) {
help();
return;
@@ -133,8 +197,8 @@ static void open_tdb(void)
static void insert_tdb(void)
{
- char *k = strtok(NULL, " ");
- char *d = strtok(NULL, " ");
+ char *k = get_token(1);
+ char *d = get_token(0);
TDB_DATA key, dbuf;
if (!k || !d) {
@@ -143,9 +207,9 @@ static void insert_tdb(void)
}
key.dptr = k;
- key.dsize = strlen(k);
+ key.dsize = strlen(k)+1;
dbuf.dptr = d;
- dbuf.dsize = strlen(d);
+ dbuf.dsize = strlen(d)+1;
if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) {
terror("insert failed");
@@ -154,8 +218,8 @@ static void insert_tdb(void)
static void store_tdb(void)
{
- char *k = strtok(NULL, " ");
- char *d = strtok(NULL, " ");
+ char *k = get_token(1);
+ char *d = get_token(0);
TDB_DATA key, dbuf;
if (!k || !d) {
@@ -164,9 +228,12 @@ static void store_tdb(void)
}
key.dptr = k;
- key.dsize = strlen(k);
+ key.dsize = strlen(k)+1;
dbuf.dptr = d;
- dbuf.dsize = strlen(d);
+ dbuf.dsize = strlen(d)+1;
+
+ printf("Storing key:\n");
+ print_rec(tdb, key, dbuf, NULL);
if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
terror("store failed");
@@ -175,7 +242,7 @@ static void store_tdb(void)
static void show_tdb(void)
{
- char *k = strtok(NULL, " ");
+ char *k = get_token(1);
TDB_DATA key, dbuf;
if (!k) {
@@ -187,14 +254,17 @@ static void show_tdb(void)
key.dsize = strlen(k)+1;
dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr) terror("fetch failed");
+ if (!dbuf.dptr) {
+ terror("fetch failed");
+ return;
+ }
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
print_rec(tdb, key, dbuf, NULL);
}
static void delete_tdb(void)
{
- char *k = strtok(NULL, " ");
+ char *k = get_token(1);
TDB_DATA key;
if (!k) {
@@ -203,13 +273,14 @@ static void delete_tdb(void)
}
key.dptr = k;
- key.dsize = strlen(k);
+ key.dsize = strlen(k)+1;
if (tdb_delete(tdb, key) != 0) {
terror("delete failed");
}
}
+#if 0
static int print_conn_key(TDB_DATA key)
{
printf( "pid =%5d ", ((connections_key*)key.dptr)->pid);
@@ -231,8 +302,9 @@ static int print_conn_data(TDB_DATA dbuf)
printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start));
return 0;
}
+#endif
-static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
#if 0
print_conn_key(key);
@@ -240,16 +312,23 @@ static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
return 0;
#else
printf("\nkey %d bytes\n", key.dsize);
- print_data(key.dptr, key.dsize);
- printf("data %d bytes\n", dbuf.dsize);
+ print_asc(key.dptr, key.dsize);
+ printf("\ndata %d bytes\n", dbuf.dsize);
print_data(dbuf.dptr, dbuf.dsize);
return 0;
#endif
}
+static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+ print_asc(key.dptr, key.dsize);
+ printf("\n");
+ return 0;
+}
+
static int total_bytes;
-static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
total_bytes += dbuf.dsize;
return 0;
@@ -265,7 +344,7 @@ static void info_tdb(void)
printf("%d records totalling %d bytes\n", count, total_bytes);
}
-static char *getline(char *prompt)
+static char *tdb_getline(char *prompt)
{
static char line[1024];
char *p;
@@ -277,34 +356,34 @@ static char *getline(char *prompt)
return p?line:NULL;
}
-static int do_delete_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
+static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
- return tdb_delete(tdb, key);
+ return tdb_delete(the_tdb, key);
}
-static void first_record(TDB_CONTEXT *tdb, TDB_DATA *pkey)
+static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
{
TDB_DATA dbuf;
- *pkey = tdb_firstkey(tdb);
+ *pkey = tdb_firstkey(the_tdb);
- dbuf = tdb_fetch(tdb, *pkey);
+ dbuf = tdb_fetch(the_tdb, *pkey);
if (!dbuf.dptr) terror("fetch failed");
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
- print_rec(tdb, *pkey, dbuf, NULL);
+ print_rec(the_tdb, *pkey, dbuf, NULL);
}
-static void next_record(TDB_CONTEXT *tdb, TDB_DATA *pkey)
+static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey)
{
TDB_DATA dbuf;
- *pkey = tdb_nextkey(tdb, *pkey);
+ *pkey = tdb_nextkey(the_tdb, *pkey);
- dbuf = tdb_fetch(tdb, *pkey);
+ dbuf = tdb_fetch(the_tdb, *pkey);
if (!dbuf.dptr)
terror("fetch failed");
else
/* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */
- print_rec(tdb, *pkey, dbuf, NULL);
+ print_rec(the_tdb, *pkey, dbuf, NULL);
}
int main(int argc, char *argv[])
@@ -321,7 +400,7 @@ int main(int argc, char *argv[])
open_tdb();
}
- while ((line = getline("tdb> "))) {
+ while ((line = tdb_getline("tdb> "))) {
/* Shell command */
@@ -342,7 +421,10 @@ int main(int argc, char *argv[])
} else if (strcmp(tok,"open") == 0) {
open_tdb();
continue;
- }
+ } else if ((strcmp(tok, "q") == 0) ||
+ (strcmp(tok, "quit") == 0)) {
+ break;
+ }
/* all the rest require a open database */
if (!tdb) {
@@ -372,10 +454,10 @@ int main(int argc, char *argv[])
tdb_traverse(tdb, print_rec, NULL);
} else if (strcmp(tok,"list") == 0) {
tdb_dump_all(tdb);
- } else if (strcmp(tok,"info") == 0) {
- info_tdb();
} else if (strcmp(tok, "free") == 0) {
tdb_printfreelist(tdb);
+ } else if (strcmp(tok,"info") == 0) {
+ info_tdb();
} else if ( (strcmp(tok, "1") == 0) ||
(strcmp(tok, "first") == 0)) {
bIterate = 1;
@@ -383,9 +465,9 @@ int main(int argc, char *argv[])
} else if ((strcmp(tok, "n") == 0) ||
(strcmp(tok, "next") == 0)) {
next_record(tdb, &iterate_kbuf);
- } else if ((strcmp(tok, "q") == 0) ||
- (strcmp(tok, "quit") == 0)) {
- break;
+ } else if ((strcmp(tok, "keys") == 0)) {
+ bIterate = 0;
+ tdb_traverse(tdb, print_key, NULL);
} else {
help();
}
diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c
index 1a3b715402d..0cdb60db6ee 100644
--- a/source/tdb/tdbtorture.c
+++ b/source/tdb/tdbtorture.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
@@ -17,12 +18,15 @@
-#define DELETE_PROB 10
-#define STORE_PROB 3
-#define TRAVERSE_PROB 8
-#define CULL_PROB 60
+#define REOPEN_PROB 30
+#define DELETE_PROB 8
+#define STORE_PROB 4
+#define LOCKSTORE_PROB 0
+#define TRAVERSE_PROB 20
+#define CULL_PROB 100
#define KEYLEN 3
#define DATALEN 100
+#define LOCKLEN 20
static TDB_CONTEXT *db;
@@ -33,12 +37,13 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
+ fflush(stdout);
#if 0
{
char *ptr;
asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
system(ptr);
- free(ptr);
+ SAFE_FREE(ptr);
}
#endif
}
@@ -62,26 +67,28 @@ static char *randbuf(int len)
return buf;
}
-static int cull_traverse(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf,
+static int cull_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
if (random() % CULL_PROB == 0) {
- tdb_delete(db, key);
+ tdb_delete(tdb, key);
}
return 0;
}
static void addrec_db(void)
{
- int klen, dlen;
- char *k, *d;
- TDB_DATA key, data;
+ int klen, dlen, slen;
+ char *k, *d, *s;
+ TDB_DATA key, data, lockkey;
klen = 1 + (rand() % KEYLEN);
dlen = 1 + (rand() % DATALEN);
+ slen = 1 + (rand() % LOCKLEN);
k = randbuf(klen);
d = randbuf(dlen);
+ s = randbuf(slen);
key.dptr = k;
key.dsize = klen+1;
@@ -89,27 +96,65 @@ static void addrec_db(void)
data.dptr = d;
data.dsize = dlen+1;
+ lockkey.dptr = s;
+ lockkey.dsize = slen+1;
+
+#if REOPEN_PROB
+ if (random() % REOPEN_PROB == 0) {
+ tdb_reopen_all();
+ goto next;
+ }
+#endif
+
+#if DELETE_PROB
if (random() % DELETE_PROB == 0) {
tdb_delete(db, key);
- } else if (random() % STORE_PROB == 0) {
+ goto next;
+ }
+#endif
+
+#if STORE_PROB
+ if (random() % STORE_PROB == 0) {
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
- } else if (random() % TRAVERSE_PROB == 0) {
- tdb_traverse(db, cull_traverse, NULL);
- } else {
+ goto next;
+ }
+#endif
+
+#if LOCKSTORE_PROB
+ if (random() % LOCKSTORE_PROB == 0) {
+ tdb_chainlock(db, lockkey);
data = tdb_fetch(db, key);
- if (data.dptr) free(data.dptr);
+ if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
+ fatal("tdb_store failed");
+ }
+ SAFE_FREE(data.dptr);
+ tdb_chainunlock(db, lockkey);
+ goto next;
+ }
+#endif
+
+#if TRAVERSE_PROB
+ if (random() % TRAVERSE_PROB == 0) {
+ tdb_traverse(db, cull_traverse, NULL);
+ goto next;
}
+#endif
+
+ data = tdb_fetch(db, key);
+ SAFE_FREE(data.dptr);
- free(k);
- free(d);
+next:
+ SAFE_FREE(k);
+ SAFE_FREE(d);
+ SAFE_FREE(s);
}
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf,
+static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
- tdb_delete(db, key);
+ tdb_delete(tdb, key);
return 0;
}
@@ -133,7 +178,7 @@ int main(int argc, char *argv[])
if ((pids[i+1]=fork()) == 0) break;
}
- db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST,
+ db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT, 0600);
if (!db) {
fatal("db open failed");
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index da4f6718d4c..87dabf165d4 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -24,7 +24,10 @@
/* these are little tdb utility functions that are meant to make
dealing with a tdb database a little less cumbersome in Samba */
-/* lock a chain by string */
+/****************************************************************************
+ Lock a chain by string.
+****************************************************************************/
+
int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
{
TDB_DATA key;
@@ -35,7 +38,10 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
return tdb_chainlock(tdb, key);
}
-/* unlock a chain by string */
+/****************************************************************************
+ Unlock a chain by string.
+****************************************************************************/
+
void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
{
TDB_DATA key;
@@ -46,7 +52,11 @@ void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
tdb_chainunlock(tdb, key);
}
-/* fetch a value by a arbitrary blob key, return -1 if not found */
+/****************************************************************************
+ Fetch a value by a arbitrary blob key, return -1 if not found.
+ JRA. DEPRECATED ! Use tdb_fetch_int32_byblob instead.
+****************************************************************************/
+
int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
{
TDB_DATA key, data;
@@ -55,20 +65,29 @@ int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
key.dptr = keyval;
key.dsize = len;
data = tdb_fetch(tdb, key);
- if (!data.dptr || data.dsize != sizeof(int)) return -1;
+ if (!data.dptr || data.dsize != sizeof(int))
+ return -1;
memcpy(&ret, data.dptr, sizeof(int));
- free(data.dptr);
+ SAFE_FREE(data.dptr);
return ret;
}
-/* fetch a value by string key, return -1 if not found */
+/****************************************************************************
+ Fetch a value by string key, return -1 if not found.
+ JRA. DEPRECATED ! Use tdb_fetch_int32 instead.
+****************************************************************************/
+
int tdb_fetch_int(TDB_CONTEXT *tdb, char *keystr)
{
return tdb_fetch_int_byblob(tdb, keystr, strlen(keystr) + 1);
}
-/* store a value by an arbitary blob key, return 0 on success, -1 on failure */
+/****************************************************************************
+ Store a value by an arbitary blob key, return 0 on success, -1 on failure.
+ JRA. DEPRECATED ! Use tdb_store_int32_byblob instead.
+****************************************************************************/
+
int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v)
{
TDB_DATA key, data;
@@ -81,14 +100,81 @@ int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v)
return tdb_store(tdb, key, data, TDB_REPLACE);
}
-/* store a value by string key, return 0 on success, -1 on failure */
+/****************************************************************************
+ Store a value by string key, return 0 on success, -1 on failure.
+ JRA. DEPRECATED ! Use tdb_store_int32 instead.
+****************************************************************************/
+
int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v)
{
return tdb_store_int_byblob(tdb, keystr, strlen(keystr) + 1, v);
}
-/* Store a buffer by a null terminated string key. Return 0 on success, -1
- on failure */
+/****************************************************************************
+ Fetch a int32 value by a arbitrary blob key, return -1 if not found.
+ Output is int32 in native byte order.
+****************************************************************************/
+
+int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
+{
+ TDB_DATA key, data;
+ int32 ret;
+
+ key.dptr = keyval;
+ key.dsize = len;
+ data = tdb_fetch(tdb, key);
+ if (!data.dptr || data.dsize != sizeof(int32))
+ return -1;
+
+ ret = IVAL(data.dptr,0);
+ SAFE_FREE(data.dptr);
+ return ret;
+}
+
+/****************************************************************************
+ Fetch a int32 value by string key, return -1 if not found.
+ Output is int32 in native byte order.
+****************************************************************************/
+
+int32 tdb_fetch_int32(TDB_CONTEXT *tdb, char *keystr)
+{
+ return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1);
+}
+
+/****************************************************************************
+ Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure.
+ Input is int32 in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+int tdb_store_int32_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int32 v)
+{
+ TDB_DATA key, data;
+ int32 v_store;
+
+ key.dptr = keystr;
+ key.dsize = len;
+ SIVAL(&v_store,0,v);
+ data.dptr = (void *)&v_store;
+ data.dsize = sizeof(int32);
+
+ return tdb_store(tdb, key, data, TDB_REPLACE);
+}
+
+/****************************************************************************
+ Store a int32 value by string key, return 0 on success, -1 on failure.
+ Input is int32 in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+int tdb_store_int32(TDB_CONTEXT *tdb, char *keystr, int32 v)
+{
+ return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v);
+}
+
+/****************************************************************************
+ Store a buffer by a null terminated string key. Return 0 on success, -1
+ on failure.
+****************************************************************************/
+
int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
{
TDB_DATA key, data;
@@ -102,8 +188,10 @@ int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
return tdb_store(tdb, key, data, TDB_REPLACE);
}
-/* Fetch a buffer using a null terminated string key. Don't forget to call
- free() on the result dptr. */
+/****************************************************************************
+ Fetch a buffer using a null terminated string key. Don't forget to call
+ free() on the result dptr.
+****************************************************************************/
TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
{
@@ -115,7 +203,10 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
return tdb_fetch(tdb, key);
}
-/* Atomic integer change. Returns old value. To create, set initial value in *oldval. */
+/****************************************************************************
+ Atomic integer change. Returns old value. To create, set initial value in *oldval.
+ Deprecated. Use int32 version. JRA.
+****************************************************************************/
int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val)
{
@@ -147,8 +238,45 @@ int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int chang
return ret;
}
-/* useful pair of routines for packing/unpacking data consisting of
- integers and strings */
+/****************************************************************************
+ Atomic integer change. Returns old value. To create, set initial value in *oldval.
+****************************************************************************/
+
+int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int32 change_val)
+{
+ int32 val;
+ int32 ret = -1;
+
+ if (tdb_lock_bystring(tdb, keystr) == -1)
+ return -1;
+
+ if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
+ if (tdb_error(tdb) != TDB_ERR_NOEXIST)
+ goto err_out;
+
+ val = *oldval;
+
+ } else {
+ *oldval = val;
+ val += change_val;
+ }
+
+ if (tdb_store_int32(tdb, keystr, val) == -1)
+ goto err_out;
+
+ ret = 0;
+
+ err_out:
+
+ tdb_unlock_bystring(tdb, keystr);
+ return ret;
+}
+
+/****************************************************************************
+ Useful pair of routines for packing/unpacking data consisting of
+ integers and strings.
+****************************************************************************/
+
size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
{
va_list ap;
@@ -170,40 +298,35 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
case 'w':
len = 2;
w = (uint16)va_arg(ap, int);
- if (bufsize >= len) {
+ if (bufsize >= len)
SSVAL(buf, 0, w);
- }
break;
case 'd':
len = 4;
d = va_arg(ap, uint32);
- if (bufsize >= len) {
+ if (bufsize >= len)
SIVAL(buf, 0, d);
- }
break;
case 'p':
len = 4;
p = va_arg(ap, void *);
d = p?1:0;
- if (bufsize >= len) {
+ if (bufsize >= len)
SIVAL(buf, 0, d);
- }
break;
case 'P':
s = va_arg(ap,char *);
w = strlen(s);
len = w + 1;
- if (bufsize >= len) {
+ if (bufsize >= len)
memcpy(buf, s, len);
- }
break;
case 'f':
s = va_arg(ap,char *);
w = strlen(s);
len = w + 1;
- if (bufsize >= len) {
+ if (bufsize >= len)
memcpy(buf, s, len);
- }
break;
case 'B':
i = va_arg(ap, int);
@@ -227,16 +350,16 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
va_end(ap);
- DEBUG(8,("tdb_pack(%s, %d) -> %d\n",
+ DEBUG(18,("tdb_pack(%s, %d) -> %d\n",
fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
return PTR_DIFF(buf, buf0);
}
-
-
-/* useful pair of routines for packing/unpacking data consisting of
- integers and strings */
+/****************************************************************************
+ Useful pair of routines for packing/unpacking data consisting of
+ integers and strings.
+****************************************************************************/
int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
{
@@ -259,47 +382,55 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
case 'w':
len = 2;
w = va_arg(ap, uint16 *);
- if (bufsize < len) goto no_space;
+ if (bufsize < len)
+ goto no_space;
*w = SVAL(buf, 0);
break;
case 'd':
len = 4;
d = va_arg(ap, uint32 *);
- if (bufsize < len) goto no_space;
+ if (bufsize < len)
+ goto no_space;
*d = IVAL(buf, 0);
break;
case 'p':
len = 4;
p = va_arg(ap, void **);
- if (bufsize < len) goto no_space;
+ if (bufsize < len)
+ goto no_space;
*p = (void *)IVAL(buf, 0);
break;
case 'P':
s = va_arg(ap,char *);
len = strlen(buf) + 1;
- if (bufsize < len || len > sizeof(pstring)) goto no_space;
+ if (bufsize < len || len > sizeof(pstring))
+ goto no_space;
memcpy(s, buf, len);
break;
case 'f':
s = va_arg(ap,char *);
len = strlen(buf) + 1;
- if (bufsize < len || len > sizeof(fstring)) goto no_space;
+ if (bufsize < len || len > sizeof(fstring))
+ goto no_space;
memcpy(s, buf, len);
break;
case 'B':
i = va_arg(ap, int *);
b = va_arg(ap, char **);
len = 4;
- if (bufsize < len) goto no_space;
+ if (bufsize < len)
+ goto no_space;
*i = IVAL(buf, 0);
if (! *i) {
*b = NULL;
break;
}
len += *i;
- if (bufsize < len) goto no_space;
+ if (bufsize < len)
+ goto no_space;
*b = (char *)malloc(*i);
- if (! *b) goto no_space;
+ if (! *b)
+ goto no_space;
memcpy(*b, buf+4, *i);
break;
default:
@@ -316,7 +447,7 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
va_end(ap);
- DEBUG(8,("tdb_unpack(%s, %d) -> %d\n",
+ DEBUG(18,("tdb_unpack(%s, %d) -> %d\n",
fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)));
return PTR_DIFF(buf, buf0);
@@ -326,8 +457,9 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
}
/****************************************************************************
-log tdb messages via DEBUG()
+ Log tdb messages via DEBUG().
****************************************************************************/
+
static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
{
va_list ap;
@@ -337,16 +469,18 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
vasprintf(&ptr, format, ap);
va_end(ap);
- if (!ptr || !*ptr) return;
+ if (!ptr || !*ptr)
+ return;
DEBUG(level, ("tdb(%s): %s", tdb->name, ptr));
- free(ptr);
+ SAFE_FREE(ptr);
}
+/****************************************************************************
+ Like tdb_open() but also setup a logging function that redirects to
+ the samba DEBUG() system.
+****************************************************************************/
-
-/* like tdb_open() but also setup a logging function that redirects to
- the samba DEBUG() system */
TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode)
{
@@ -355,11 +489,21 @@ TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
if (!lp_use_mmap())
tdb_flags |= TDB_NOMMAP;
- tdb = tdb_open(name, hash_size, tdb_flags,
- open_flags, mode);
- if (!tdb) return NULL;
-
- tdb_logging_function(tdb, tdb_log);
+ tdb = tdb_open_ex(name, hash_size, tdb_flags,
+ open_flags, mode, tdb_log);
+ if (!tdb)
+ return NULL;
return tdb;
}
+
+
+/****************************************************************************
+ Allow tdb_delete to be used as a tdb_traversal_fn.
+****************************************************************************/
+
+int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf,
+ void *state)
+{
+ return tdb_delete(the_tdb, key);
+}
diff --git a/source/utils/locktest.c b/source/utils/locktest.c
index 80dbba1e37e..4697067e881 100644
--- a/source/utils/locktest.c
+++ b/source/utils/locktest.c
@@ -217,7 +217,7 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NS
}
cli_ulogoff(cli[server][conn]);
cli_shutdown(cli[server][conn]);
- free(cli[server][conn]);
+ SAFE_FREE(cli[server][conn]);
cli[server][conn] = NULL;
}
cli[server][conn] = connect_one(share[server]);
diff --git a/source/utils/locktest2.c b/source/utils/locktest2.c
index 0391aa29426..91083bc3ec4 100644
--- a/source/utils/locktest2.c
+++ b/source/utils/locktest2.c
@@ -268,7 +268,7 @@ static void reconnect(struct cli_state *cli[NSERVERS][NCONNECTIONS],
}
cli_ulogoff(cli[server][conn]);
cli_shutdown(cli[server][conn]);
- free(cli[server][conn]);
+ SAFE_FREE(cli[server][conn]);
cli[server][conn] = NULL;
}
cli[server][conn] = connect_one(share[server]);
diff --git a/source/utils/make_printerdef.c b/source/utils/make_printerdef.c
index a449a24fcdd..f5d40ea3f00 100644
--- a/source/utils/make_printerdef.c
+++ b/source/utils/make_printerdef.c
@@ -307,7 +307,7 @@ static char *find_desc(FILE *fichier,char *text)
if (!strcmp(text,long_desc))
found=1;
}
- free(chaine);
+ SAFE_FREE(chaine);
if (!found || !crap) return(NULL);
while(*crap==' ') crap++;
pstrcpy(short_desc,crap);
diff --git a/source/utils/make_smbcodepage.c b/source/utils/make_smbcodepage.c
index 1bd3edc2631..256dde7c0d1 100644
--- a/source/utils/make_smbcodepage.c
+++ b/source/utils/make_smbcodepage.c
@@ -99,7 +99,7 @@ static int clean_data( char **buf, size_t *size)
newbuf_p += (strlen(newbuf_p) + 1);
}
- free(*buf);
+ SAFE_FREE(*buf);
*buf = newbuf;
return num_lines;
}
@@ -209,7 +209,7 @@ The maximum size I will believe is 100k.\n", prog_name, size);
{
fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name,
input_file, strerror(errno));
- free((char *)buf);
+ SAFE_FREE(buf);
fclose(fp);
exit(1);
}
@@ -303,7 +303,7 @@ definition file. File %s has %d.\n", prog_name, MAXCODEPAGELINES, input_file, nu
fclose(fp);
- free(orig_buf);
+ SAFE_FREE(orig_buf);
return 0;
}
diff --git a/source/utils/make_unicodemap.c b/source/utils/make_unicodemap.c
index 3584facbf62..79c63ff003c 100644
--- a/source/utils/make_unicodemap.c
+++ b/source/utils/make_unicodemap.c
@@ -96,7 +96,7 @@ static size_t clean_data( char **buf, size_t *size)
newbuf_p += (strlen(newbuf_p) + 1);
}
- free(*buf);
+ SAFE_FREE(*buf);
*buf = newbuf;
return num_lines;
}
@@ -172,7 +172,7 @@ static int do_compile(const char *codepage, const char *input_file, const char *
if(fread( buf, 1, size, fp) != size) {
fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name,
input_file, strerror(errno));
- free((char *)buf);
+ SAFE_FREE(buf);
fclose(fp);
exit(1);
}
@@ -289,8 +289,8 @@ static int do_compile(const char *codepage, const char *input_file, const char *
fclose(fp);
- free(orig_buf);
- free(output_buf);
+ SAFE_FREE(orig_buf);
+ SAFE_FREE(output_buf);
return 0;
}
diff --git a/source/utils/masktest.c b/source/utils/masktest.c
index a654b5bfd11..ba719bae248 100644
--- a/source/utils/masktest.c
+++ b/source/utils/masktest.c
@@ -23,7 +23,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
static fstring password;
static fstring username;
static int got_pass;
diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c
index 0f978a6cf3f..27bd419c781 100644
--- a/source/utils/nmblookup.c
+++ b/source/utils/nmblookup.c
@@ -24,9 +24,8 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
extern struct in_addr ipzero;
+extern BOOL AllowDebugChange;
static BOOL use_bcast = True;
static BOOL got_bcast = False;
@@ -113,7 +112,7 @@ static void do_node_status(int fd, char *name, int type, struct in_addr ip)
printf("Looking up status of %s\n",inet_ntoa(ip));
make_nmb_name(&nname, name, type);
- status = name_status_query(fd,&nname,ip, &count);
+ status = node_status_query(fd,&nname,ip, &count);
if (status) {
for (i=0;i<count;i++) {
fstrcpy(cleanname, status[i].name);
@@ -124,7 +123,7 @@ static void do_node_status(int fd, char *name, int type, struct in_addr ip)
cleanname,status[i].type,
node_status_flags(status[i].flags));
}
- free(status);
+ SAFE_FREE(status);
}
printf("\n");
}
@@ -197,9 +196,11 @@ int main(int argc,char *argv[])
int i;
static pstring servicesf = CONFIGFILE;
BOOL lookup_by_ip = False;
- int commandline_debuglevel = -2;
DEBUGLEVEL = 1;
+ /* Prevent smb.conf setting from overridding */
+ AllowDebugChange = False;
+
*lookup = 0;
TimeInit();
@@ -241,7 +242,7 @@ int main(int argc,char *argv[])
recursion_desired = True;
break;
case 'd':
- commandline_debuglevel = DEBUGLEVEL = atoi(optarg);
+ DEBUGLEVEL = atoi(optarg);
break;
case 's':
pstrcpy(servicesf, optarg);
@@ -270,14 +271,6 @@ int main(int argc,char *argv[])
fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
- /*
- * Ensure we reset DEBUGLEVEL if someone specified it
- * on the command line.
- */
-
- if(commandline_debuglevel != -2)
- DEBUGLEVEL = commandline_debuglevel;
-
load_interfaces();
if (!open_sockets()) return(1);
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index 7006eeee4e5..a96793e18e2 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -32,7 +32,7 @@
#include "includes.h"
extern pstring global_myname;
-extern int DEBUGLEVEL;
+extern BOOL AllowDebugChange;
/*
* Next two lines needed for SunOS and don't
@@ -43,11 +43,11 @@ extern int optind;
/*********************************************************
Print command usage on stderr and die.
-**********************************************************/
+ **********************************************************/
static void usage(void)
{
if (getuid() == 0) {
- printf("tdbedit options\n");
+ printf("pdbedit options\n");
} else {
printf("You need to be root to use this tool!\n");
}
@@ -188,13 +188,13 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d
if (fullname)
pdb_set_fullname(sam_pwent, fullname);
if (homedir)
- pdb_set_homedir(sam_pwent, homedir);
+ pdb_set_homedir(sam_pwent, homedir, True);
if (drive)
- pdb_set_dir_drive(sam_pwent,drive);
+ pdb_set_dir_drive(sam_pwent, drive, True);
if (script)
- pdb_set_logon_script(sam_pwent, script);
+ pdb_set_logon_script(sam_pwent, script, True);
if (profile)
- pdb_set_profile_path (sam_pwent, profile);
+ pdb_set_profile_path (sam_pwent, profile, True);
if (pdb_update_sam_account (sam_pwent, True))
print_user_info (username, True, False);
@@ -208,13 +208,98 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d
}
/*********************************************************
+ A strdup with exit
+**********************************************************/
+
+static char *strdup_x(const char *s)
+{
+ char *new_s = strdup(s);
+ if (!new_s) {
+ fprintf(stderr,"out of memory\n");
+ exit(1);
+ }
+ return new_s;
+}
+
+/*************************************************************
+ Utility function to prompt for passwords from stdin. Each
+ password entered must end with a newline.
+*************************************************************/
+static char *stdin_new_passwd(void)
+{
+ static fstring new_passwd;
+ size_t len;
+
+ ZERO_ARRAY(new_passwd);
+
+ /*
+ * 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;
+ }
+ }
+ return(new_passwd);
+}
+
+/*************************************************************
+ Utility function to get passwords via tty or stdin
+ Used if the '-s' option is set to silently get passwords
+ to enable scripting.
+ _copied_ from smbpasswd
+*************************************************************/
+static char *get_pass( char *prompt, BOOL stdin_get)
+{
+ char *p;
+ if (stdin_get) {
+ p = stdin_new_passwd();
+ } else {
+ p = getpass(prompt);
+ }
+ return strdup_x(p);
+}
+
+/*************************************************************
+ Utility function to prompt for new password.
+ _copied_ from smbpasswd
+*************************************************************/
+static char *prompt_for_new_password(BOOL stdin_get)
+{
+ char *p;
+ fstring new_passwd;
+
+ ZERO_ARRAY(new_passwd);
+
+ p = get_pass("New SMB password:", stdin_get);
+
+ fstrcpy(new_passwd, p);
+ safe_free(p);
+
+ p = get_pass("Retype new SMB password:", stdin_get);
+
+ if (strcmp(p, new_passwd)) {
+ fprintf(stderr, "Mismatch - password unchanged.\n");
+ ZERO_ARRAY(new_passwd);
+ safe_free(p);
+ return NULL;
+ }
+
+ return p;
+}
+
+
+/*********************************************************
Add New User
**********************************************************/
static int new_user (char *username, char *fullname, char *homedir, char *drive, char *script, char *profile)
{
SAM_ACCOUNT *sam_pwent=NULL;
struct passwd *pwd = NULL;
- char *password1, *password2;
+ char *password;
ZERO_STRUCT(sam_pwent);
@@ -225,28 +310,27 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive,
pdb_free_sam (sam_pwent);
return -1;
}
-
- password1 = getpass("new password:");
- password2 = getpass("retype new password:");
- if (strcmp (password1, password2)) {
- fprintf (stderr, "Passwords does not match!\n");
+
+ password = prompt_for_new_password(0);
+ if (!password) {
+ fprintf (stderr, "Passwords do not match!\n");
pdb_free_sam (sam_pwent);
return -1;
}
- pdb_set_plaintext_passwd(sam_pwent, password1);
+ pdb_set_plaintext_passwd(sam_pwent, password);
pdb_set_username(sam_pwent, username);
if (fullname)
pdb_set_fullname(sam_pwent, fullname);
if (homedir)
- pdb_set_homedir (sam_pwent, homedir);
+ pdb_set_homedir (sam_pwent, homedir, True);
if (drive)
- pdb_set_dir_drive (sam_pwent, drive);
+ pdb_set_dir_drive (sam_pwent, drive, True);
if (script)
- pdb_set_logon_script(sam_pwent, script);
+ pdb_set_logon_script(sam_pwent, script, True);
if (profile)
- pdb_set_profile_path (sam_pwent, profile);
+ pdb_set_profile_path (sam_pwent, profile, True);
/* TODO: Check uid not being in MACHINE UID range!! */
pdb_set_uid (sam_pwent, pwd->pw_uid);
@@ -557,7 +641,7 @@ static int import_users (char *filename)
good++;
pdb_reset_sam (sam_pwent);
}
- printf ("%d lines read.\n%d entryes imported\n", line, good);
+ printf ("%d lines read.\n%d entries imported\n", line, good);
pdb_free_sam(sam_pwent);
return 0;
}
@@ -588,25 +672,35 @@ int main (int argc, char **argv)
TimeInit();
- setup_logging("tdbedit", True);
+ setup_logging("pdbedit", True);
+
+ charset_initialise();
if (argc < 2) {
usage();
return 0;
}
- if(!initialize_password_db(True)) {
- fprintf(stderr, "Can't setup password database vectors.\n");
- exit(1);
- }
-
+ DEBUGLEVEL = 0;
+ AllowDebugChange = False;
+
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n",
servicesf);
exit(1);
}
+
+ secrets_init();
+
+ if(!initialize_password_db(True)) {
+ fprintf(stderr, "Can't setup password database vectors.\n");
+ exit(1);
+ }
- while ((ch = getopt(argc, argv, "ad:f:h:i:lmp:s:u:vwx")) != EOF) {
+
+ codepage_initialise(lp_client_code_page());
+
+ while ((ch = getopt(argc, argv, "ad:f:h:i:lmp:s:u:vwxD:")) != EOF) {
switch(ch) {
case 'a':
add_user = True;
@@ -653,6 +747,9 @@ int main (int argc, char **argv)
import = True;
smbpasswd = optarg;
break;
+ case 'D':
+ DEBUGLEVEL = atoi(optarg);
+ break;
default:
usage();
}
diff --git a/source/utils/rpccheck.c b/source/utils/rpccheck.c
index 1db7de34234..e8e61e9f718 100644
--- a/source/utils/rpccheck.c
+++ b/source/utils/rpccheck.c
@@ -21,8 +21,6 @@
#include "includes.h"
-extern int DEBUGLEVEL;
-
main()
{
char filter[]="0123456789ABCDEF";
diff --git a/source/utils/rpctorture.c b/source/utils/rpctorture.c
index c80cfe4adea..3bf70b9719e 100644
--- a/source/utils/rpctorture.c
+++ b/source/utils/rpctorture.c
@@ -34,10 +34,6 @@ extern pstring global_myname;
extern pstring user_socket_options;
-extern pstring debugf;
-extern int DEBUGLEVEL;
-
-
extern file_info def_finfo;
#define CNV_LANG(s) dos2unix_format(s,False)
@@ -240,6 +236,7 @@ enum client_action
enum client_action cli_action = CLIENT_NONE;
int nprocs = 1;
int numops = 100;
+ pstring logfile;
struct client_info cli_info;
@@ -458,8 +455,9 @@ enum client_action
case 'l':
{
- slprintf(debugf, sizeof(debugf)-1,
+ slprintf(logfile, sizeof(logfile)-1,
"%s.client",optarg);
+ lp_set_logfile(logfile);
break;
}
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 59385decaa4..f65f65fd330 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -92,9 +92,8 @@ static BOOL cacls_open_policy_hnd(void)
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
- if (cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True,
- GENERIC_EXECUTE_ACCESS, &pol)
- != NT_STATUS_OK) {
+ if (!NT_STATUS_IS_OK(cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True,
+ GENERIC_EXECUTE_ACCESS, &pol))) {
return False;
}
@@ -118,8 +117,8 @@ static void SidToString(fstring str, DOM_SID *sid)
/* Ask LSA to convert the sid to a name */
if (!cacls_open_policy_hnd() ||
- cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, &types,
- &num_names) != NT_STATUS_OK ||
+ !NT_STATUS_IS_OK(cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, &types,
+ &num_names)) ||
!names || !names[0]) {
return;
}
@@ -142,8 +141,8 @@ static BOOL StringToSid(DOM_SID *sid, char *str)
}
if (!cacls_open_policy_hnd() ||
- cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, &sids, &types,
- &num_sids) != NT_STATUS_OK) {
+ !NT_STATUS_IS_OK(cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, &sids, &types,
+ &num_sids))) {
result = False;
goto done;
}
@@ -164,7 +163,7 @@ static void print_ace(FILE *f, SEC_ACE *ace)
int do_print = 0;
uint32 got_mask;
- SidToString(sidstr, &ace->sid);
+ SidToString(sidstr, &ace->trustee);
fprintf(f, "%s:", sidstr);
@@ -329,7 +328,7 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace)
memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
- free(aces);
+ SAFE_FREE(aces);
(*the_acl) = new;
return True;
}
@@ -392,8 +391,8 @@ static SEC_DESC *sec_desc_parse(char *str)
ret = make_sec_desc(ctx,revision, owner_sid, grp_sid,
NULL, dacl, &sd_size);
- if (grp_sid) free(grp_sid);
- if (owner_sid) free(owner_sid);
+ SAFE_FREE(grp_sid);
+ SAFE_FREE(owner_sid);
return ret;
}
@@ -528,7 +527,7 @@ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
{
if (sec_ace_equal(ace1, ace2)) return 0;
if (ace1->type != ace2->type) return ace2->type - ace1->type;
- if (sid_compare(&ace1->sid, &ace2->sid)) return sid_compare(&ace1->sid, &ace2->sid);
+ if (sid_compare(&ace1->trustee, &ace2->trustee)) return sid_compare(&ace1->trustee, &ace2->trustee);
if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags;
if (ace1->info.mask != ace2->info.mask) return ace1->info.mask - ace2->info.mask;
if (ace1->size != ace2->size) return ace1->size - ace2->size;
@@ -606,10 +605,8 @@ static int cacl_set(struct cli_state *cli, char *filename,
}
old->dacl->num_aces--;
if (old->dacl->num_aces == 0) {
- free(old->dacl->ace);
- old->dacl->ace=NULL;
- free(old->dacl);
- old->dacl = NULL;
+ SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl);
old->off_dacl = 0;
}
found = True;
@@ -630,8 +627,8 @@ static int cacl_set(struct cli_state *cli, char *filename,
BOOL found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sid_equal(&sd->dacl->ace[i].sid,
- &old->dacl->ace[j].sid)) {
+ if (sid_equal(&sd->dacl->ace[i].trustee,
+ &old->dacl->ace[j].trustee)) {
old->dacl->ace[j] = sd->dacl->ace[i];
found = True;
}
@@ -640,7 +637,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
if (!found) {
fstring str;
- SidToString(str, &sd->dacl->ace[i].sid);
+ SidToString(str, &sd->dacl->ace[i].trustee);
printf("ACL for SID %s not found\n", str);
}
}
@@ -718,14 +715,12 @@ struct cli_state *connect_one(char *share)
!cli_connect(c, server_n, &ip)) {
DEBUG(0,("Connection to %s failed\n", server_n));
cli_shutdown(c);
- safe_free(c);
return NULL;
}
if (!cli_session_request(c, &calling, &called)) {
DEBUG(0,("session request to %s failed\n", called.name));
cli_shutdown(c);
- safe_free(c);
if (strcmp(called.name, "*SMBSERVER")) {
make_nmb_name(&called , "*SMBSERVER", 0x20);
goto again;
@@ -738,7 +733,6 @@ struct cli_state *connect_one(char *share)
if (!cli_negprot(c)) {
DEBUG(0,("protocol negotiation failed\n"));
cli_shutdown(c);
- safe_free(c);
return NULL;
}
@@ -755,7 +749,6 @@ struct cli_state *connect_one(char *share)
lp_workgroup())) {
DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
- safe_free(c);
return NULL;
}
@@ -765,7 +758,6 @@ struct cli_state *connect_one(char *share)
password, strlen(password)+1)) {
DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
cli_shutdown(c);
- safe_free(c);
return NULL;
}
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index bba7b15dd28..3b4781bb742 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -21,6 +21,8 @@
#include "includes.h"
+extern BOOL AllowDebugChange;
+
static struct {
char *name;
int value;
@@ -175,7 +177,7 @@ static int parse_type(char *mtype)
/****************************************************************************
do command
****************************************************************************/
-static BOOL do_command(char *dest, char *msg_name, char **params)
+static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
{
int i, n, v;
int mtype;
@@ -308,7 +310,10 @@ static BOOL do_command(char *dest, char *msg_name, char **params)
n = atoi(params[0]);
pong_count = 0;
for (i=0;i<n;i++) {
- retval = send_message(dest, MSG_PING, NULL, 0, True);
+ if (iparams > 1)
+ retval = send_message(dest, MSG_PING, params[1], strlen(params[1]) + 1, True);
+ else
+ retval = send_message(dest, MSG_PING, NULL, 0, True);
if (retval == False) break;
}
if (retval) {
@@ -339,6 +344,8 @@ static BOOL do_command(char *dest, char *msg_name, char **params)
TimeInit();
setup_logging(argv[0],True);
+ AllowDebugChange = False;
+ DEBUGLEVEL = 0;
charset_initialise();
if (argc < 2) usage(True);
@@ -366,17 +373,17 @@ static BOOL do_command(char *dest, char *msg_name, char **params)
if (!interactive) {
if (argc < 2) usage(True);
- return (do_command(argv[0],argv[1],argc > 2 ? &argv[2] : 0));
+ return (do_command(argv[0],argv[1], argc-2, argc > 2 ? &argv[2] : 0));
}
while (True) {
- char *myargv[3];
+ char *myargv[4];
int myargc;
printf("smbcontrol> ");
if (!fgets(temp, sizeof(temp)-1, stdin)) break;
myargc = 0;
- while ((myargc < 3) &&
+ while ((myargc < 4) &&
(myargv[myargc] = strtok(myargc?NULL:temp," \t\n"))) {
myargc++;
}
@@ -384,7 +391,7 @@ static BOOL do_command(char *dest, char *msg_name, char **params)
if (strequal(myargv[0],"q")) break;
if (myargc < 2)
usage(False);
- else if (!do_command(myargv[0],myargv[1],myargc > 2 ? &myargv[2] : 0))
+ else if (!do_command(myargv[0],myargv[1],myargc-2,myargc > 2 ? &myargv[2] : 0))
usage(False);
}
return(0);
diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c
index db83873e694..6be0860c928 100644
--- a/source/utils/smbfilter.c
+++ b/source/utils/smbfilter.c
@@ -36,8 +36,6 @@
static char *netbiosname;
static char packet[BUFFER_SIZE];
-extern int DEBUGLEVEL;
-
static void filter_reply(char *buf)
{
int msg_type = CVAL(buf,0);
@@ -120,7 +118,7 @@ static void filter_child(int c, struct in_addr dest_ip)
if (s != -1) FD_SET(s, &fds);
if (c != -1) FD_SET(c, &fds);
- num = sys_select_intr(MAX(s+1, c+1),&fds,NULL);
+ num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
if (num <= 0) continue;
if (c != -1 && FD_ISSET(c, &fds)) {
@@ -184,7 +182,7 @@ static void start_filter(char *desthost)
FD_ZERO(&fds);
FD_SET(s, &fds);
- num = sys_select_intr(s+1,&fds,NULL);
+ num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
if (num > 0) {
c = accept(s, &addr, &in_addrlen);
if (c != -1) {
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index b29b5d9a97e..24185114f13 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -22,7 +22,7 @@
#include "includes.h"
extern pstring global_myname;
-extern int DEBUGLEVEL;
+extern BOOL AllowDebugChange;
/*
* Next two lines needed for SunOS and don't
@@ -35,16 +35,17 @@ extern int optind;
static BOOL local_mode;
/*********************************************************
-a strdup with exit
+ A strdup with exit
**********************************************************/
-static char *xstrdup(char *s)
+
+static char *strdup_x(const char *s)
{
- s = strdup(s);
- if (!s) {
+ char *new_s = strdup(s);
+ if (!new_s) {
fprintf(stderr,"out of memory\n");
exit(1);
}
- return s;
+ return new_s;
}
@@ -81,66 +82,6 @@ static void usage(void)
exit(1);
}
-/*********************************************************
-Join a domain.
-**********************************************************/
-static int join_domain(char *domain, char *remote)
-{
- pstring remote_machine;
- fstring trust_passwd;
- unsigned char orig_trust_passwd_hash[16];
- BOOL ret;
-
- pstrcpy(remote_machine, remote ? remote : "");
- fstrcpy(trust_passwd, global_myname);
- strlower(trust_passwd);
- E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
-
- /* Ensure that we are not trying to join a
- domain if we are locally set up as a domain
- controller. */
-
- if(strequal(remote, global_myname)) {
- fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
- return 1;
- }
-
- /*
- * Write the old machine account password.
- */
-
- if(!secrets_store_trust_account_password(domain, orig_trust_passwd_hash)) {
- fprintf(stderr, "Unable to write the machine account password for \
-machine %s in domain %s.\n", global_myname, domain);
- return 1;
- }
-
- /*
- * If we are given a remote machine assume this is the PDC.
- */
-
- if(remote == NULL) {
- pstrcpy(remote_machine, lp_passwordserver());
- }
-
- if(!*remote_machine) {
- fprintf(stderr, "No password server list given in smb.conf - \
-unable to join domain.\n");
- return 1;
- }
-
- ret = change_trust_account_password( domain, remote_machine);
-
- if(!ret) {
- trust_password_delete(domain);
- fprintf(stderr,"Unable to join domain %s.\n",domain);
- } else {
- printf("Joined domain %s.\n",domain);
- }
-
- return (int)ret;
-}
-
/* Initialise client credentials for authenticated pipe access */
void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
@@ -165,13 +106,13 @@ Join a domain using the administrator username and password
/* Macro for checking RPC error codes to make things more readable */
#define CHECK_RPC_ERR(rpc, msg) \
- if ((result = rpc) != NT_STATUS_OK) { \
+ if (!NT_STATUS_IS_OK(result = rpc)) { \
DEBUG(0, (msg ": %s\n", get_nt_error_msg(result))); \
goto done; \
}
#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \
- if ((result = rpc) != NT_STATUS_OK) { \
+ if (!NT_STATUS_IS_OK(result = rpc)) { \
DEBUG(0, debug_args); \
goto done; \
}
@@ -205,7 +146,7 @@ static int join_domain_byuser(char *domain, char *remote_machine,
/* Misc */
- uint32 result;
+ NTSTATUS result;
int retval = 1;
/* Connect to remote machine */
@@ -293,14 +234,18 @@ static int join_domain_byuser(char *domain, char *remote_machine,
acct_name, ACB_WSTRUST,
unknown, &user_pol,
&user_rid);
+ }
- /* We *must* do this.... don't ask... */
+ if (NT_STATUS_IS_OK(result)) {
+
+ /* We *must* do this.... don't ask... */
+
CHECK_RPC_ERR_DEBUG(cli_samr_close(&cli, mem_ctx, &user_pol), ("error closing user policy"));
result = NT_STATUS_USER_EXISTS;
- }
+ }
- if (result == NT_STATUS_USER_EXISTS) {
+ if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_USER_EXISTS)) {
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
char *names;
@@ -333,7 +278,7 @@ static int join_domain_byuser(char *domain, char *remote_machine,
("could not re-open existing user %s: %s\n",
acct_name, get_nt_error_msg(result)));
- } else if (result != NT_STATUS_OK) {
+ } else if (!NT_STATUS_IS_OK(result)) {
DEBUG(0, ("error creating domain user: %s\n",
get_nt_error_msg(result)));
goto done;
@@ -430,6 +375,75 @@ static int join_domain_byuser(char *domain, char *remote_machine,
return retval;
}
+/*********************************************************
+Join a domain. Old server manager method.
+**********************************************************/
+
+static int join_domain(char *domain, char *remote)
+{
+ pstring remote_machine;
+ fstring trust_passwd;
+ unsigned char orig_trust_passwd_hash[16];
+ DOM_SID domain_sid;
+ BOOL ret;
+
+ pstrcpy(remote_machine, remote ? remote : "");
+ fstrcpy(trust_passwd, global_myname);
+ strlower(trust_passwd);
+ E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
+
+ /* Ensure that we are not trying to join a
+ domain if we are locally set up as a domain
+ controller. */
+
+ if(strequal(remote, global_myname)) {
+ fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
+ return 1;
+ }
+
+ /*
+ * Write the old machine account password.
+ */
+
+ if(!secrets_store_trust_account_password(domain, orig_trust_passwd_hash)) {
+ fprintf(stderr, "Unable to write the machine account password for \
+machine %s in domain %s.\n", global_myname, domain);
+ return 1;
+ }
+
+ /*
+ * If we are given a remote machine assume this is the PDC.
+ */
+
+ if(remote == NULL) {
+ pstrcpy(remote_machine, lp_passwordserver());
+ }
+
+ if(!*remote_machine) {
+ fprintf(stderr, "No password server list given in smb.conf - \
+unable to join domain.\n");
+ return 1;
+ }
+
+ if (!fetch_domain_sid( domain, remote_machine, &domain_sid) ||
+ !secrets_store_domain_sid(domain, &domain_sid)) {
+ fprintf(stderr,"Failed to get domain SID. Unable to join domain %s.\n",domain);
+ return 1;
+ }
+
+ ret = change_trust_account_password( domain, remote_machine);
+
+ if(!ret) {
+ trust_password_delete(domain);
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ return 1;
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
+
+ return 0;
+}
+
static void set_line_buffering(FILE *f)
{
setvbuf(f, NULL, _IOLBF, 0);
@@ -474,7 +488,7 @@ static char *get_pass( char *prompt, BOOL stdin_get)
} else {
p = getpass(prompt);
}
- return xstrdup(p);
+ return strdup_x(p);
}
/*************************************************************
@@ -546,11 +560,6 @@ static BOOL password_change(const char *remote_machine, char *user_name,
******************************************************************/
static BOOL store_ldap_admin_pw (char* pw)
{
- TDB_DATA kbuf, dbuf;
- pstring fname;
- pstring key;
- char *p;
-
if (!pw)
return False;
@@ -593,11 +602,11 @@ static int process_root(int argc, char *argv[])
break;
case 'x':
local_flags |= LOCAL_DELETE_USER;
- new_passwd = xstrdup("XXXXXX");
+ new_passwd = strdup_x("XXXXXX");
break;
case 'd':
local_flags |= LOCAL_DISABLE_USER;
- new_passwd = xstrdup("XXXXXX");
+ new_passwd = strdup_x("XXXXXX");
break;
case 'e':
local_flags |= LOCAL_ENABLE_USER;
@@ -607,7 +616,7 @@ static int process_root(int argc, char *argv[])
break;
case 'n':
local_flags |= LOCAL_SET_NO_PASSWORD;
- new_passwd = xstrdup("NO PASSWORD");
+ new_passwd = strdup_x("NO PASSWORD");
break;
case 'j':
new_domain = optarg;
@@ -740,7 +749,7 @@ static int process_root(int argc, char *argv[])
if (got_username || got_pass)
usage();
fstrcpy(user_name, argv[0]);
- new_passwd = xstrdup(argv[1]);
+ new_passwd = strdup_x(argv[1]);
break;
default:
usage();
@@ -770,7 +779,7 @@ static int process_root(int argc, char *argv[])
if (local_flags & LOCAL_ADD_USER) {
safe_free(new_passwd);
- new_passwd = xstrdup(user_name);
+ new_passwd = strdup_x(user_name);
strlower(new_passwd);
}
@@ -810,7 +819,7 @@ static int process_root(int argc, char *argv[])
goto done;
}
if((sampass != NULL) && (pdb_get_lanman_passwd(sampass) != NULL)) {
- new_passwd = xstrdup("XXXX"); /* Don't care. */
+ new_passwd = strdup_x("XXXX"); /* Don't care. */
}
pdb_free_sam(sampass);
@@ -910,7 +919,7 @@ static int process_nonroot(int argc, char *argv[])
if (!user_name) {
pwd = sys_getpwuid(getuid());
if (pwd) {
- user_name = xstrdup(pwd->pw_name);
+ user_name = strdup_x(pwd->pw_name);
} else {
fprintf(stderr,"you don't exist - go away\n");
exit(1);
@@ -966,6 +975,8 @@ int main(int argc, char **argv)
{
static pstring servicesf = CONFIGFILE;
+ AllowDebugChange = False;
+
#if defined(HAVE_SET_AUTH_PARAMETERS)
set_auth_parameters(argc, argv);
#endif /* HAVE_SET_AUTH_PARAMETERS */
diff --git a/source/utils/smbw_sample.c b/source/utils/smbw_sample.c
index db92af95108..cf94743411d 100644
--- a/source/utils/smbw_sample.c
+++ b/source/utils/smbw_sample.c
@@ -4,22 +4,25 @@
#include <dirent.h>
#include <sys/stat.h>
+extern DIR *smbw_opendir(const char *fname);
+extern struct dirent *smbw_readdir(DIR *dirp);
+
static void usage(void)
{
- printf("
-smbw_sample - a sample program that uses smbw
-
-smbw_sample <options> path
-
- options:
- -W workgroup
- -l logfile
- -P prefix
- -d debuglevel
- -U username%%password
- -R resolve order
-
-note that path must start with /smb/
+ printf("\n \
+smbw_sample - a sample program that uses smbw\n \
+\n \
+smbw_sample <options> path\n \
+\n \
+ options:\n \
+ -W workgroup\n \
+ -l logfile\n \
+ -P prefix\n \
+ -d debuglevel\n \
+ -U username%%password\n \
+ -R resolve order\n \
+\n \
+note that path must start with /smb/\n \
");
}
diff --git a/source/utils/status.c b/source/utils/status.c
index 28726d40f0f..01d80ad53dd 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -44,8 +44,8 @@ struct session_record{
struct session_record *next;
} *srecs;
-extern int DEBUGLEVEL;
extern FILE *dbf;
+extern BOOL AllowDebugChange;
static pstring Ucrit_username = ""; /* added by OH */
static pid_t Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */
@@ -535,6 +535,8 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
}
if (ptr==NULL) {
ptr=(struct session_record *) malloc(sizeof(struct session_record));
+ if (!ptr)
+ return 0;
ptr->uid=crec.uid;
ptr->pid=crec.pid;
ptr->start=crec.start;
@@ -579,6 +581,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
charset_initialise();
+ AllowDebugChange = False;
DEBUGLEVEL = 0;
dbf = stderr;
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index 10292b3033a..9502ec9669d 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -35,9 +35,10 @@
#include "includes.h"
#include "smb.h"
+extern BOOL AllowDebugChange;
+
/* these live in util.c */
extern FILE *dbf;
-extern int DEBUGLEVEL;
/***********************************************
Here we do a set of 'hard coded' checks for bad
@@ -219,6 +220,7 @@ int main(int argc, char *argv[])
dbf = stdout;
DEBUGLEVEL = 2;
+ AllowDebugChange = False;
printf("Load smb config files from %s\n",configfile);
diff --git a/source/utils/testprns.c b/source/utils/testprns.c
index c03fa0436a6..0ba5403c30a 100644
--- a/source/utils/testprns.c
+++ b/source/utils/testprns.c
@@ -36,7 +36,6 @@
/* these live in util.c */
extern FILE *dbf;
-extern int DEBUGLEVEL;
int main(int argc, char *argv[])
{
diff --git a/source/utils/torture.c b/source/utils/torture.c
index 1277cd2ee32..185cd93d164 100644
--- a/source/utils/torture.c
+++ b/source/utils/torture.c
@@ -215,7 +215,8 @@ static BOOL check_error(struct cli_state *c,
{
uint8 class;
uint32 num;
- (void)cli_error(c, &class, &num, NULL);
+
+ (void)cli_dos_error(c, &class, &num);
if ((eclass != class || ecode != num) &&
num != (nterr&0xFFFFFF)) {
printf("unexpected error code class=%d code=%d\n",
@@ -3645,8 +3646,8 @@ int cli_setfileinfo_test(struct cli_state *cli, int fnum, int level, char *data,
return False;
}
- if (rdata) free(rdata);
- if (rparam) free(rparam);
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
return True;
}
@@ -4305,7 +4306,7 @@ static BOOL run_opentest(int dummy)
/* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
- cli_error( &cli1, &eclass, &errnum, NULL);
+ cli_dos_error( &cli1, &eclass, &errnum);
if (eclass != ERRDOS || errnum != ERRnoaccess) {
printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
@@ -4333,7 +4334,7 @@ static BOOL run_opentest(int dummy)
/* This will fail - but the error should be ERRshare. */
fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
- cli_error( &cli1, &eclass, &errnum, NULL);
+ cli_dos_error( &cli1, &eclass, &errnum);
if (eclass != ERRDOS || errnum != ERRbadshare) {
printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 70299f14c34..0b86265a1e5 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -168,7 +168,7 @@ void cgi_load_variables(FILE *f1)
variables[num_variables].name = strdup(line);
variables[num_variables].value = strdup(p+1);
- free(line);
+ SAFE_FREE(line);
if (!variables[num_variables].name ||
!variables[num_variables].value)
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index f22fe0d9b25..bf2e6da17d1 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -36,7 +36,7 @@ BOOL nmbd_running(void)
if ((ip_list = name_query(fd, "__SAMBA__", 0,
True, True, loopback_ip,
&count)) != NULL) {
- free(ip_list);
+ SAFE_FREE(ip_list);
close(fd);
return True;
}
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index fd251f89c50..920d0f3367c 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -39,7 +39,7 @@ static void initPid2Machine (void)
{
/* show machine name rather PID on table "Open Files"? */
if (PID_or_Machine) {
- PIDMAP *p, *q;
+ PIDMAP *p;
for (p = pidmap; p != NULL; ) {
DLIST_REMOVE(pidmap, p);
diff --git a/source/web/swat.c b/source/web/swat.c
index 251707e74e9..d09034671ee 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -1026,6 +1026,7 @@ static void printers_page(void)
load_config(True);
iNumNonAutoPrintServices = lp_numservices();
load_printers();
+ codepage_initialise(lp_client_code_page());
cgi_setup(SWATDIR, !demo_mode);