summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-04-12 00:37:55 +0000
committerGerald Carter <jerry@samba.org>2005-04-12 00:37:55 +0000
commitf0f7108060652a3f0d1b5ca4783cf62cd84fac12 (patch)
tree8b23f45f7547544c863d9c29f3ae4eba2882ff4b
parentdae1a1db3c946093333d9e5001e30f75140fd3ca (diff)
downloadsamba-f0f7108060652a3f0d1b5ca4783cf62cd84fac12.tar.gz
r6303: Setting up for 3.0.15pre1
current as of r6296
-rw-r--r--source/Makefile.in82
-rw-r--r--source/VERSION4
-rw-r--r--source/auth/auth_compat.c5
-rw-r--r--source/auth/auth_sam.c3
-rw-r--r--source/auth/auth_util.c5
-rw-r--r--source/client/client.c30
-rw-r--r--source/client/clitar.c4
-rwxr-xr-xsource/client/mount.cifs.c194
-rw-r--r--source/client/smbspool.c4
-rw-r--r--source/client/umount.cifs.c273
-rw-r--r--source/configure.in55
-rw-r--r--source/groupdb/mapping.c41
-rw-r--r--source/include/doserr.h2
-rw-r--r--source/include/includes.h11
-rw-r--r--source/include/libsmb_internal.h2
-rw-r--r--source/include/libsmbclient.h295
-rw-r--r--source/include/msdfs.h7
-rw-r--r--source/include/nt_status.h1
-rw-r--r--source/include/ntdomain.h3
-rw-r--r--source/include/nterr.h3
-rw-r--r--source/include/passdb.h49
-rw-r--r--source/include/rpc_buffer.h35
-rw-r--r--source/include/rpc_client.h21
-rw-r--r--source/include/rpc_eventlog.h193
-rw-r--r--source/include/rpc_lsa.h56
-rw-r--r--source/include/rpc_misc.h337
-rw-r--r--source/include/rpc_netlogon.h14
-rw-r--r--source/include/rpc_reg.h589
-rw-r--r--source/include/rpc_secdes.h47
-rw-r--r--source/include/rpc_shutdown.h65
-rwxr-xr-xsource/include/rpc_spoolss.h221
-rw-r--r--source/include/rpc_srvsvc.h22
-rw-r--r--source/include/rpc_svcctl.h246
-rw-r--r--source/include/smb.h62
-rw-r--r--source/include/smb_macros.h46
-rw-r--r--source/include/trans2.h12
-rw-r--r--source/intl/lang_tdb.c4
-rw-r--r--source/lib/access.c2
-rw-r--r--source/lib/account_pol.c8
-rw-r--r--source/lib/charcnv.c15
-rw-r--r--source/lib/data_blob.c2
-rw-r--r--source/lib/iconv.c2
-rw-r--r--source/lib/ms_fnmatch.c4
-rw-r--r--source/lib/privileges.c9
-rw-r--r--source/lib/secace.c2
-rw-r--r--source/lib/secdesc.c4
-rw-r--r--source/lib/select.c26
-rw-r--r--source/lib/smbldap.c7
-rw-r--r--source/lib/substitute.c3
-rw-r--r--source/lib/system.c192
-rw-r--r--source/lib/system_smbd.c4
-rw-r--r--source/lib/talloc.c13
-rw-r--r--source/lib/time.c22
-rw-r--r--source/lib/util.c65
-rw-r--r--source/lib/util_seaccess.c41
-rw-r--r--source/lib/util_sid.c168
-rw-r--r--source/lib/util_smbd.c4
-rw-r--r--source/lib/util_str.c46
-rw-r--r--source/lib/util_unistr.c39
-rw-r--r--source/lib/util_uuid.c2
-rw-r--r--source/lib/wins_srv.c3
-rw-r--r--source/libads/kerberos.c3
-rw-r--r--source/libads/ldap.c21
-rw-r--r--source/libads/ldap_printer.c6
-rw-r--r--source/libads/sasl.c9
-rw-r--r--source/libsmb/cliconnect.c7
-rw-r--r--source/libsmb/clientgen.c3
-rw-r--r--source/libsmb/clifile.c4
-rw-r--r--source/libsmb/clifsinfo.c115
-rw-r--r--source/libsmb/clikrb5.c3
-rw-r--r--source/libsmb/clilist.c4
-rw-r--r--source/libsmb/clirap.c38
-rw-r--r--source/libsmb/clirap2.c124
-rw-r--r--source/libsmb/clispnego.c3
-rw-r--r--source/libsmb/doserr.c2
-rw-r--r--source/libsmb/libsmbclient.c967
-rw-r--r--source/libsmb/nmblib.c5
-rw-r--r--source/libsmb/smb_signing.c3
-rw-r--r--source/libsmb/smbencrypt.c2
-rw-r--r--source/libsmb/spnego.c15
-rw-r--r--source/modules/getdate.c9
-rw-r--r--source/modules/getdate.y9
-rw-r--r--source/modules/vfs_catia.c317
-rw-r--r--source/modules/vfs_fake_perms.c6
-rw-r--r--source/modules/weird.c4
-rw-r--r--source/nmbd/nmbd.c4
-rw-r--r--source/nmbd/nmbd_subnetdb.c2
-rw-r--r--source/nmbd/nmbd_synclists.c3
-rw-r--r--source/nsswitch/wb_client.c2
-rw-r--r--source/nsswitch/wb_common.c7
-rw-r--r--source/nsswitch/winbindd.c2
-rw-r--r--source/nsswitch/winbindd.h1
-rw-r--r--source/nsswitch/winbindd_acct.c2
-rw-r--r--source/nsswitch/winbindd_ads.c3
-rw-r--r--source/nsswitch/winbindd_cache.c12
-rw-r--r--source/nsswitch/winbindd_group.c54
-rw-r--r--source/nsswitch/winbindd_nss.h2
-rw-r--r--source/nsswitch/winbindd_rpc.c3
-rw-r--r--source/nsswitch/winbindd_util.c21
-rw-r--r--source/param/loadparm.c58
-rw-r--r--source/param/params.c3
-rw-r--r--source/passdb/machine_sid.c2
-rw-r--r--source/passdb/passdb.c2
-rw-r--r--source/passdb/pdb_get_set.c2
-rw-r--r--source/passdb/pdb_interface.c485
-rw-r--r--source/passdb/pdb_ldap.c289
-rw-r--r--source/passdb/secrets.c19
-rw-r--r--source/passdb/util_sam_sid.c10
-rw-r--r--source/printing/nt_printing.c5
-rw-r--r--source/printing/printfsp.c3
-rw-r--r--source/printing/printing.c51
-rw-r--r--source/python/py_smb.c2
-rw-r--r--source/registry/reg_db.c7
-rw-r--r--source/registry/reg_eventlog.c302
-rw-r--r--source/registry/reg_frontend.c5
-rw-r--r--source/rpc_client/cli_lsarpc.c107
-rw-r--r--source/rpc_client/cli_reg.c721
-rw-r--r--source/rpc_client/cli_shutdown.c52
-rw-r--r--source/rpc_client/cli_spoolss.c84
-rw-r--r--source/rpc_client/cli_svcctl.c415
-rw-r--r--source/rpc_parse/parse_buffer.c491
-rw-r--r--source/rpc_parse/parse_eventlog.c457
-rw-r--r--source/rpc_parse/parse_lsa.c171
-rw-r--r--source/rpc_parse/parse_misc.c480
-rw-r--r--source/rpc_parse/parse_net.c21
-rw-r--r--source/rpc_parse/parse_prs.c53
-rw-r--r--source/rpc_parse/parse_reg.c1103
-rw-r--r--source/rpc_parse/parse_rpc.c45
-rw-r--r--source/rpc_parse/parse_sec.c2
-rw-r--r--source/rpc_parse/parse_shutdown.c123
-rw-r--r--source/rpc_parse/parse_spoolss.c689
-rw-r--r--source/rpc_parse/parse_srv.c73
-rw-r--r--source/rpc_parse/parse_svcctl.c660
-rw-r--r--source/rpc_server/srv_eventlog.c206
-rw-r--r--source/rpc_server/srv_eventlog_nt.c923
-rw-r--r--source/rpc_server/srv_lsa_ds_nt.c7
-rw-r--r--source/rpc_server/srv_lsa_nt.c35
-rw-r--r--source/rpc_server/srv_netlog.c2
-rw-r--r--source/rpc_server/srv_netlog_nt.c5
-rw-r--r--source/rpc_server/srv_pipe.c12
-rw-r--r--source/rpc_server/srv_reg.c97
-rw-r--r--source/rpc_server/srv_reg_nt.c205
-rw-r--r--source/rpc_server/srv_samr_nt.c136
-rw-r--r--source/rpc_server/srv_samr_util.c2
-rwxr-xr-xsource/rpc_server/srv_spoolss.c3
-rw-r--r--source/rpc_server/srv_spoolss_nt.c953
-rw-r--r--source/rpc_server/srv_srvsvc.c29
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c71
-rw-r--r--source/rpc_server/srv_svcctl.c294
-rw-r--r--source/rpc_server/srv_svcctl_nt.c295
-rw-r--r--source/rpc_server/srv_util.c3
-rw-r--r--source/rpcclient/cmd_reg.c32
-rw-r--r--source/rpcclient/cmd_samr.c82
-rw-r--r--source/rpcclient/cmd_shutdown.c6
-rw-r--r--source/rpcclient/cmd_spoolss.c85
-rw-r--r--source/rpcclient/rpcclient.c2
-rw-r--r--source/sam/idmap_util.c103
-rwxr-xr-xsource/script/installman.sh2
-rw-r--r--source/smbd/chgpasswd.c7
-rw-r--r--source/smbd/dir.c15
-rw-r--r--source/smbd/dosmode.c4
-rw-r--r--source/smbd/error.c145
-rw-r--r--source/smbd/fake_file.c3
-rw-r--r--source/smbd/filename.c2
-rw-r--r--source/smbd/files.c6
-rw-r--r--source/smbd/lanman.c107
-rw-r--r--source/smbd/msdfs.c42
-rw-r--r--source/smbd/negprot.c3
-rw-r--r--source/smbd/notify_kernel.c10
-rw-r--r--source/smbd/nttrans.c303
-rw-r--r--source/smbd/open.c258
-rw-r--r--source/smbd/oplock.c18
-rw-r--r--source/smbd/oplock_linux.c30
-rw-r--r--source/smbd/posix_acls.c31
-rw-r--r--source/smbd/process.c12
-rw-r--r--source/smbd/quotas.c15
-rw-r--r--source/smbd/reply.c340
-rw-r--r--source/smbd/server.c4
-rw-r--r--source/smbd/service.c4
-rw-r--r--source/smbd/sesssetup.c27
-rw-r--r--source/smbd/statcache.c5
-rw-r--r--source/smbd/trans2.c998
-rw-r--r--source/smbwrapper/smbw.c2
-rw-r--r--source/smbwrapper/smbw_stat.c24
-rw-r--r--source/tdb/tdb.c2
-rw-r--r--source/tdb/tdbbackup.c5
-rw-r--r--source/tdb/tdbtool.c4
-rw-r--r--source/tdb/tdbutil.c11
-rw-r--r--source/torture/torture.c6
-rw-r--r--source/torture/utable.c2
-rw-r--r--source/utils/net.c74
-rw-r--r--source/utils/net_ads.c4
-rw-r--r--source/utils/net_groupmap.c52
-rw-r--r--source/utils/net_lookup.c4
-rw-r--r--source/utils/net_rap.c18
-rw-r--r--source/utils/net_rpc.c90
-rw-r--r--source/utils/net_rpc_rights.c182
-rw-r--r--source/utils/net_rpc_samsync.c4
-rw-r--r--source/utils/net_rpc_service.c529
-rw-r--r--source/utils/pdbedit.c4
-rw-r--r--source/utils/smbcontrol.c3
-rw-r--r--source/utils/smbpasswd.c2
-rw-r--r--source/web/diagnose.c2
-rw-r--r--source/web/neg_lang.c4
204 files changed, 14179 insertions, 5343 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index fda2bd3d93a..c4619079841 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -92,8 +92,6 @@ LOCKDIR = @lockdir@
# the directory where pid files go
PIDDIR = @piddir@
-# man pages language(s)
-man_langs = "@manlangs@"
LIBSMBCLIENT=bin/libsmbclient.a @LIBSMBCLIENT_SHARED@
LIBSMBCLIENT_MAJOR=0
@@ -173,6 +171,8 @@ SNPRINTF_OBJ = lib/snprintf.o
WBCOMMON_OBJ = nsswitch/wb_common.o
+DUMMYROOT_OBJ = lib/dummyroot.o
+
AFS_OBJ = lib/afs.o
AFS_SETTOKEN_OBJ = lib/afs_settoken.o
@@ -206,7 +206,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
-LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummyroot.o lib/dummysmbd.o
+LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
READLINE_OBJ = lib/readline.o
@@ -255,12 +255,12 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
rpc_client/cli_ds.o rpc_client/cli_echo.o \
- rpc_client/cli_shutdown.o
+ rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
REGOBJS_OBJ = registry/reg_objects.o
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
- registry/reg_db.o
+ registry/reg_db.o registry/reg_eventlog.o
RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o
@@ -277,10 +277,14 @@ RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
RPC_WKS_OBJ = rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
+RPC_SVCCTL_OBJ = rpc_server/srv_svcctl.o rpc_server/srv_svcctl_nt.o
+
RPC_DFS_OBJ = rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
+RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o
+
RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
@@ -298,7 +302,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
rpc_parse/parse_wks.o rpc_parse/parse_ds.o \
rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
- $(REGOBJS_OBJ)
+ rpc_parse/parse_svcctl.o \
+ rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o $(REGOBJS_OBJ)
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
@@ -342,6 +347,7 @@ VFS_CAP_OBJ = modules/vfs_cap.o
VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
VFS_AFSACL_OBJ = modules/vfs_afsacl.o
+VFS_CATIA_OBJ = modules/vfs_catia.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -434,20 +440,20 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \
- $(PASSCHANGE_OBJ)
+ $(PASSCHANGE_OBJ) $(DUMMYROOT_OBJ)
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ)
STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(ERRORMAP_OBJ)
+ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
$(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
- $(PRINTBASE_OBJ) $(ERRORMAP_OBJ)
+ $(PRINTBASE_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
@@ -463,11 +469,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSCHANGE_OBJ) $(PARAM_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
- $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ)
+ $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) $(DUMMYROOT_OBJ)
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
$(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(SMBLDAP_OBJ)
+ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ) libsmb/asn1.o
SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ)
@@ -483,7 +489,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ)
+ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ)
PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \
nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \
@@ -505,8 +511,8 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
libsmb/libsmb_cache.o \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
- $(SECRETS_OBJ)
+ $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
+ $(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ)
# This shared library is intended for linking with unit test programs
# to test Samba internals. It's called libbigballofmud.so to
@@ -516,7 +522,7 @@ LIBBIGBALLOFMUD_MAJOR = 0
LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
- $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
+ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
@@ -530,15 +536,16 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
- utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o
+ utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o \
+ utils/net_rpc_service.o
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
- $(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
+ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ) $(SERVER_MUTEX_OBJ) \
+ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(PRINTERDB_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
@@ -566,7 +573,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+ $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
@@ -578,17 +585,18 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ
LOG2PCAP_OBJ = utils/log2pcaphex.o
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
- $(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ)
+ $(PASSDB_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
+ $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ) $(SMBLDAP_OBJ)
SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(PARAM_OBJ) \
- $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
- $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+ $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
+ $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
+ $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(DUMMYROOT_OBJ)
TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) libsmb/nterr.o
@@ -619,7 +627,8 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
- $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
+ $(RPC_ECHO_OBJ) $(RPC_SVCCTL_OBJ) $(RPC_EVENTLOG_OBJ) $(SMBLDAP_OBJ) \
+ $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
@@ -631,7 +640,7 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
- $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
+ $(DUMMYROOT_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(SECRETS_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
@@ -661,7 +670,7 @@ WINBINDD_OBJ = \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
$(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
$(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
- $(DCUTIL_OBJ) $(IDMAP_OBJ) \
+ $(DCUTIL_OBJ) $(IDMAP_OBJ) $(DUMMYROOT_OBJ) \
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -970,7 +979,7 @@ bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy
bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS)
bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
@echo Linking $@
@@ -1026,6 +1035,11 @@ bin/librpc_srvsvc.@SHLIBEXT@: $(RPC_SVC_OBJ)
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVC_OBJ) -lc \
@SONAMEFLAG@`basename $@`
+bin/librpc_svcctl.@SHLIBEXT@: $(RPC_SVCCTL_OBJ)
+ @echo "Linking $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVCCTL_OBJ) -lc \
+ @SONAMEFLAG@`basename $@`
+
bin/librpc_wkssvc.@SHLIBEXT@: $(RPC_WKS_OBJ)
@echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_WKS_OBJ) -lc \
@@ -1228,6 +1242,12 @@ bin/afsacl.@SHLIBEXT@: $(VFS_AFSACL_OBJ:.o=.po)
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AFSACL_OBJ:.o=.po) \
@SONAMEFLAG@`basename $@`
+bin/catia.@SHLIBEXT@: $(VFS_CATIA_OBJ:.o=.@PICSUFFIX@)
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CATIA_OBJ:.o=.@PICSUFFIX@) \
+ @SONAMEFLAG@`basename $@`
+
+
bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@
@@ -1335,7 +1355,7 @@ installclientlib: installdirs libsmbclient
PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
$(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
+ $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
@@ -1368,7 +1388,7 @@ revert:
@$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(BIN_PROGS) $(SCRIPTS)
installman: installdirs
- @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs) "@ROFF@"
+ @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
.PHONY: showlayout
@@ -1390,7 +1410,7 @@ showlayout:
uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules
uninstallman:
- @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs)
+ @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
uninstallbin:
@$(SHELL) $(srcdir)/script/uninstallbin.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(SBINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(VARDIR) $(DESTDIR)$(SBIN_PROGS)
diff --git a/source/VERSION b/source/VERSION
index 026b4553ff8..4d50fe3468e 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -19,7 +19,7 @@
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=14
+SAMBA_VERSION_RELEASE=15
########################################################
# For 'pre' releases the version will be #
@@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=14
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=
+SAMBA_VERSION_PRE_RELEASE=1
########################################################
# For 'rc' releases the version will be #
diff --git a/source/auth/auth_compat.c b/source/auth/auth_compat.c
index a70f1e98b72..2ac70d73546 100644
--- a/source/auth/auth_compat.c
+++ b/source/auth/auth_compat.c
@@ -20,6 +20,9 @@
#include "includes.h"
+extern struct auth_context *negprot_global_auth_context;
+extern BOOL global_encrypted_passwords_negotiated;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
@@ -68,7 +71,6 @@ static NTSTATUS pass_check_smb(const char *smb_name,
{
NTSTATUS nt_status;
- extern struct auth_context *negprot_global_auth_context;
auth_serversupplied_info *server_info = NULL;
if (encrypted) {
auth_usersupplied_info *user_info = NULL;
@@ -94,7 +96,6 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
{
DATA_BLOB null_password = data_blob(NULL, 0);
- extern BOOL global_encrypted_passwords_negotiated;
BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
if (encrypted) {
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 9da59f220aa..023e441e241 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -23,6 +23,8 @@
#include "includes.h"
+extern struct timeval smb_last_time;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
@@ -74,7 +76,6 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
static BOOL logon_hours_ok(SAM_ACCOUNT *sampass)
{
/* In logon hours first bit is Sunday from 12AM to 1AM */
- extern struct timeval smb_last_time;
const uint8 *hours;
struct tm *utctime;
uint8 bitmask, bitpos;
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 7cab3df99e4..a50a449815c 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -26,11 +26,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Network;
-extern DOM_SID global_sid_Builtin_Guests;
-extern DOM_SID global_sid_Authenticated_Users;
-
/****************************************************************************
Create a UNIX user on demand.
diff --git a/source/client/client.c b/source/client/client.c
index 07eb02cf05c..604bf0989a8 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -29,6 +29,9 @@
#define REGISTER 0
#endif
+extern BOOL AllowDebugChange;
+extern BOOL override_logfile;
+extern char tar_type;
extern BOOL in_client;
static int port = 0;
pstring cur_dir = "\\";
@@ -711,7 +714,7 @@ static int do_get(char *rname, char *lname, BOOL reget)
struct timeval tp_start;
int read_size = io_bufsize;
uint16 attr;
- size_t size;
+ SMB_OFF_T size;
off_t start = 0;
off_t nread = 0;
int rc = 0;
@@ -1135,7 +1138,7 @@ static int do_put(char *rname, char *lname, BOOL reput)
{
int fnum;
XFILE *f;
- size_t start = 0;
+ SMB_OFF_T start = 0;
off_t nread = 0;
char *buf = NULL;
int maxwrite = io_bufsize;
@@ -2236,6 +2239,25 @@ static int cmd_rename(void)
}
/****************************************************************************
+ Print the volume name.
+****************************************************************************/
+
+static int cmd_volume(void)
+{
+ fstring volname;
+ uint32 serial_num;
+ time_t create_date;
+
+ if (!cli_get_fs_volume_info(cli, volname, &serial_num, &create_date)) {
+ d_printf("Errr %s getting volume info\n",cli_errstr(cli));
+ return 1;
+ }
+
+ d_printf("Volume: |%s| serial number 0x%x\n", volname, (unsigned int)serial_num);
+ return 0;
+}
+
+/****************************************************************************
Hard link files using the NT call.
****************************************************************************/
@@ -2748,6 +2770,7 @@ static struct
{"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}},
+ {"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}},
{"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}},
{"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
{"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}},
@@ -3271,13 +3294,10 @@ static int do_message_op(void)
int main(int argc,char *argv[])
{
- extern BOOL AllowDebugChange;
- extern BOOL override_logfile;
pstring base_directory;
int opt;
pstring query_host;
BOOL message = False;
- extern char tar_type;
pstring term_code;
static const char *new_name_resolve_order = NULL;
poptContext pc;
diff --git a/source/client/clitar.c b/source/client/clitar.c
index 524feca1d2a..b241bd0ec2a 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -44,7 +44,7 @@ static int clipfind(char **aret, int ret, char *tok);
typedef struct file_info_struct file_info2;
struct file_info_struct {
- SMB_BIG_UINT size;
+ SMB_OFF_T size;
uint16 mode;
uid_t uid;
gid_t gid;
@@ -63,6 +63,7 @@ typedef struct {
} stack;
#define SEPARATORS " \t\n\r"
+extern time_t newer_than;
extern struct cli_state *cli;
/* These defines are for the do_setrattr routine, to indicate
@@ -1621,7 +1622,6 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
return 0;
} else {
SMB_STRUCT_STAT stbuf;
- extern time_t newer_than;
if (sys_stat(argv[Optind], &stbuf) == 0) {
newer_than = stbuf.st_mtime;
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 7b30b98fa7b..3145447cc4e 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -1,6 +1,6 @@
/*
Mount helper utility for Linux CIFS VFS (virtual filesystem) client
- Copyright (C) 2003 Steve French (sfrench@us.ibm.com)
+ Copyright (C) 2003,2005 Steve French (sfrench@us.ibm.com)
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
@@ -39,7 +39,7 @@
#include <fcntl.h>
#define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "6"
+#define MOUNT_CIFS_VERSION_MINOR "7"
#ifndef MOUNT_CIFS_VENDOR_SUFFIX
#define MOUNT_CIFS_VENDOR_SUFFIX ""
@@ -60,7 +60,8 @@ static int got_uid = 0;
static int got_gid = 0;
static int free_share_name = 0;
static char * user_name = NULL;
-char * mountpassword = NULL;
+static char * mountpassword = NULL;
+char * domain_name = NULL;
/* BB finish BB
@@ -72,6 +73,9 @@ char * mountpassword = NULL;
BB end finish BB */
+static char * check_for_domain(char **);
+
+
static void mount_cifs_usage(void)
{
printf("\nUsage: %s <remotetarget> <dir> -o <options>\n", thisprogram);
@@ -79,11 +83,11 @@ static void mount_cifs_usage(void)
printf(" to a local directory.\n\nOptions:\n");
printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
printf("\nLess commonly used options:");
- printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,\n\trw,ro,sep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,directio");
- printf("\n\nOptions not needed for servers supporting CIFS Unix extensions (e.g. most Samba versions):");
+ printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,\n\tdirectio");
+ printf("\n\nOptions not needed for servers supporting CIFS Unix extensions\n\t(e.g. most Samba versions):");
printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>");
printf("\n\nRarely used options:");
- printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,dev,nodev");
+ printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,\n\tdev,nodev,nouser_xattr,netbiosname,hard,soft,intr,nointr,noacl");
printf("\n\nOptions are described in more detail in the manual page");
printf("\n\tman 8 mount.cifs\n");
printf("\nTo display the version number of the mount helper:");
@@ -107,7 +111,7 @@ static char * getusername(void) {
return username;
}
-char * parse_cifs_url(char * unc_name)
+static char * parse_cifs_url(char * unc_name)
{
printf("\nMounting cifs URL not implemented yet. Attempt to mount %s\n",unc_name);
return NULL;
@@ -264,7 +268,9 @@ static int parse_options(char * options, int * filesys_flags)
data = options;
if(verboseflag)
- printf("\n parsing options: %s", options);
+ printf("parsing options: %s\n", options);
+
+ /* BB fixme check for separator override BB */
/* while ((data = strsep(&options, ",")) != NULL) { */
while(data != NULL) {
@@ -276,15 +282,12 @@ static int parse_options(char * options, int * filesys_flags)
/* data = next keyword */
/* value = next value ie stuff after equal sign */
- next_keyword = strchr(data,',');
+ next_keyword = strchr(data,','); /* BB handle sep= */
/* temporarily null terminate end of keyword=value pair */
if(next_keyword)
*next_keyword = 0;
- /* if (!*data)
- continue; */
-
/* temporarily null terminate keyword to make keyword and value distinct */
if ((value = strchr(data, '=')) != NULL) {
*value = '\0';
@@ -298,6 +301,7 @@ static int parse_options(char * options, int * filesys_flags)
} else if (strncmp(data, "user_xattr",10) == 0) {
/* do nothing - need to skip so not parsed as user name */
} else if (strncmp(data, "user", 4) == 0) {
+
if (!value || !*value) {
if(data[4] == '\0') {
if(verboseflag)
@@ -308,7 +312,6 @@ static int parse_options(char * options, int * filesys_flags)
data[1] = ',';
data[2] = ',';
data[3] = ',';
- /* BB remove it from mount line so as not to confuse kernel code */
} else {
printf("username specified with no parameter\n");
return 1; /* needs_arg; */
@@ -334,6 +337,13 @@ static int parse_options(char * options, int * filesys_flags)
}
}
}
+ /* this is only case in which the user
+ name buf is not malloc - so we have to
+ check for domain name embedded within
+ the user name here since the later
+ call to check_for_domain will not be
+ invoked */
+ domain_name = check_for_domain(&value);
} else {
printf("username too long\n");
return 1;
@@ -516,15 +526,135 @@ static int parse_options(char * options, int * filesys_flags)
/* put previous overwritten comma back */
if(next_keyword)
- *next_keyword = ',';
+ *next_keyword = ','; /* BB handle sep= */
else
data = NULL;
}
return 0;
}
+/* replace all (one or more) commas with double commas */
+static void check_for_comma(char ** ppasswrd)
+{
+ char *new_pass_buf;
+ char *pass;
+ int i,j;
+ int number_of_commas = 0;
+ int len = strlen(*ppasswrd);
+
+ if(ppasswrd == NULL)
+ return;
+ else
+ (pass = *ppasswrd);
+
+ for(i=0;i<len;i++) {
+ if(pass[i] == ',')
+ number_of_commas++;
+ }
+
+ if(number_of_commas == 0)
+ return;
+ if(number_of_commas > 64) {
+ /* would otherwise overflow the mount options buffer */
+ printf("\nInvalid password. Password contains too many commas.\n");
+ return;
+ }
+
+ new_pass_buf = malloc(len+number_of_commas+1);
+ if(new_pass_buf == NULL)
+ return;
+
+ for(i=0,j=0;i<len;i++,j++) {
+ new_pass_buf[j] = pass[i];
+ if(pass[i] == ',') {
+ j++;
+ new_pass_buf[j] = pass[i];
+ }
+ }
+ new_pass_buf[len+number_of_commas] = 0;
+
+ free(*ppasswrd);
+ *ppasswrd = new_pass_buf;
+
+ return;
+}
+
+/* Usernames can not have backslash in them and we use
+ [BB check if usernames can have forward slash in them BB]
+ backslash as domain\user separator character
+*/
+static char * check_for_domain(char **ppuser)
+{
+ char * original_string;
+ char * usernm;
+ char * domainnm;
+ int original_len;
+ int len;
+ int i;
+
+ if(ppuser == NULL)
+ return NULL;
+
+ original_string = *ppuser;
+
+ if (original_string == NULL)
+ return NULL;
+
+ original_len = strlen(original_string);
+
+ usernm = strchr(*ppuser,'/');
+ if (usernm == NULL) {
+ usernm = strchr(*ppuser,'\\');
+ if (usernm == NULL)
+ return NULL;
+ }
+
+ if(got_domain) {
+ printf("Domain name specified twice. Username probably malformed\n");
+ return NULL;
+ }
+
+ usernm[0] = 0;
+ domainnm = *ppuser;
+ if (domainnm[0] != 0) {
+ got_domain = 1;
+ } else {
+ printf("null domain\n");
+ }
+ len = strlen(domainnm);
+ /* reset domainm to new buffer, and copy
+ domain name into it */
+ domainnm = malloc(len+1);
+ if(domainnm == NULL)
+ return NULL;
+
+ strcpy(domainnm,*ppuser);
+
+/* move_string(*ppuser, usernm+1) */
+ len = strlen(usernm+1);
+
+ if(len >= original_len) {
+ /* should not happen */
+ return domainnm;
+ }
+
+ for(i=0;i<original_len;i++) {
+ if(i<len)
+ original_string[i] = usernm[i+1];
+ else /* stuff with commas to remove last parm */
+ original_string[i] = ',';
+ }
+
+ /* BB add check for more than one slash?
+ strchr(*ppuser,'/');
+ strchr(*ppuser,'\\')
+ */
+
+ return domainnm;
+}
+
/* Note that caller frees the returned buffer if necessary */
-char * parse_server(char ** punc_name)
+static char * parse_server(char ** punc_name)
{
char * unc_name = *punc_name;
int length = strnlen(unc_name,1024);
@@ -645,7 +775,6 @@ int main(int argc, char ** argv)
int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */
char * orgoptions = NULL;
char * share_name = NULL;
- char * domain_name = NULL;
char * ipaddr = NULL;
char * uuid = NULL;
char * mountpoint;
@@ -756,7 +885,7 @@ int main(int argc, char ** argv)
user_name = optarg;
break;
case 'd':
- domain_name = optarg;
+ domain_name = optarg; /* BB fix this - currently ignored */
break;
case 'p':
if(mountpassword == NULL)
@@ -796,14 +925,12 @@ int main(int argc, char ** argv)
if (orgoptions && parse_options(orgoptions, &flags))
return -1;
-
ipaddr = parse_server(&share_name);
if((ipaddr == NULL) && (got_ip == 0)) {
printf("No ip address specified and hostname not found\n");
return -1;
}
-
/* BB save off path and pop after mount returns? */
resolved_path = malloc(PATH_MAX+1);
if(resolved_path) {
@@ -841,8 +968,10 @@ int main(int argc, char ** argv)
}
}
- if(got_user == 0)
+ if(got_user == 0) {
user_name = getusername();
+ got_user = 1;
+ }
if(got_password == 0) {
mountpassword = getpass("Password: "); /* BB obsolete */
@@ -864,7 +993,7 @@ mount_retry:
optlen += strlen(ipaddr) + 4;
if(mountpassword)
optlen += strlen(mountpassword) + 6;
- options = malloc(optlen + 10);
+ options = malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */);
if(options == NULL) {
printf("Could not allocate memory for mount options\n");
@@ -882,15 +1011,31 @@ mount_retry:
if(ipaddr) {
strncat(options,",ip=",4);
strcat(options,ipaddr);
- }
+ }
+
if(user_name) {
+ /* check for syntax like user=domain\user */
+ domain_name = check_for_domain(&user_name);
strncat(options,",user=",6);
strcat(options,user_name);
- }
+ }
+ if(retry == 0) {
+ if(domain_name) {
+ /* extra length accounted for in option string above */
+ strncat(options,",domain=",8);
+ strcat(options,domain_name);
+ }
+ }
if(mountpassword) {
+ /* Commas have to be doubled, or else they will
+ look like the parameter separator */
+/* if(sep is not set)*/
+ if(retry == 0)
+ check_for_comma(&mountpassword);
strncat(options,",pass=",6);
strcat(options,mountpassword);
}
+
strncat(options,",ver=",5);
strcat(options,MOUNT_CIFS_VERSION_MAJOR);
@@ -978,7 +1123,8 @@ mount_retry:
}
}
if(mountpassword) {
- memset(mountpassword,0,64);
+ int len = strlen(mountpassword);
+ memset(mountpassword,0,len);
free(mountpassword);
}
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index 5df6bfe407e..aeb4c91b19c 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -148,12 +148,12 @@ static int smb_print(struct cli_state *, char *, FILE *);
if ((password = strchr_m(username, ':')) != NULL)
*password++ = '\0';
else
- password = "";
+ password = CONST_DISCARD(char *, "");
}
else
{
username = "";
- password = "";
+ password = CONST_DISCARD(char *, "");
server = uri + 6;
}
diff --git a/source/client/umount.cifs.c b/source/client/umount.cifs.c
new file mode 100644
index 00000000000..18dbc3b1cf6
--- /dev/null
+++ b/source/client/umount.cifs.c
@@ -0,0 +1,273 @@
+/*
+ Unmount utility program for Linux CIFS VFS (virtual filesystem) client
+ Copyright (C) 2005 Steve French (sfrench@us.ibm.com)
+
+ 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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <errno.h>
+#include <string.h>
+#include <mntent.h>
+
+#define UNMOUNT_CIFS_VERSION_MAJOR "0"
+#define UNMOUNT_CIFS_VERSION_MINOR "1"
+
+#ifndef UNMOUNT_CIFS_VENDOR_SUFFIX
+#define UNMOUNT_CIFS_VENDOR_SUFFIX ""
+#endif
+
+#ifndef MNT_DETACH
+#define MNT_DETACH 0x02
+#endif
+
+#ifndef MNT_EXPIRE
+#define MNT_EXPIRE 0x04
+#endif
+
+#define CIFS_IOC_CHECKUMOUNT _IO('c', 2)
+
+static struct option longopts[] = {
+ { "all", 0, NULL, 'a' },
+ { "help",0, NULL, 'h' },
+ { "read-only", 0, NULL, 'r' },
+ { "ro", 0, NULL, 'r' },
+ { "verbose", 0, NULL, 'v' },
+ { "version", 0, NULL, 'V' },
+ { "expire", 0, NULL, 'e' },
+ { "force", 0, 0, 'f' },
+ { "lazy", 0, 0, 'l' },
+ { "no-mtab", 0, 0, 'n' },
+ { NULL, 0, NULL, 0 }
+};
+
+char * thisprogram;
+int verboseflg = 0;
+
+static void umount_cifs_usage(void)
+{
+ printf("\nUsage: %s <remotetarget> <dir>\n", thisprogram);
+ printf("\nUnmount the specified directory\n");
+ printf("\nLess commonly used options:");
+ printf("\n\t-r\tIf mount fails, retry with readonly remount.");
+ printf("\n\t-n\tDo not write to mtab.");
+ printf("\n\t-f\tAttempt a forced unmount, even if the fs is busy.");
+ printf("\n\t-l\tAttempt lazy unmount, Unmount now, cleanup later.");
+ printf("\n\t-v\tEnable verbose mode (may be useful for debugging).");
+ printf("\n\t-h\tDisplay this help.");
+ printf("\n\nOptions are described in more detail in the manual page");
+ printf("\n\tman 8 umount.cifs\n");
+ printf("\nTo display the version number of the cifs umount utility:");
+ printf("\n\t%s -V\n",thisprogram);
+}
+
+static int umount_check_perm(char * dir)
+{
+ int fileid;
+ int rc;
+
+ /* presumably can not chdir into the target as we do on mount */
+
+ fileid = open(dir, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, 0);
+ if(fileid == -1) {
+ if(verboseflg)
+ printf("error opening mountpoint %d %s",errno,strerror(errno));
+ return errno;
+ }
+
+ rc = ioctl(fileid, CIFS_IOC_CHECKUMOUNT, NULL);
+
+ if(verboseflg)
+ printf("ioctl returned %d with errno %d %s\n",rc,errno,strerror(errno));
+
+ if(rc == ENOTTY)
+ printf("user unmounting via %s is an optional feature of the cifs filesystem driver (cifs.ko)\n\tand requires cifs.ko version 1.32 or later\n",thisprogram);
+ else if (rc > 0)
+ printf("user unmount of %s failed with %d %s",dir,errno,strerror(errno));
+ close(fileid);
+
+ return rc;
+}
+
+int main(int argc, char ** argv)
+{
+ int c;
+ int rc;
+ int flags = 0;
+ int nomtab = 0;
+ int retry_remount = 0;
+ struct mntent mountent;
+ char * mountpoint;
+ FILE * pmntfile;
+
+ if(argc && argv) {
+ thisprogram = argv[0];
+ } else {
+ umount_cifs_usage();
+ return -EINVAL;
+ }
+
+ if(argc < 2) {
+ umount_cifs_usage();
+ return -EINVAL;
+ }
+
+ if(thisprogram == NULL)
+ thisprogram = "umount.cifs";
+
+ /* add sharename in opts string as unc= parm */
+
+ while ((c = getopt_long (argc, argv, "afhilnrvV",
+ longopts, NULL)) != -1) {
+ switch (c) {
+/* No code to do the following option yet */
+/* case 'a':
+ ++umount_all;
+ break; */
+ case '?':
+ case 'h': /* help */
+ umount_cifs_usage();
+ exit(1);
+ case 'n':
+ ++nomtab;
+ break;
+ case 'f':
+ flags |= MNT_FORCE;
+ break;
+ case 'l':
+ flags |= MNT_DETACH; /* lazy unmount */
+ break;
+ case 'e':
+ flags |= MNT_EXPIRE; /* gradually timeout */
+ break;
+ case 'r':
+ ++retry_remount;
+ break;
+ case 'v':
+ ++verboseflg;
+ break;
+ case 'V':
+ printf ("umount.cifs version: %s.%s%s\n",
+ UNMOUNT_CIFS_VERSION_MAJOR,
+ UNMOUNT_CIFS_VERSION_MINOR,
+ UNMOUNT_CIFS_VENDOR_SUFFIX);
+ exit (0);
+ default:
+ printf("unknown unmount option %c\n",c);
+ umount_cifs_usage();
+ exit(1);
+ }
+ }
+
+ /* move past the umount options */
+ argv += optind;
+ argc -= optind;
+
+ mountpoint = argv[0];
+
+ if((argc < 1) || (argv[0] == NULL)) {
+ printf("\nMissing name of unmount directory\n");
+ umount_cifs_usage();
+ return -EINVAL;
+ }
+
+ if(verboseflg)
+ printf("optind %d unmount dir %s\n",optind, mountpoint);
+
+ /* check if running effectively root */
+ if(geteuid() != 0)
+ printf("Trying to unmount when %s not installed suid\n",thisprogram);
+
+ /* fixup path if needed */
+
+ /* check if our uid was the one who mounted */
+ rc = umount_check_perm(mountpoint);
+ if (rc) {
+ return rc;
+ }
+
+ if(umount2(mountpoint, flags)) {
+ /* remember to kill daemon on error */
+
+ switch (errno) {
+ case 0:
+ printf("mount failed but no error number set\n");
+ break;
+ default:
+
+ printf("mount error %d = %s\n",errno,strerror(errno));
+ }
+ printf("Refer to the umount.cifs(8) manual page (e.g.man 8 umount.cifs)\n");
+ return -1;
+ } else {
+ pmntfile = setmntent(MOUNTED, "a+");
+ if(pmntfile) {
+/* mountent.mnt_fsname = share_name;
+ mountent.mnt_dir = mountpoint;
+ mountent.mnt_type = "cifs";
+ mountent.mnt_opts = malloc(220);
+ if(mountent.mnt_opts) {
+ char * mount_user = getusername();
+ memset(mountent.mnt_opts,0,200);
+ if(flags & MS_RDONLY)
+ strcat(mountent.mnt_opts,"ro");
+ else
+ strcat(mountent.mnt_opts,"rw");
+ if(flags & MS_MANDLOCK)
+ strcat(mountent.mnt_opts,",mand");
+ else
+ strcat(mountent.mnt_opts,",nomand");
+ if(flags & MS_NOEXEC)
+ strcat(mountent.mnt_opts,",noexec");
+ if(flags & MS_NOSUID)
+ strcat(mountent.mnt_opts,",nosuid");
+ if(flags & MS_NODEV)
+ strcat(mountent.mnt_opts,",nodev");
+ if(flags & MS_SYNCHRONOUS)
+ strcat(mountent.mnt_opts,",synch");
+ if(mount_user) {
+ if(getuid() != 0) {
+ strcat(mountent.mnt_opts,",user=");
+ strcat(mountent.mnt_opts,mount_user);
+ }
+ free(mount_user);
+ }
+ }
+ mountent.mnt_freq = 0;
+ mountent.mnt_passno = 0;
+ rc = addmntent(pmntfile,&mountent);
+ endmntent(pmntfile);
+ if(mountent.mnt_opts)
+ free(mountent.mnt_opts);*/
+ } else {
+ printf("could not update mount table\n");
+ }
+ }
+
+ return 0;
+}
+
diff --git a/source/configure.in b/source/configure.in
index f81d7fbb17d..fce7e268256 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -248,7 +248,7 @@ fi
AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
[if eval "test x$enable_developer = xyes"; then
developer=yes
- CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
# Add -Wdeclaration-after-statement if compiler supports it
AC_CACHE_CHECK(
[that the C compiler understands -Wdeclaration-after-statement],
@@ -416,7 +416,7 @@ DYNEXP=
dnl Add modules that have to be built by default here
dnl These have to be built static:
-default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
+default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin printerdb_file"
dnl These are preferably build shared, and static if dlopen() is not available
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437"
@@ -691,8 +691,10 @@ AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h)
-AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
-AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/mode.h)
+AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
+## These fail to compile on IRIX so just check for their presence
+AC_CHECK_HEADERS(rpcsvc/yp_prot.h, sys/mode.h, [], [] -)
+AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h)
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
@@ -727,8 +729,10 @@ AC_CHECK_HEADERS(shadow.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/cdefs.h glob.h)
-# These faile to compile on Solaris so just check for their presence
+AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h)
+AC_CHECK_HEADERS(sys/cdefs.h glob.h)
+
+## These faile to compile on Solaris so just check for their presence
AC_CHECK_HEADERS(security/pam_modules.h net/if.h netinet/ip.h, [], [], -)
# For experimental utmp support (lastlog on some BSD-like systems)
@@ -1162,6 +1166,18 @@ AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
+# Check if we have extattr
+case "$host_os" in
+ *freebsd4* | *DragonFly* )
+ AC_DEFINE(BROKEN_EXTATTR, 1, [Does extattr API work])
+ ;;
+ *)
+ AC_CHECK_FUNCS(extattr_delete_fd extattr_delete_file extattr_delete_link)
+ AC_CHECK_FUNCS(extattr_get_fd extattr_get_file extattr_get_link)
+ AC_CHECK_FUNCS(extattr_list_fd extattr_list_file extattr_list_link)
+ AC_CHECK_FUNCS(extattr_set_fd extattr_set_file extattr_set_link)
+ ;;
+esac
# Assume non-shared by default and override below
BLDSHARED="false"
@@ -3632,30 +3648,6 @@ else
fi
#################################################
-# choose native language(s) of man pages
-AC_MSG_CHECKING(chosen man pages' language(s))
-AC_ARG_WITH(manpages-langs,
-[ --with-manpages-langs={en,ja,pl} Choose man pages' language(s). (en)],
-[ case "$withval" in
- yes|no)
- AC_MSG_WARN(--with-manpages-langs called without argument - will use default)
- manlangs="en"
- ;;
- *)
- manlangs="$withval"
- ;;
- esac
-
- AC_MSG_RESULT($manlangs)
- manlangs=`echo $manlangs | sed "s/,/ /g"` # replacing commas with spaces to produce a list
- AC_SUBST(manlangs)],
-
- [manlangs="en"
- AC_MSG_RESULT($manlangs)
- AC_SUBST(manlangs)]
-)
-
-#################################################
# should we build libsmbclient?
INSTALLCLIENTCMD_SH=:
@@ -4555,10 +4547,12 @@ SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_svcctl, \$(RPC_SVCCTL_OBJ), "bin/librpc_svcctl.$SHLIBEXT", RPC)
SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_eventlog, \$(RPC_EVENTLOG_OBJ), "bin/librpc_eventlog.$SHLIBEXT", RPC)
SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC,smbd/server.o)
@@ -4595,6 +4589,7 @@ SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_catia, \$(VFS_AFSACL_OBJ), "bin/catia.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 5613240a121..6e9d9b8e6cf 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -518,7 +518,7 @@ static NTSTATUS one_alias_membership(const DOM_SID *member,
if (!string_to_sid(&alias, string_sid))
continue;
- add_sid_to_array_unique(&alias, sids, num);
+ add_sid_to_array_unique(NULL, &alias, sids, num);
if (sids == NULL)
return NT_STATUS_NO_MEMORY;
@@ -665,7 +665,7 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data,
if (!string_to_sid(&member, member_string))
continue;
- add_sid_to_array(&member, closure->sids, closure->num);
+ add_sid_to_array(NULL, &member, closure->sids, closure->num);
}
return 0;
@@ -1253,8 +1253,6 @@ NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods,
uint32 *num_aliases,
struct acct_info **info)
{
- extern DOM_SID global_sid_Builtin;
-
GROUP_MAP *map;
int i, num_maps;
enum SID_NAME_USE type = SID_NAME_UNKNOWN;
@@ -1348,11 +1346,42 @@ NTSTATUS pdb_default_enum_aliasmem(struct pdb_methods *methods,
}
NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
const DOM_SID *members,
int num_members,
- DOM_SID **aliases, int *num)
+ uint32 **alias_rids,
+ int *num_alias_rids)
{
- return alias_memberships(members, num_members, aliases, num);
+ DOM_SID *alias_sids;
+ int i, num_alias_sids;
+ NTSTATUS result;
+
+ alias_sids = NULL;
+ num_alias_sids = 0;
+
+ result = alias_memberships(members, num_members,
+ &alias_sids, &num_alias_sids);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ *alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
+ if ((alias_sids != 0) && (*alias_rids == NULL))
+ return NT_STATUS_NO_MEMORY;
+
+ *num_alias_rids = 0;
+
+ for (i=0; i<num_alias_sids; i++) {
+ if (!sid_peek_check_rid(domain_sid, &alias_sids[i],
+ &(*alias_rids)[*num_alias_rids]))
+ continue;
+ *num_alias_rids += 1;
+ }
+
+ SAFE_FREE(alias_sids);
+
+ return NT_STATUS_OK;
}
/**********************************************************************
diff --git a/source/include/doserr.h b/source/include/doserr.h
index c6d6b1fac90..60a3c335ec4 100644
--- a/source/include/doserr.h
+++ b/source/include/doserr.h
@@ -185,6 +185,8 @@
#define WERR_INVALID_OWNER W_ERROR(1307)
#define WERR_IO_PENDING W_ERROR(997)
#define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
+#define WERR_NO_SUCH_SERVICE W_ERROR(1060)
+#define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052)
#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
#define WERR_INVALID_FORM_NAME W_ERROR(1902)
diff --git a/source/include/includes.h b/source/include/includes.h
index 982eee18862..cf6f493dd6a 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -476,6 +476,14 @@
#include <sys/xattr.h>
#endif
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
#if HAVE_LOCALE_H
#include <locale.h>
#endif
@@ -1372,4 +1380,7 @@ LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to);
#undef HAVE_MMAP
#endif
+#define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr)))
+#define CONST_ADD(type, ptr) ((type) ((const void *) (ptr)))
+
#endif /* _INCLUDES_H */
diff --git a/source/include/libsmb_internal.h b/source/include/libsmb_internal.h
index a1db5c27926..2eca879cbe2 100644
--- a/source/include/libsmb_internal.h
+++ b/source/include/libsmb_internal.h
@@ -35,7 +35,7 @@ struct smbc_dir_list {
struct _SMBCFILE {
int cli_fd;
char *fname;
- off_t offset;
+ SMB_OFF_T offset;
struct _SMBCSRV *srv;
BOOL file;
struct smbc_dir_list *dir_list, *dir_end, *dir_next;
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index 636083b41d4..ea013c113a0 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -26,6 +26,10 @@
#ifndef SMBCLIENT_H_INCLUDED
#define SMBCLIENT_H_INCLUDED
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/*-------------------------------------------------------------------*/
/* The following are special comments to instruct DOXYGEN (automated
* documentation tool:
@@ -550,13 +554,7 @@ struct _SMBCCTX {
*
* @note Do not forget to smbc_init_context() the returned SMBCCTX pointer !
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
SMBCCTX * smbc_new_context(void);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup misc
* Delete a SBMCCTX (a context) acquired from smbc_new_context().
@@ -579,13 +577,8 @@ SMBCCTX * smbc_new_context(void);
* just before exit()'ing. When shutdown_ctx is 0, this function can be
* use in periodical cleanup functions for example.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup misc
* Initialize a SBMCCTX (a context).
@@ -605,13 +598,8 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx);
* but it might leak memory on smbc_context_init() failure. Avoid this.
* You'll have to call smbc_free_context() yourself on failure.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+
SMBCCTX * smbc_init_context(SMBCCTX * context);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup misc
* Initialize the samba client library.
@@ -631,13 +619,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context);
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_init(smbc_get_auth_data_fn fn, int debug);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup misc
* Set or retrieve the compatibility library's context pointer
@@ -661,13 +643,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug);
* authentication functions have been freed, if necessary.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
SMBCCTX * smbc_set_context(SMBCCTX * new_context);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup file
* Open a file on an SMB server.
@@ -720,13 +696,8 @@ SMBCCTX * smbc_set_context(SMBCCTX * new_context);
* try again with an empty username and password. This
* often gets mapped to the guest account on some machines.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+
int smbc_open(const char *furl, int flags, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup file
* Create a file on an SMB server.
@@ -759,13 +730,8 @@ int smbc_open(const char *furl, int flags, mode_t mode);
* @see smbc_open()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
+
int smbc_creat(const char *furl, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup file
* Read from a file using an opened file handle.
@@ -787,13 +753,8 @@ int smbc_creat(const char *furl, mode_t mode);
* @see smbc_open(), smbc_write()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
ssize_t smbc_read(int fd, void *buf, size_t bufsize);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup file
* Write to a file using an opened file handle.
@@ -815,13 +776,8 @@ ssize_t smbc_read(int fd, void *buf, size_t bufsize);
* @see smbc_open(), smbc_read()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
ssize_t smbc_write(int fd, void *buf, size_t bufsize);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup file
* Seek to a specific location in a file.
@@ -851,13 +807,8 @@ ssize_t smbc_write(int fd, void *buf, size_t bufsize);
*
* @todo Are errno values complete and correct?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
off_t smbc_lseek(int fd, off_t offset, int whence);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup file
* Close an open file handle.
@@ -870,13 +821,8 @@ off_t smbc_lseek(int fd, off_t offset, int whence);
*
* @see smbc_open(), smbc_creat()
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_close(int fd);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Unlink (delete) a file or directory.
@@ -899,13 +845,8 @@ int smbc_close(int fd);
*
* @todo Are errno values complete and correct?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_unlink(const char *furl);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Rename or move a file or directory.
@@ -947,13 +888,8 @@ int smbc_unlink(const char *furl);
* share? I say no... NOTE. I agree for the moment.
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_rename(const char *ourl, const char *nurl);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Open a directory used to obtain directory entries.
@@ -975,13 +911,8 @@ int smbc_rename(const char *ourl, const char *nurl);
* @see smbc_getdents(), smbc_readdir(), smbc_closedir()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_opendir(const char *durl);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Close a directory handle opened by smbc_opendir().
@@ -993,13 +924,8 @@ int smbc_opendir(const char *durl);
*
* @see smbc_opendir()
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_closedir(int dh);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Get multiple directory entries.
@@ -1027,13 +953,8 @@ int smbc_closedir(int dh);
*
* @todo Add example code so people know how to parse buffers.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Get a single directory entry.
@@ -1047,13 +968,8 @@ int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
*
* @see smbc_dirent, smbc_getdents(), smbc_open()
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
struct smbc_dirent* smbc_readdir(unsigned int dh);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Get the current directory offset.
@@ -1075,13 +991,8 @@ struct smbc_dirent* smbc_readdir(unsigned int dh);
* @see smbc_readdir()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
off_t smbc_telldir(int dh);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* lseek on directories.
@@ -1105,13 +1016,7 @@ off_t smbc_telldir(int dh);
*
* @todo In what does the reture and errno values mean?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_lseekdir(int fd, off_t offset);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup directory
* Create a directory.
@@ -1134,13 +1039,8 @@ int smbc_lseekdir(int fd, off_t offset);
* @see smbc_rmdir()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_mkdir(const char *durl, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup directory
* Remove a directory.
@@ -1160,13 +1060,8 @@ int smbc_mkdir(const char *durl, mode_t mode);
*
* @todo Are errno values complete and correct?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_rmdir(const char *durl);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Get information about a file or directory.
@@ -1187,13 +1082,8 @@ int smbc_rmdir(const char *durl);
* @see Unix stat()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_stat(const char *url, struct stat *st);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Get file information via an file descriptor.
@@ -1213,13 +1103,8 @@ int smbc_stat(const char *url, struct stat *st);
* @see smbc_stat(), Unix stat()
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_fstat(int fd, struct stat *st);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribue
* Change the ownership of a file or directory.
@@ -1244,13 +1129,8 @@ int smbc_fstat(int fd, struct stat *st);
* @todo How do we abstract owner and group uid and gid?
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_chown(const char *url, uid_t owner, gid_t group);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Change the permissions of a file.
@@ -1272,13 +1152,7 @@ int smbc_chown(const char *url, uid_t owner, gid_t group);
*
* @todo Are errno values complete and correct?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_chmod(const char *url, mode_t mode);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup attribute
* Change the last modification time on a file
@@ -1295,13 +1169,7 @@ int smbc_chmod(const char *url, mode_t mode);
* - EPERM Permission was denied.
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_utimes(const char *url, struct timeval *tbuf);
-#ifdef __cplusplus
-}
-#endif
#ifdef HAVE_UTIME_H
/**@ingroup attribute
@@ -1320,13 +1188,7 @@ int smbc_utimes(const char *url, struct timeval *tbuf);
* - EPERM Permission was denied.
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_utime(const char *fname, struct utimbuf *utbuf);
-#ifdef __cplusplus
-}
-#endif
#endif
/**@ingroup attribute
@@ -1428,17 +1290,12 @@ int smbc_utime(const char *fname, struct utimbuf *utbuf);
* sYsTeM.nt_sEc_desc.owNER
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_setxattr(const char *url,
const char *name,
const void *value,
size_t size,
int flags);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Set extended attributes for a file. This is used for modifying a file's
@@ -1543,17 +1400,12 @@ int smbc_setxattr(const char *url,
* sYsTeM.nt_sEc_desc.owNER
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_lsetxattr(const char *url,
const char *name,
const void *value,
size_t size,
int flags);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Set extended attributes for a file. This is used for modifying a file's
@@ -1655,17 +1507,12 @@ int smbc_lsetxattr(const char *url,
* sYsTeM.nt_sEc_desc.owNER
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_fsetxattr(int fd,
const char *name,
const void *value,
size_t size,
int flags);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Get extended attributes for a file.
@@ -1723,16 +1570,11 @@ int smbc_fsetxattr(int fd,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_getxattr(const char *url,
const char *name,
const void *value,
size_t size);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Get extended attributes for a file. The POSIX function which this maps to
@@ -1793,16 +1635,11 @@ int smbc_getxattr(const char *url,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_lgetxattr(const char *url,
const char *name,
const void *value,
size_t size);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Get extended attributes for a file.
@@ -1861,16 +1698,11 @@ int smbc_lgetxattr(const char *url,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_fgetxattr(int fd,
const char *name,
const void *value,
size_t size);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Remove extended attributes for a file. This is used for modifying a file's
@@ -1915,14 +1747,9 @@ int smbc_fgetxattr(int fd,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_removexattr(const char *url,
const char *name);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Remove extended attributes for a file. This is used for modifying a file's
@@ -1970,14 +1797,9 @@ int smbc_removexattr(const char *url,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_lremovexattr(const char *url,
const char *name);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* Remove extended attributes for a file. This is used for modifying a file's
@@ -2023,14 +1845,9 @@ int smbc_lremovexattr(const char *url,
* extended attributes
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_fremovexattr(int fd,
const char *name);
-#ifdef __cplusplus
-}
-#endif
+
/**@ingroup attribute
* List the supported extended attribute names associated with a file
@@ -2062,15 +1879,9 @@ int smbc_fremovexattr(int fd,
* extended attributes at all. Whether this is a feature or
* a bug is yet to be decided.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_listxattr(const char *url,
char *list,
size_t size);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup attribute
* List the supported extended attribute names associated with a file The
@@ -2106,15 +1917,9 @@ int smbc_listxattr(const char *url,
* extended attributes at all. Whether this is a feature or
* a bug is yet to be decided.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_llistxattr(const char *url,
char *list,
size_t size);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup attribute
* List the supported extended attribute names associated with a file
@@ -2147,15 +1952,9 @@ int smbc_llistxattr(const char *url,
* extended attributes at all. Whether this is a feature or
* a bug is yet to be decided.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_flistxattr(int fd,
char *list,
size_t size);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup print
* Print a file given the name in fname. It would be a URL ...
@@ -2172,13 +1971,7 @@ int smbc_flistxattr(int fd,
* and errors returned by smbc_open
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_print_file(const char *fname, const char *printq);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup print
* Open a print file that can be written to by other calls. This simply
@@ -2193,13 +1986,7 @@ int smbc_print_file(const char *fname, const char *printq);
* - all errors returned by smbc_open
*
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_open_print_job(const char *fname);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup print
* List the print jobs on a print share, for the moment, pass a callback
@@ -2212,13 +1999,7 @@ int smbc_open_print_job(const char *fname);
* - EINVAL fname was NULL or smbc_init not called
* - EACCES ???
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup print
* Delete a print job
@@ -2232,13 +2013,7 @@ int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn);
*
* @todo what errno values are possible here?
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_unlink_print_job(const char *purl, int id);
-#ifdef __cplusplus
-}
-#endif
/**@ingroup callback
* Remove a server from the cached server list it's unused.
@@ -2250,10 +2025,8 @@ int smbc_unlink_print_job(const char *purl, int id);
* @return On success, 0 is returned. 1 is returned if the server could not
* be removed. Also useable outside libsmbclient.
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/include/msdfs.h b/source/include/msdfs.h
index afbbe738fe1..8d6b23bcbfb 100644
--- a/source/include/msdfs.h
+++ b/source/include/msdfs.h
@@ -68,18 +68,17 @@ struct dfs_path
#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \
{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \
lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \
- dfs_redirect(name,conn,False)) \
+ dfs_redirect(name, conn, False)) \
return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \
ERRSRV, ERRbadpath);; }
-#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf) \
+#define RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf) \
{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \
lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && \
- dfs_redirect(name,conn,True)) \
+ dfs_redirect(name,conn, True)) \
return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, \
ERRSRV, ERRbadpath);; }
-
#define init_dfsroot(conn, inbuf, outbuf) \
{ if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { \
DEBUG(2,("Serving %s as a Dfs root\n", \
diff --git a/source/include/nt_status.h b/source/include/nt_status.h
index 9747f73eb18..ab768258df1 100644
--- a/source/include/nt_status.h
+++ b/source/include/nt_status.h
@@ -56,6 +56,7 @@ typedef uint32 WERROR;
#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_IS_INVALID(x) (NT_STATUS_V(x) == 0xFFFFFFFF)
#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)
#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y))
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 45d64cf6331..87fac492db3 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -391,13 +391,16 @@ typedef struct {
#include "authdata.h"
/* different dce/rpc pipes */
+#include "rpc_buffer.h"
#include "rpc_lsa.h"
#include "rpc_netlogon.h"
#include "rpc_reg.h"
#include "rpc_samr.h"
#include "rpc_srvsvc.h"
#include "rpc_wkssvc.h"
+#include "rpc_svcctl.h"
#include "rpc_spoolss.h"
+#include "rpc_eventlog.h"
#include "rpc_dfs.h"
#include "rpc_ds.h"
#include "rpc_echo.h"
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 6cf5a756d29..417719625e7 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -37,6 +37,9 @@
#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c)
#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c)
+/* Special "invalid" NT status code. */
+#define NT_STATUS_INVALID NT_STATUS(0xFFFFFFFF)
+
/* Win32 Error codes extracted using a loop in smbclient then printing a
netmon sniff to a file. */
diff --git a/source/include/passdb.h b/source/include/passdb.h
index 5a70bb45a8c..624f0c5fea6 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -337,10 +337,20 @@ typedef struct pdb_context
DOM_SID **members, int *num_members);
NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
const DOM_SID *members,
int num_members,
- DOM_SID **aliases,
- int *num_aliases);
+ uint32 **alias_rids,
+ int *num_alias_rids);
+
+ NTSTATUS (*pdb_lookup_rids)(struct pdb_context *context,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs);
void (*free_fn)(struct pdb_context **);
@@ -437,9 +447,19 @@ typedef struct pdb_methods
const DOM_SID *alias, DOM_SID **members,
int *num_members);
NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
const DOM_SID *members,
int num_members,
- DOM_SID **aliases, int *num);
+ uint32 **alias_rids,
+ int *num_alias_rids);
+ NTSTATUS (*lookup_rids)(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs);
void *private_data; /* Private data of some kind */
@@ -460,4 +480,27 @@ struct pdb_init_function_entry {
enum sql_search_field { SQL_SEARCH_NONE = 0, SQL_SEARCH_USER_SID = 1, SQL_SEARCH_USER_NAME = 2};
+struct samr_displayentry {
+ uint32 rid;
+ uint16 acct_flags;
+ const char *account_name;
+ const char *fullname;
+ const char *description;
+};
+
+enum pdb_search_type {
+ PDB_USER_SEARCH,
+ PDB_GROUP_SEARCH,
+ PDB_ALIAS_SEARCH
+};
+
+struct pdb_search {
+ TALLOC_CTX *mem_ctx;
+ enum pdb_search_type type;
+ struct samr_displayentry *cache;
+ uint32 cache_size;
+ BOOL search_ended;
+ void *private;
+};
+
#endif /* _PASSDB_H */
diff --git a/source/include/rpc_buffer.h b/source/include/rpc_buffer.h
new file mode 100644
index 00000000000..da2be8a4df6
--- /dev/null
+++ b/source/include/rpc_buffer.h
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+
+ Copyright (C) Andrew Tridgell 1992-2000,
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ Copyright (C) Jean Francois Micouleau 1998-2000.
+ Copyright (C) Gerald Carter 2001-2005.
+
+ 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 _RPC_BUFFER_H /* _RPC_SPOOLSS_H */
+#define _RPC_BUFFER_H
+
+typedef struct {
+ uint32 size;
+ prs_struct prs;
+ uint32 struct_start;
+ uint32 string_at_end;
+} RPC_BUFFER;
+
+
+#endif /* _RPC_BUFFER_H */
diff --git a/source/include/rpc_client.h b/source/include/rpc_client.h
index bce9ec7f273..4ac2f43ee00 100644
--- a/source/include/rpc_client.h
+++ b/source/include/rpc_client.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
SMB parameters and setup
- Copyright (C) Elrond 2000
+ Copyright (C) Gerald (Jerry) Carter 2005.
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 +21,21 @@
#ifndef _RPC_CLIENT_H
#define _RPC_CLIENT_H
-#if 0 /* JERRY */
-#include "rpc_client_proto.h"
-#endif
+/* macro to expand cookie-cutter code in cli_xxx() */
+
+#define CLI_DO_RPC( pcli, ctx, pipe_num, opnum, q_in, r_out, q_ps, r_ps, q_io_fn, r_io_fn, default_error) \
+{ r_out.status = default_error;\
+ prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
+ prs_init( &r_ps, 0, ctx, UNMARSHALL );\
+ if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
+ if ( rpc_api_pipe_req(pcli, pipe_num, opnum, &q_ps, &r_ps) ) {\
+ if (!r_io_fn("", &r_out, &r_ps, 0)) {\
+ r_out.status = default_error;\
+ }\
+ }\
+ }\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+}
#endif /* _RPC_CLIENT_H */
diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h
new file mode 100644
index 00000000000..b692a762257
--- /dev/null
+++ b/source/include/rpc_eventlog.h
@@ -0,0 +1,193 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * 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 _RPC_EVENTLOG_H /* _RPC_EVENTLOG_H */
+#define _RPC_EVENTLOG_H
+
+/* opcodes */
+
+#define EVENTLOG_CLEAREVENTLOG 0x00
+#define EVENTLOG_CLOSEEVENTLOG 0x02
+#define EVENTLOG_GETNUMRECORDS 0x04
+#define EVENTLOG_GETOLDESTENTRY 0x05
+#define EVENTLOG_OPENEVENTLOG 0x07
+#define EVENTLOG_READEVENTLOG 0x0a
+
+/* Eventlog read flags */
+
+#define EVENTLOG_SEQUENTIAL_READ 0x0001
+#define EVENTLOG_SEEK_READ 0x0002
+#define EVENTLOG_FORWARDS_READ 0x0004
+#define EVENTLOG_BACKWARDS_READ 0x0008
+
+/* Event types */
+
+#define EVENTLOG_SUCCESS 0x0000
+#define EVENTLOG_ERROR_TYPE 0x0001
+#define EVENTLOG_WARNING_TYPE 0x0002
+#define EVENTLOG_INFORMATION_TYPE 0x0004
+#define EVENTLOG_AUDIT_SUCCESS 0x0008
+#define EVENTLOG_AUDIT_FAILURE 0x0010
+
+
+typedef struct eventlog_q_open_eventlog
+{
+ uint32 unknown1;
+ uint16 unknown2;
+ uint16 unknown3;
+ uint16 sourcename_length;
+ uint16 sourcename_size;
+ uint32 sourcename_ptr;
+ UNISTR2 sourcename;
+ uint32 servername_ptr;
+ UNISTR2 servername;
+}
+EVENTLOG_Q_OPEN_EVENTLOG;
+
+typedef struct eventlog_r_open_eventlog
+{
+ POLICY_HND handle;
+ WERROR status;
+}
+EVENTLOG_R_OPEN_EVENTLOG;
+
+typedef struct eventlog_q_close_eventlog
+{
+ POLICY_HND handle;
+}
+EVENTLOG_Q_CLOSE_EVENTLOG;
+
+typedef struct eventlog_r_close_eventlog
+{
+ POLICY_HND handle;
+ WERROR status;
+}
+EVENTLOG_R_CLOSE_EVENTLOG;
+
+typedef struct eventlog_q_get_num_records
+{
+ POLICY_HND handle;
+}
+EVENTLOG_Q_GET_NUM_RECORDS;
+
+typedef struct eventlog_r_get_num_records
+{
+ uint32 num_records;
+ WERROR status;
+}
+EVENTLOG_R_GET_NUM_RECORDS;
+
+typedef struct eventlog_q_get_oldest_entry
+{
+ POLICY_HND handle;
+}
+EVENTLOG_Q_GET_OLDEST_ENTRY;
+
+typedef struct eventlog_r_get_oldest_entry
+{
+ uint32 oldest_entry;
+ WERROR status;
+}
+EVENTLOG_R_GET_OLDEST_ENTRY;
+
+typedef struct eventlog_q_read_eventlog
+{
+ POLICY_HND handle;
+ uint32 flags;
+ uint32 offset;
+ uint32 max_read_size;
+}
+EVENTLOG_Q_READ_EVENTLOG;
+
+typedef struct eventlog_record
+{
+ uint32 length;
+ uint32 reserved1;
+ uint32 record_number;
+ uint32 time_generated;
+ uint32 time_written;
+ uint32 event_id;
+ uint16 event_type;
+ uint16 num_strings;
+ uint16 event_category;
+ uint16 reserved2;
+ uint32 closing_record_number;
+ uint32 string_offset;
+ uint32 user_sid_length;
+ uint32 user_sid_offset;
+ uint32 data_length;
+ uint32 data_offset;
+} Eventlog_record;
+
+typedef struct eventlog_data_record
+{
+ uint32 source_name_len;
+ wpstring source_name;
+ uint32 computer_name_len;
+ wpstring computer_name;
+ uint32 sid_padding;
+ wpstring sid;
+ uint32 strings_len;
+ wpstring strings;
+ uint32 user_data_len;
+ pstring user_data;
+ uint32 data_padding;
+} Eventlog_data_record;
+
+typedef struct eventlog_entry
+{
+ Eventlog_record record;
+ Eventlog_data_record data_record;
+ uint8 *data;
+ uint8 *end_of_data_padding;
+ struct eventlog_entry *next;
+} Eventlog_entry;
+
+typedef struct eventlog_r_read_eventlog
+{
+ uint32 num_bytes_in_resp;
+ uint32 bytes_in_next_record;
+ uint32 num_records;
+ Eventlog_entry *entry;
+ uint8 *end_of_entries_padding;
+ uint32 sent_size;
+ uint32 real_size;
+ WERROR status;
+}
+EVENTLOG_R_READ_EVENTLOG;
+
+typedef struct eventlog_q_clear_eventlog
+{
+ POLICY_HND handle;
+ uint32 unknown1;
+ uint16 backup_file_length;
+ uint16 backup_file_size;
+ uint32 backup_file_ptr;
+ UNISTR2 backup_file;
+}
+EVENTLOG_Q_CLEAR_EVENTLOG;
+
+typedef struct eventlog_r_clear_eventlog
+{
+ WERROR status;
+}
+EVENTLOG_R_CLEAR_EVENTLOG;
+
+#endif /* _RPC_EVENTLOG_H */
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index a0d78280c20..8eaf68a234d 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -1,9 +1,10 @@
/*
Unix SMB/CIFS implementation.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+ Copyright (C) Gerald (Jerry) Carter 2005
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
@@ -68,7 +69,7 @@
#define LSA_LOOKUPPRIVNAME 0x20
#define LSA_PRIV_GET_DISPNAME 0x21
#define LSA_DELETEOBJECT 0x22
-#define LSA_ENUMACCTWITHRIGHT 0x23
+#define LSA_ENUMACCTWITHRIGHT 0x23 /* TODO: implement this one -- jerry */
#define LSA_ENUMACCTRIGHTS 0x24
#define LSA_ADDACCTRIGHTS 0x25
#define LSA_REMOVEACCTRIGHTS 0x26
@@ -305,32 +306,33 @@ typedef struct lsa_r_query_info2
NTSTATUS status;
} LSA_R_QUERY_INFO2;
-/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
-typedef struct lsa_enum_trust_dom_info
-{
- POLICY_HND pol; /* policy handle */
- uint32 enum_context; /* enumeration context handle */
- uint32 preferred_len; /* preferred maximum length */
+/*******************************************************/
+typedef struct {
+ POLICY_HND pol;
+ uint32 enum_context;
+ uint32 preferred_len; /* preferred maximum length */
} LSA_Q_ENUM_TRUST_DOM;
-/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
-typedef struct lsa_r_enum_trust_dom_info
-{
- uint32 enum_context; /* enumeration context handle */
- uint32 num_domains; /* number of domains */
- uint32 ptr_enum_domains; /* buffer pointer to num domains */
-
- /* this lot is only added if ptr_enum_domains is non-NULL */
- uint32 num_domains2; /* number of domains */
- UNIHDR2 *hdr_domain_name;
- UNISTR2 *uni_domain_name;
- DOM_SID2 *domain_sid;
+typedef struct {
+ UNISTR4 name;
+ DOM_SID2 *sid;
+} DOMAIN_INFO;
- NTSTATUS status; /* return code */
+typedef struct {
+ uint32 count;
+ DOMAIN_INFO *domains;
+} DOMAIN_LIST;
+typedef struct {
+ uint32 enum_context;
+ uint32 count;
+ DOMAIN_LIST *domlist;
+ NTSTATUS status;
} LSA_R_ENUM_TRUST_DOM;
+/*******************************************************/
+
/* LSA_Q_CLOSE */
typedef struct lsa_q_close_info
{
@@ -423,7 +425,7 @@ typedef struct lsa_q_lookup_sids
POLICY_HND pol; /* policy handle */
LSA_SID_ENUM sids;
LSA_TRANS_NAME_ENUM names;
- LOOKUP_LEVEL level;
+ uint16 level;
uint32 mapped_count;
} LSA_Q_LOOKUP_SIDS;
@@ -532,7 +534,7 @@ typedef struct
typedef struct
{
uint32 count;
- UNISTR2_ARRAY rights;
+ UNISTR4_ARRAY *rights;
NTSTATUS status;
} LSA_R_ENUM_ACCT_RIGHTS;
@@ -542,8 +544,8 @@ typedef struct
{
POLICY_HND pol; /* policy handle */
DOM_SID2 sid;
- UNISTR2_ARRAY rights;
uint32 count;
+ UNISTR4_ARRAY *rights;
} LSA_Q_ADD_ACCT_RIGHTS;
/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */
@@ -559,8 +561,8 @@ typedef struct
POLICY_HND pol; /* policy handle */
DOM_SID2 sid;
uint32 removeall;
- UNISTR2_ARRAY rights;
uint32 count;
+ UNISTR4_ARRAY *rights;
} LSA_Q_REMOVE_ACCT_RIGHTS;
/* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index 6abc85a4cac..dcc0ecc554a 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -1,9 +1,10 @@
/*
Unix SMB/CIFS implementation.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+ Copyright (C) Gerald (Jerry) Carter 2005
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,15 @@
#define _RPC_MISC_H
#define SMB_RPC_INTERFACE_VERSION 1
+#define PRS_POINTER_CAST BOOL (*)(const char*, prs_struct*, int, void*)
+
+enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
+
+
-/* well-known RIDs - Relative IDs */
+/**********************************************************************
+ * well-known RIDs - Relative IDs
+ **********************************************************************/
/* RIDs - Well-known users ... */
#define DOMAIN_USER_RID_ADMIN (0x000001F4L)
@@ -65,186 +73,208 @@
#define BUILTIN_ALIAS_RID_RAS_SERVERS (0x00000229L)
#define BUILTIN_ALIAS_RID_PRE_2K_ACCESS (0x0000022aL)
-/*
+
+/**********************************************************************
* Masks for mappings between unix uid and gid types and
* NT RIDS.
- */
-
+ **********************************************************************/
#define BASE_RID (0x000003E8L)
/* Take the bottom bit. */
-#define RID_TYPE_MASK 1
-#define RID_MULTIPLIER 2
+#define RID_TYPE_MASK 1
+#define RID_MULTIPLIER 2
/* The two common types. */
-#define USER_RID_TYPE 0
-#define GROUP_RID_TYPE 1
+#define USER_RID_TYPE 0
+#define GROUP_RID_TYPE 1
-/* ENUM_HND */
-typedef struct enum_hnd_info
-{
+
+
+/**********************************************************************
+ * RPC policy handle used pretty much everywhere
+ **********************************************************************/
+
+typedef struct {
uint32 ptr_hnd; /* pointer to enumeration handle */
uint32 handle; /* enumeration handle */
} ENUM_HND;
-/* LOOKUP_LEVEL - switch value */
-typedef struct lookup_level_info
-{
- uint16 value;
-} LOOKUP_LEVEL;
-/* DOM_SID2 - security id */
-typedef struct sid_info_2
-{
- uint32 num_auths; /* length, bytes, including length of len :-) */
- DOM_SID sid;
-} DOM_SID2;
-/* STRHDR - string header */
-typedef struct header_info
-{
- uint16 str_str_len;
- uint16 str_max_len;
- uint32 buffer; /* non-zero */
-} STRHDR;
+/**********************************************************************
+ * RPC policy handle used pretty much everywhere
+ **********************************************************************/
-/* UNIHDR - unicode string header */
-typedef struct unihdr_info
-{
- uint16 uni_str_len;
- uint16 uni_max_len;
- uint32 buffer; /* usually has a value of 4 */
-} UNIHDR;
+typedef struct {
+ uint32 data1;
+ uint32 data2;
+ uint16 data3;
+ uint16 data4;
+ uint8 data5[8];
+#ifdef __INSURE__
-/* UNIHDR2 - unicode string header and undocumented buffer */
-typedef struct unihdr2_info
-{
- UNIHDR unihdr;
- uint32 buffer; /* 32 bit buffer pointer */
-} UNIHDR2;
+ /* To prevent the leakage of policy handles mallocate a bit of
+ memory when a policy handle is created and free it when the
+ handle is closed. This should cause Insure to flag an error
+ when policy handles are overwritten or fall out of scope without
+ being freed. */
-/* UNISTR - unicode string size and buffer */
-typedef struct unistr_info
-{
- /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
- uint16 *buffer;
-} UNISTR;
+ char *marker;
+#endif
+} POLICY_HND;
-/* BUFHDR - buffer header */
-typedef struct bufhdr_info
-{
+
+/**********************************************************************
+ * Buffer Headers -- use by SEC_DESC_BUF in winreg and netlogon code
+ **********************************************************************/
+
+typedef struct {
uint32 buf_max_len;
uint32 buf_len;
} BUFHDR;
-/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
-/* pathetic. some stupid team of \PIPE\winreg writers got the concept */
-/* of a unicode string different from the other \PIPE\ writers */
-typedef struct buffer2_info
-{
+typedef struct {
+ uint32 info_level;
+ uint32 length; /* uint8 chars */
+ uint32 buffer;
+} BUFHDR2;
+
+typedef struct {
+ uint32 size;
+ uint32 buffer;
+} BUFHDR4;
+
+
+/**********************************************************************
+ * Buffers
+ **********************************************************************/
+
+/* buffer used by \winreg\ calls to fill in arbitrary REG_XXX values.
+ It *may* look like a UNISTR2 but it is *not*. This is not a goof
+ by the winreg developers. It is a generic buffer */
+
+typedef struct {
uint32 buf_max_len;
uint32 offset;
uint32 buf_len;
- /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
uint16 *buffer;
-} BUFFER2;
+} REGVAL_BUFFER;
-/* BUFFER3 */
-typedef struct buffer3_info
-{
- uint32 buf_max_len;
- uint8 *buffer; /* Data */
+/* generic rpc version of the DATA_BLOB. Just a length and uint8 array */
+
+typedef struct {
uint32 buf_len;
-} BUFFER3;
+ uint8 *buffer;
+} RPC_DATA_BLOB;
-/* BUFFER5 */
-typedef struct buffer5_info
-{
+/**********************************************************************
+ * Buffers use by spoolss (i might be able to replace it with
+ * an RPC_DATA_BLOB)
+ **********************************************************************/
+
+typedef struct {
uint32 buf_len;
uint16 *buffer; /* data */
} BUFFER5;
-/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
-typedef struct unistr2_info
-{
+
+/**********************************************************************
+ * Unicode and basic string headers
+ **********************************************************************/
+
+typedef struct {
+ uint16 str_str_len;
+ uint16 str_max_len;
+ uint32 buffer; /* non-zero */
+} STRHDR;
+
+typedef struct {
+ uint16 uni_str_len;
+ uint16 uni_max_len;
+ uint32 buffer;
+} UNIHDR;
+
+/**********************************************************************
+ * UNICODE string variations
+ **********************************************************************/
+
+
+typedef struct { /* UNISTR - unicode string size and buffer */
+ uint16 *buffer; /* unicode characters. ***MUST*** be
+ little-endian. ***MUST*** be null-terminated */
+} UNISTR;
+
+typedef struct { /* UNISTR2 - unicode string size (in
+ uint16 unicode chars) and buffer */
uint32 uni_max_len;
uint32 offset;
uint32 uni_str_len;
- /* unicode characters. ***MUST*** be little-endian.
- **must** be null-terminated and the uni_str_len should include
- the NULL character */
- uint16 *buffer;
+ uint16 *buffer; /* unicode characters. ***MUST*** be little-endian.
+ **must** be null-terminated and the uni_str_len
+ should include the NULL character */
} UNISTR2;
-/* STRING2 - string size (in uint8 chars) and buffer */
-typedef struct string2_info
-{
+typedef struct { /* UNISTR3 - XXXX not sure about this structure */
+ uint32 uni_str_len;
+ UNISTR str;
+
+} UNISTR3;
+
+typedef struct { /* Buffer wrapped around a UNISTR2 */
+ uint16 length; /* number of bytes not counting NULL terminatation */
+ uint16 size; /* number of bytes including NULL terminatation */
+ UNISTR2 *string;
+} UNISTR4;
+
+typedef struct {
+ uint32 count;
+ UNISTR4 *strings;
+} UNISTR4_ARRAY;
+
+
+/**********************************************************************
+ * String variations
+ **********************************************************************/
+
+typedef struct { /* STRING2 - string size (in uint8 chars) and buffer */
uint32 str_max_len;
uint32 offset;
uint32 str_str_len;
- uint8 *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
+ uint8 *buffer; /* uint8 characters. **NOT** necessarily null-terminated */
} STRING2;
-/* UNISTR3 - XXXX not sure about this structure */
-typedef struct unistr3_info
-{
- uint32 uni_str_len;
- UNISTR str;
-} UNISTR3;
-/* an element in a unicode string array */
-typedef struct
-{
- uint16 length;
- uint16 size;
- uint32 ref_id;
- UNISTR2 string;
-} UNISTR2_ARRAY_EL;
-
-/* an array of unicode strings */
-typedef struct
-{
- uint32 ref_id;
- uint32 count;
- UNISTR2_ARRAY_EL *strings;
-} UNISTR2_ARRAY;
+/**********************************************************************
+ * Domain SID structures
+ **********************************************************************/
-/* an element in a sid array */
-typedef struct
-{
- uint32 ref_id;
- DOM_SID2 sid;
-} SID_ARRAY_EL;
+typedef struct {
+ uint32 num_auths; /* length, bytes, including length of len :-) */
+ DOM_SID sid;
+} DOM_SID2;
-/* an array of sids */
-typedef struct
-{
- uint32 ref_id;
- uint32 count;
- SID_ARRAY_EL *sids;
-} SID_ARRAY;
+
+/**********************************************************************
+ * Domain SID structures
+ **********************************************************************/
/* DOM_RID2 - domain RID structure for ntlsa pipe */
-typedef struct domrid2_info
-{
+typedef struct {
uint8 type; /* value is SID_NAME_USE enum */
uint32 rid;
uint32 rid_idx; /* referenced domain index */
-
} DOM_RID2;
-/* DOM_RID3 - domain RID structure for samr pipe */
-typedef struct domrid3_info
-{
+
+typedef struct { /* DOM_RID3 - domain RID structure for samr pipe */
uint32 rid; /* domain-relative (to a SID) id */
uint32 type1; /* value is 0x1 */
uint32 ptr_type; /* undocumented pointer */
uint32 type2; /* value is 0x1 */
uint32 unk; /* value is 0x2 */
-
} DOM_RID3;
/* DOM_RID4 - rid + user attributes */
@@ -255,6 +285,16 @@ typedef struct domrid4_info
uint32 rid; /* user RID */
} DOM_RID4;
+/* DOM_GID - group id + user attributes */
+typedef struct {
+ uint32 g_rid; /* a group RID */
+ uint32 attr;
+} DOM_GID;
+
+/**********************************************************************
+ * ????
+ **********************************************************************/
+
/* DOM_CLNT_SRV - client / server names */
typedef struct clnt_srv_info
{
@@ -316,32 +356,8 @@ typedef struct owf_info
} OWF_INFO;
-/* DOM_GID - group id + user attributes */
-typedef struct gid_info
-{
- uint32 g_rid; /* a group RID */
- uint32 attr;
-} DOM_GID;
-/* POLICY_HND */
-typedef struct lsa_policy_info
-{
- uint32 data1;
- uint32 data2;
- uint16 data3;
- uint16 data4;
- uint8 data5[8];
-#ifdef __INSURE__
-
- /* To prevent the leakage of policy handles mallocate a bit of
- memory when a policy handle is created and free it when the
- handle is closed. This should cause Insure to flag an error
- when policy handles are overwritten or fall out of scope without
- being freed. */
- char *marker;
-#endif
-} POLICY_HND;
/*
* A client connection's state, pipe name,
@@ -380,33 +396,8 @@ 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;
-/* BUFHDR4 - another buffer header */
-typedef struct bufhdr4_info
-{
- uint32 size;
- uint32 buffer;
-}
-BUFHDR4;
-/* BUFFER4 - simple length and buffer */
-typedef struct buffer4_info
-{
- uint32 buf_len;
- uint8 *buffer;
-
-}
-BUFFER4;
-
-enum unistr2_term_codes { UNI_FLAGS_NONE = 0, UNI_STR_TERMINATE = 1, UNI_MAXLEN_TERMINATE = 2, UNI_BROKEN_NON_NULL = 3 };
#endif /* _RPC_MISC_H */
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index 3ba1ce6465b..6812358575a 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -643,7 +643,7 @@ typedef struct sam_domain_info_info
UNISTR2 uni_dom_name;
UNISTR2 buf_oem_info;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
LOCKOUT_STRING account_lockout;
@@ -670,7 +670,7 @@ typedef struct sam_group_info_info
UNISTR2 uni_grp_name;
UNISTR2 uni_grp_desc;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
} SAM_GROUP_INFO;
@@ -748,11 +748,11 @@ typedef struct sam_account_info_info
uint32 unknown1; /* 0x4EC */
uint32 unknown2; /* 0 */
- BUFFER4 buf_logon_hrs;
+ RPC_DATA_BLOB buf_logon_hrs;
UNISTR2 uni_comment;
UNISTR2 uni_parameters;
SAM_PWD pass;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
UNISTR2 uni_profile;
} SAM_ACCOUNT_INFO;
@@ -783,7 +783,7 @@ typedef struct sam_alias_info_info
uint8 reserved[40];
UNISTR2 uni_als_name;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
UNISTR2 uni_als_desc;
} SAM_ALIAS_INFO;
@@ -829,7 +829,7 @@ typedef struct
UNISTR2 domain_name;
DOM_SID2 domain_sid;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
} SAM_DELTA_POLICY;
/* SAM_DELTA_TRUST_DOMS */
@@ -881,7 +881,7 @@ typedef struct
UNIHDR *hdr_privslist;
UNISTR2 *uni_privslist;
- BUFFER4 buf_sec_desc;
+ RPC_DATA_BLOB buf_sec_desc;
} SAM_DELTA_PRIVS;
/* SAM_DELTA_SECRET */
diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h
index bfb5f1e0763..f70fb5f03cf 100644
--- a/source/include/rpc_reg.h
+++ b/source/include/rpc_reg.h
@@ -4,7 +4,8 @@
Copyright (C) Andrew Tridgell 1992-1997.
Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
Copyright (C) Paul Ashton 1997.
- Copyright (C) Gerald Carter 2002.
+ Copyright (C) Jeremy Cooper 2004.
+ Copyright (C) Gerald Carter 2002-2005.
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,50 +25,44 @@
#ifndef _RPC_REG_H /* _RPC_REG_H */
#define _RPC_REG_H
+/* RPC opnum */
-/* winreg pipe defines
- NOT IMPLEMENTED !!
-#define _REG_UNK_01 0x01
-#define _REG_UNK_03 0x03
-#define REG_CREATE_KEY 0x06
-#define REG_DELETE_KEY 0x07
-#define REG_DELETE_VALUE 0x08
-#define REG_FLUSH_KEY 0x0b
-#define REG_GET_KEY_SEC 0x0c
-#define _REG_UNK_0D 0x0d
-#define _REG_UNK_0E 0x0e
-#define _REG_UNK_12 0x12
-#define _REG_UNK_13 0x13
-#define REG_SET_KEY_SEC 0x15
-#define REG_CREATE_VALUE 0x16
-#define _REG_UNK_17 0x17
-*/
-
-/* Implemented */
#define REG_OPEN_HKCR 0x00
#define REG_OPEN_HKLM 0x02
+#define REG_OPEN_HKPD 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_OPEN_ENTRY 0x0f
#define REG_QUERY_KEY 0x10
#define REG_INFO 0x11
+#define REG_RESTORE_KEY 0x13
+#define REG_SAVE_KEY 0x14
+#define REG_SET_KEY_SEC 0x15
+#define REG_SET_VALUE 0x16
#define REG_SHUTDOWN 0x18
#define REG_ABORT_SHUTDOWN 0x19
-#define REG_SAVE_KEY 0x14 /* no idea what the real name is */
-#define REG_UNKNOWN_1A 0x1a
+#define REG_GETVERSION 0x1a
+#define REG_SHUTDOWN_EX 0x1e
#define HKEY_CLASSES_ROOT 0x80000000
#define HKEY_CURRENT_USER 0x80000001
#define HKEY_LOCAL_MACHINE 0x80000002
#define HKEY_USERS 0x80000003
+#define HKEY_PERFORMANCE_DATA 0x80000004
#define KEY_HKLM "HKLM"
#define KEY_HKU "HKU"
#define KEY_HKCR "HKCR"
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
+#define KEY_EVENTLOG "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Eventlog"
#define KEY_TREE_ROOT ""
/* Registry data types */
@@ -85,6 +80,10 @@
#define REG_FULL_RESOURCE_DESCRIPTOR 9
#define REG_RESOURCE_REQUIREMENTS_LIST 10
+/*
+ * INTERNAL REGISTRY STRUCTURES
+ */
+
/* structure to contain registry values */
typedef struct {
@@ -94,7 +93,7 @@ typedef struct {
uint8 *data_p;
} REGISTRY_VALUE;
-/* container for regostry values */
+/* container for registry values */
typedef struct {
TALLOC_CTX *ctx;
@@ -143,379 +142,253 @@ typedef struct _RegistryKey {
} REGISTRY_KEY;
+/*
+ * RPC REGISTRY STRUCTURES
+ */
-/* REG_Q_OPEN_HKCR */
-typedef struct q_reg_open_hkcr_info
-{
- uint32 ptr;
- uint16 unknown_0; /* 0x5428 - 16 bit unknown */
- uint16 unknown_1; /* random. changes */
- uint32 level; /* 0x0000 0002 - 32 bit unknown */
-
-} REG_Q_OPEN_HKCR ;
-
-/* REG_R_OPEN_HKCR */
-typedef struct r_reg_open_hkcr_info
-{
- POLICY_HND pol; /* policy handle */
- WERROR status; /* return status */
-
-} 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;
+/***********************************************/
-}
-REG_Q_OPEN_HKLM;
-
-/* REG_R_OPEN_HKLM */
-typedef struct r_reg_open_hklm_info
-{
- POLICY_HND pol; /* policy handle */
- WERROR status; /* return status */
-
-}
-REG_R_OPEN_HKLM;
-
-
-/* REG_Q_OPEN_HKU */
-typedef struct q_reg_open_hku_info
-{
- uint32 ptr;
- uint16 unknown_0;
- uint16 unknown_1;
- uint32 access_mask;
-
-} REG_Q_OPEN_HKU;
-
-/* REG_R_OPEN_HKU */
-typedef struct r_reg_open_hku_info
-{
- POLICY_HND pol; /* policy handle */
- WERROR status; /* return status */
+typedef struct {
+ uint16 *server;
+ uint32 access;
+} REG_Q_OPEN_HIVE;
-} REG_R_OPEN_HKU;
+typedef struct {
+ POLICY_HND pol;
+ WERROR status;
+} REG_R_OPEN_HIVE;
-/* REG_Q_FLUSH_KEY */
-typedef struct q_reg_open_flush_key_info
-{
- POLICY_HND pol; /* policy handle */
+/***********************************************/
+typedef struct {
+ POLICY_HND pol;
} REG_Q_FLUSH_KEY;
-/* REG_R_FLUSH_KEY */
-typedef struct r_reg_open_flush_key_info
-{
- WERROR status; /* return status */
-
+typedef struct {
+ WERROR status;
} REG_R_FLUSH_KEY;
-/* REG_Q_SET_KEY_SEC */
-typedef struct q_reg_set_key_sec_info
-{
- POLICY_HND pol; /* policy handle */
-
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
+/***********************************************/
- uint32 ptr; /* pointer */
- BUFHDR hdr_sec; /* header for security data */
- SEC_DESC_BUF *data; /* security data */
-
+typedef struct {
+ POLICY_HND pol;
+ uint32 sec_info;
+ uint32 ptr;
+ BUFHDR hdr_sec;
+ SEC_DESC_BUF *data;
} REG_Q_SET_KEY_SEC;
-/* REG_R_SET_KEY_SEC */
-typedef struct r_reg_set_key_sec_info
-{
+typedef struct {
WERROR status;
-
} REG_R_SET_KEY_SEC;
-/* REG_Q_GET_KEY_SEC */
-typedef struct q_reg_get_key_sec_info
-{
- POLICY_HND pol; /* policy handle */
-
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
+/***********************************************/
- uint32 ptr; /* pointer */
- BUFHDR hdr_sec; /* header for security data */
- SEC_DESC_BUF *data; /* security data */
-
+typedef struct {
+ POLICY_HND pol;
+ uint32 sec_info;
+ uint32 ptr;
+ BUFHDR hdr_sec;
+ SEC_DESC_BUF *data;
} REG_Q_GET_KEY_SEC;
-/* REG_R_GET_KEY_SEC */
-typedef struct r_reg_get_key_sec_info
-{
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
-
- uint32 ptr; /* pointer */
- BUFHDR hdr_sec; /* header for security data */
- SEC_DESC_BUF *data; /* security data */
-
+typedef struct {
+ uint32 sec_info;
+ uint32 ptr;
+ BUFHDR hdr_sec;
+ SEC_DESC_BUF *data;
WERROR status;
-
} REG_R_GET_KEY_SEC;
-/* REG_Q_CREATE_VALUE */
-typedef struct q_reg_create_value_info
-{
- POLICY_HND pol; /* policy handle */
-
- UNIHDR hdr_name; /* name of value */
- UNISTR2 uni_name;
-
- uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
- BUFFER3 *buf_value; /* value, in byte buffer */
-
-} REG_Q_CREATE_VALUE;
+/***********************************************/
-/* REG_R_CREATE_VALUE */
-typedef struct r_reg_create_value_info
-{
- WERROR status; /* return status */
-
-} REG_R_CREATE_VALUE;
-
-/* REG_Q_ENUM_VALUE */
-typedef struct q_reg_query_value_info
-{
- POLICY_HND pol; /* policy handle */
-
- uint32 val_index; /* index */
-
- UNIHDR hdr_name; /* name of value */
- UNISTR2 uni_name;
-
- uint32 ptr_type; /* pointer */
- uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
- uint32 ptr_value; /* pointer */
- BUFFER2 buf_value; /* value, in byte buffer */
-
- uint32 ptr1; /* pointer */
- uint32 len_value1; /* */
-
- uint32 ptr2; /* pointer */
- uint32 len_value2; /* */
+typedef struct {
+ POLICY_HND pol;
+ UNISTR4 name;
+ uint32 type;
+ RPC_DATA_BLOB value;
+ uint32 size;
+} REG_Q_SET_VALUE;
+
+typedef struct {
+ WERROR status;
+} REG_R_SET_VALUE;
+/***********************************************/
+typedef struct {
+ POLICY_HND pol;
+ uint32 val_index;
+ UNISTR4 name;
+ uint32 *type;
+ REGVAL_BUFFER *value; /* value, in byte buffer */
+ uint32 *len_value1;
+ uint32 *len_value2;
} REG_Q_ENUM_VALUE;
-/* REG_R_ENUM_VALUE */
-typedef struct r_reg_enum_value_info
-{
- UNIHDR hdr_name; /* name of value */
- UNISTR2 uni_name;
-
- uint32 ptr_type; /* pointer */
- uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
-
- uint32 ptr_value; /* pointer */
- BUFFER2 buf_value; /* value, in byte buffer */
-
- uint32 ptr1; /* pointer */
- uint32 len_value1; /* */
-
- uint32 ptr2; /* pointer */
- uint32 len_value2; /* */
-
- WERROR status; /* return status */
-
+typedef struct {
+ UNISTR4 name;
+ uint32 *type;
+ REGVAL_BUFFER *value;
+ uint32 *len_value1;
+ uint32 *len_value2;
+ WERROR status;
} REG_R_ENUM_VALUE;
-/* REG_Q_CREATE_KEY */
-typedef struct q_reg_create_key_info
-{
- POLICY_HND pnt_pol; /* parent key policy handle */
+/***********************************************/
- UNIHDR hdr_name;
- UNISTR2 uni_name;
-
- UNIHDR hdr_class;
- UNISTR2 uni_class;
-
- uint32 reserved; /* 0x0000 0000 */
- SEC_ACCESS sam_access; /* access rights flags, see rpc_secdes.h */
-
- uint32 ptr1;
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
-
- uint32 ptr2; /* pointer */
- BUFHDR hdr_sec; /* header for security data */
- uint32 ptr3; /* pointer */
+typedef struct {
+ POLICY_HND pnt_pol;
+ UNISTR4 name;
+ UNISTR4 class;
+ uint32 reserved;
+ uint32 access;
+ uint32 *sec_info;
+ uint32 ptr2;
+ BUFHDR hdr_sec;
+ uint32 ptr3;
SEC_DESC_BUF *data;
-
uint32 unknown_2; /* 0x0000 0000 */
-
} REG_Q_CREATE_KEY;
-/* REG_R_CREATE_KEY */
-typedef struct r_reg_create_key_info
-{
- POLICY_HND key_pol; /* policy handle */
- uint32 unknown; /* 0x0000 0000 */
-
- WERROR status; /* return status */
-
+typedef struct {
+ POLICY_HND key_pol;
+ uint32 unknown;
+ WERROR status;
} REG_R_CREATE_KEY;
-/* REG_Q_DELETE_KEY */
-typedef struct q_reg_delete_key_info
-{
- POLICY_HND pnt_pol; /* parent key policy handle */
+/***********************************************/
- UNIHDR hdr_name;
- UNISTR2 uni_name;
+typedef struct {
+ POLICY_HND pnt_pol;
+ UNISTR4 name;
} REG_Q_DELETE_KEY;
-/* REG_R_DELETE_KEY */
-typedef struct r_reg_delete_key_info
-{
- POLICY_HND key_pol; /* policy handle */
-
- WERROR status; /* return status */
-
+typedef struct {
+ POLICY_HND key_pol;
+ WERROR status;
} REG_R_DELETE_KEY;
-/* REG_Q_DELETE_VALUE */
-typedef struct q_reg_delete_val_info
-{
- POLICY_HND pnt_pol; /* parent key policy handle */
-
- UNIHDR hdr_name;
- UNISTR2 uni_name;
+/***********************************************/
+typedef struct {
+ POLICY_HND pnt_pol;
+ UNISTR4 name;
} REG_Q_DELETE_VALUE;
-/* REG_R_DELETE_VALUE */
-typedef struct r_reg_delete_val_info
-{
- POLICY_HND key_pol; /* policy handle */
-
- WERROR status; /* return status */
-
+typedef struct {
+ POLICY_HND key_pol;
+ WERROR status;
} REG_R_DELETE_VALUE;
-/* REG_Q_QUERY_KEY */
-typedef struct q_reg_query_info
-{
- POLICY_HND pol; /* policy handle */
- UNIHDR hdr_class;
- UNISTR2 uni_class;
+/***********************************************/
+typedef struct {
+ POLICY_HND pol;
+ UNISTR4 class;
} REG_Q_QUERY_KEY;
-/* REG_R_QUERY_KEY */
-typedef struct r_reg_query_key_info
-{
- UNIHDR hdr_class;
- UNISTR2 uni_class;
-
+typedef struct {
+ UNISTR4 class;
uint32 num_subkeys;
uint32 max_subkeylen;
- uint32 reserved; /* 0x0000 0000 - according to MSDN (max_subkeysize?) */
+ uint32 reserved; /* 0x0000 0000 - according to MSDN (max_subkeysize?) */
uint32 num_values;
uint32 max_valnamelen;
uint32 max_valbufsize;
- uint32 sec_desc; /* 0x0000 0078 */
- NTTIME mod_time; /* modified time */
-
- WERROR status; /* return status */
-
+ uint32 sec_desc; /* 0x0000 0078 */
+ NTTIME mod_time; /* modified time */
+ WERROR status;
} REG_R_QUERY_KEY;
-/* REG_Q_UNKNOWN_1A */
-typedef struct q_reg_unk_1a_info
-{
- POLICY_HND pol; /* policy handle */
+/***********************************************/
-} REG_Q_UNKNOWN_1A;
+typedef struct {
+ POLICY_HND pol; /* policy handle */
+} REG_Q_GETVERSION;
-/* REG_R_UNKNOWN_1A */
-typedef struct r_reg_unk_1a_info
-{
+typedef struct {
uint32 unknown; /* 0x0500 0000 */
WERROR status; /* return status */
+} REG_R_GETVERSION;
-} REG_R_UNKNOWN_1A;
+/***********************************************/
-/* REG_Q_UNKNOWN_1A */
-typedef struct q_reg_unknown_14
-{
- POLICY_HND pol; /* policy handle */
-
- UNIHDR hdr_file; /* unicode product type header */
- UNISTR2 uni_file; /* local filename to save key as from regedt32.exe */
- /* e.g. "c:\temp\test.dat" */
-
- uint32 unknown; /* 0x0000 0000 */
+typedef struct {
+ POLICY_HND pol;
+ UNISTR4 filename;
+ uint32 flags;
+} REG_Q_RESTORE_KEY;
-} REG_Q_SAVE_KEY;
+typedef struct {
+ WERROR status; /* return status */
+} REG_R_RESTORE_KEY;
-/* REG_R_UNKNOWN_1A */
-typedef struct r_reg_unknown_14
-{
- WERROR status; /* return status */
+/***********************************************/
-} REG_R_SAVE_KEY;
+/* I have no idea if this is correct since I
+ have not seen the full structure on the wire
+ as of yet */
+
+typedef struct {
+ uint32 max_len;
+ uint32 len;
+ SEC_DESC *secdesc;
+} REG_SEC_DESC_BUF;
+typedef struct {
+ uint32 size; /* size in bytes of security descriptor */
+ REG_SEC_DESC_BUF secdesc;
+ uint8 inherit; /* see MSDN for a description */
+} SECURITY_ATTRIBUTE;
-/* REG_Q_CLOSE */
-typedef struct reg_q_close_info
-{
- POLICY_HND pol; /* policy handle */
+typedef struct {
+ POLICY_HND pol;
+ UNISTR4 filename;
+ SECURITY_ATTRIBUTE *sec_attr;
+} REG_Q_SAVE_KEY;
-} REG_Q_CLOSE;
+typedef struct {
+ WERROR status; /* return status */
+} REG_R_SAVE_KEY;
-/* REG_R_CLOSE */
-typedef struct reg_r_close_info
-{
- POLICY_HND pol; /* policy handle. should be all zeros. */
- WERROR status; /* return code */
+/***********************************************/
+typedef struct {
+ POLICY_HND pol; /* policy handle */
+} REG_Q_CLOSE;
+
+typedef struct {
+ POLICY_HND pol;
+ WERROR status;
} REG_R_CLOSE;
-/* REG_Q_ENUM_KEY */
-typedef struct q_reg_enum_value_info
-{
- POLICY_HND pol; /* policy handle */
+/***********************************************/
+typedef struct {
+ POLICY_HND pol;
uint32 key_index;
-
uint16 key_name_len; /* 0x0000 */
uint16 unknown_1; /* 0x0414 */
-
uint32 ptr1; /* pointer */
uint32 unknown_2; /* 0x0000 020A */
uint8 pad1[8]; /* padding - zeros */
-
uint32 ptr2; /* pointer */
uint8 pad2[8]; /* padding - zeros */
-
uint32 ptr3; /* pointer */
NTTIME time; /* current time? */
-
} REG_Q_ENUM_KEY;
-/* REG_R_ENUM_KEY */
-typedef struct r_reg_enum_key_info
-{
+typedef struct {
uint16 key_name_len; /* number of bytes in key name */
uint16 unknown_1; /* 0x0414 - matches with query unknown_1 */
@@ -532,17 +405,14 @@ typedef struct r_reg_enum_key_info
NTTIME time; /* current time? */
WERROR status; /* return status */
-
} REG_R_ENUM_KEY;
-/* REG_Q_INFO */
-typedef struct q_reg_info_info
-{
- POLICY_HND pol; /* policy handle */
+/***********************************************/
- UNIHDR hdr_type; /* unicode product type header */
- UNISTR2 uni_type; /* unicode product type - "ProductType" */
+typedef struct {
+ POLICY_HND pol; /* policy handle */
+ UNISTR4 name;
uint32 ptr_reserved; /* pointer */
@@ -560,83 +430,66 @@ typedef struct q_reg_info_info
} REG_Q_INFO;
-/* REG_R_INFO */
-typedef struct r_reg_info_info
-{
- uint32 ptr_type; /* key type pointer */
- uint32 type; /* key datatype */
-
- uint32 ptr_uni_val; /* key value pointer */
- BUFFER2 uni_val; /* key value */
-
- uint32 ptr_max_len;
- uint32 buf_max_len;
-
- uint32 ptr_len;
- uint32 buf_len;
-
+typedef struct {
+ uint32 *type;
+ REGVAL_BUFFER *value; /* key value */
+ uint32 *buf_max_len;
+ uint32 *buf_len;
WERROR status; /* return status */
-
} REG_R_INFO;
-/* REG_Q_OPEN_ENTRY */
-typedef struct q_reg_open_entry_info
-{
- POLICY_HND pol; /* policy handle */
-
- UNIHDR hdr_name; /* unicode registry string header */
- UNISTR2 uni_name; /* unicode registry string name */
+/***********************************************/
+typedef struct {
+ POLICY_HND pol;
+ UNISTR4 name;
uint32 unknown_0; /* 32 bit unknown - 0x0000 0000 */
- uint32 access_desired;
-
+ uint32 access;
} REG_Q_OPEN_ENTRY;
-
-
-/* REG_R_OPEN_ENTRY */
-typedef struct r_reg_open_entry_info
-{
- POLICY_HND pol; /* policy handle */
- WERROR status; /* return status */
-
+typedef struct {
+ POLICY_HND pol;
+ WERROR 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 */
+/***********************************************/
+
+typedef struct {
+ uint16 *server;
+ UNISTR4 *message;
+ uint32 timeout; /* in seconds */
uint8 force; /* boolean: force shutdown */
- uint8 reboot; /* boolean: reboot on shutdown */
-
+ uint8 reboot; /* boolean: reboot on shutdown */
} REG_Q_SHUTDOWN;
-/* REG_R_SHUTDOWN */
-typedef struct r_reg_shutdown_info
-{
+typedef struct {
WERROR status; /* return status */
-
} REG_R_SHUTDOWN;
-/* REG_Q_ABORT_SHUTDOWN */
-typedef struct q_reg_abort_shutdown_info
-{
- uint32 ptr_server;
- uint16 server;
+/***********************************************/
+
+typedef struct {
+ uint16 *server;
+ UNISTR4 *message;
+ uint32 timeout; /* in seconds */
+ uint8 force; /* boolean: force shutdown */
+ uint8 reboot; /* boolean: reboot on shutdown */
+ uint32 reason; /* reason - must be defined code */
+} REG_Q_SHUTDOWN_EX;
-} REG_Q_ABORT_SHUTDOWN;
+typedef struct {
+ WERROR status;
+} REG_R_SHUTDOWN_EX;
+
+/***********************************************/
-/* REG_R_ABORT_SHUTDOWN */
-typedef struct r_reg_abort_shutdown_info
-{
- WERROR status; /* return status */
+typedef struct {
+ uint16 *server;
+} REG_Q_ABORT_SHUTDOWN;
+typedef struct {
+ WERROR status;
} REG_R_ABORT_SHUTDOWN;
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index 3e4c47dce9a..ea987f9e4e0 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -472,4 +472,51 @@ typedef struct standard_mapping {
(STANDARD_RIGHTS_EXECUTE_ACCESS | \
SA_RIGHT_ALIAS_LOOKUP_INFO ) /* 0x00020008 */
+/*
+ * Acces bits for the svcctl objects
+ */
+
+/* Service Control Manager Bits */
+
+#define SC_RIGHT_MGR_CONNECT 0x0001
+#define SC_RIGHT_MGR_CREATE_SERVICE 0x0002
+#define SC_RIGHT_MGR_ENUMERATE_SERVICE 0x0004
+#define SC_RIGHT_MGR_LOCK 0x0008
+#define SC_RIGHT_MGR_QUERY_LOCK_STATUS 0x0010
+#define SC_RIGHT_MGR_MODIFY_BOOT_CONFIG 0x0020
+
+#define SC_MANAGER_ALL_ACCESS \
+ ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+ SC_RIGHT_MGR_CONNECT | \
+ SC_RIGHT_MGR_CREATE_SERVICE | \
+ SC_RIGHT_MGR_ENUMERATE_SERVICE | \
+ SC_RIGHT_MGR_LOCK | \
+ SC_RIGHT_MGR_QUERY_LOCK_STATUS | \
+ SC_RIGHT_MGR_MODIFY_BOOT_CONFIG )
+
+/* Service Object Bits */
+
+#define SC_RIGHT_SVC_QUERY_CONFIG 0x0001
+#define SC_RIGHT_SVC_CHANGE_CONFIG 0x0002
+#define SC_RIGHT_SVC_QUERY_STATUS 0x0004
+#define SC_RIGHT_SVC_ENUMERATE_DEPENDENTS 0x0008
+#define SC_RIGHT_SVC_START 0x0010
+#define SC_RIGHT_SVC_STOP 0x0020
+#define SC_RIGHT_SVC_PAUSE_CONTINUE 0x0040
+#define SC_RIGHT_SVC_INTERROGATE 0x0080
+#define SC_RIGHT_SVC_USER_DEFINED_CONTROL 0x0100
+
+#define SERVICE_ALL_ACCESS \
+ ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+ SC_RIGHT_SVC_QUERY_CONFIG | \
+ SC_RIGHT_SVC_CHANGE_CONFIG | \
+ SC_RIGHT_SVC_QUERY_STATUS | \
+ SC_RIGHT_SVC_ENUMERATE_DEPENDENTS | \
+ SC_RIGHT_SVC_START | \
+ SC_RIGHT_SVC_STOP | \
+ SC_RIGHT_SVC_PAUSE_CONTINUE | \
+ SC_RIGHT_SVC_INTERROGATE | \
+ SC_RIGHT_SVC_USER_DEFINED_CONTROL )
+
+
#endif /* _RPC_SECDES_H */
diff --git a/source/include/rpc_shutdown.h b/source/include/rpc_shutdown.h
index b8e50b835f5..a9d86aec26c 100644
--- a/source/include/rpc_shutdown.h
+++ b/source/include/rpc_shutdown.h
@@ -1,7 +1,8 @@
/*
Unix SMB/CIFS implementation.
- SMB parameters and setup
+
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) Gerald (Jerry) Carter 2005.
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,49 +23,53 @@
#define _RPC_SHUTDOWN_H
-/* Implemented */
+/* opnums */
+
#define SHUTDOWN_INIT 0x00
#define SHUTDOWN_ABORT 0x01
-/* NOT IMPLEMENTED
#define SHUTDOWN_INIT_EX 0x02
-*/
-/* SHUTDOWN_Q_INIT */
-typedef struct q_shutodwn_init_info
-{
- uint32 ptr_server;
- uint16 server;
- uint32 ptr_msg;
- UNIHDR hdr_msg; /* shutdown message */
- UNISTR2 uni_msg; /* seconds */
- uint32 timeout; /* seconds */
+
+/***********************************************/
+
+typedef struct {
+ uint16 *server;
+ UNISTR4 *message;
+ uint32 timeout; /* in seconds */
uint8 force; /* boolean: force shutdown */
- uint8 reboot; /* boolean: reboot on shutdown */
-
+ uint8 reboot; /* boolean: reboot on shutdown */
} SHUTDOWN_Q_INIT;
-/* SHUTDOWN_R_INIT */
-typedef struct r_shutdown_init_info
-{
- NTSTATUS status; /* return status */
-
+typedef struct {
+ WERROR status; /* return status */
} SHUTDOWN_R_INIT;
-/* SHUTDOWN_Q_ABORT */
-typedef struct q_shutdown_abort_info
-{
- uint32 ptr_server;
- uint16 server;
+/***********************************************/
+
+typedef struct {
+ uint16 *server;
+ UNISTR4 *message;
+ uint32 timeout; /* in seconds */
+ uint8 force; /* boolean: force shutdown */
+ uint8 reboot; /* boolean: reboot on shutdown */
+ uint32 reason; /* reason - must be defined code */
+} SHUTDOWN_Q_INIT_EX;
-} SHUTDOWN_Q_ABORT;
+typedef struct {
+ WERROR status;
+} SHUTDOWN_R_INIT_EX;
-/* SHUTDOWN_R_ABORT */
-typedef struct r_shutdown_abort_info
-{
- NTSTATUS status; /* return status */
+/***********************************************/
+typedef struct {
+ uint16 *server;
+} SHUTDOWN_Q_ABORT;
+
+typedef struct {
+ WERROR status;
} SHUTDOWN_R_ABORT;
+
#endif /* _RPC_SHUTDOWN_H */
diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h
index 7c5942759f4..64533635083 100755
--- a/source/include/rpc_spoolss.h
+++ b/source/include/rpc_spoolss.h
@@ -1,11 +1,10 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
- SMB parameters and setup
+
Copyright (C) Andrew Tridgell 1992-2000,
Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
Copyright (C) Jean Francois Micouleau 1998-2000.
- Copyright (C) Gerald Carter 2001-2002.
+ Copyright (C) Gerald Carter 2001-2005.
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
@@ -427,27 +426,22 @@ PRINTER_MESSAGE_INFO;
/* this struct is undocumented */
/* thanks to the ddk ... */
-typedef struct spool_user_1
-{
+typedef struct {
uint32 size; /* length of user_name & client_name + 2? */
- uint32 client_name_ptr;
- uint32 user_name_ptr;
+ UNISTR2 *client_name;
+ UNISTR2 *user_name;
uint32 build;
uint32 major;
uint32 minor;
uint32 processor;
- UNISTR2 client_name;
- UNISTR2 user_name;
-}
-SPOOL_USER_1;
+} SPOOL_USER_1;
-typedef struct spool_user_ctr_info
-{
+typedef struct {
uint32 level;
- uint32 ptr;
- SPOOL_USER_1 user1;
-}
-SPOOL_USER_CTR;
+ union {
+ SPOOL_USER_1 *user1;
+ } user;
+} SPOOL_USER_CTR;
/*
* various bits in the DEVICEMODE.fields member
@@ -544,41 +538,33 @@ typedef struct _printer_default
}
PRINTER_DEFAULT;
-/* SPOOL_Q_OPEN_PRINTER request to open a printer */
-typedef struct spool_q_open_printer
-{
- uint32 printername_ptr;
- UNISTR2 printername;
+/********************************************/
+
+typedef struct {
+ UNISTR2 *printername;
PRINTER_DEFAULT printer_default;
-}
-SPOOL_Q_OPEN_PRINTER;
+} SPOOL_Q_OPEN_PRINTER;
-/* SPOOL_R_OPEN_PRINTER reply to an open printer */
-typedef struct spool_r_open_printer
-{
+typedef struct {
POLICY_HND handle; /* handle used along all transactions (20*uint8) */
WERROR status;
-}
-SPOOL_R_OPEN_PRINTER;
+} SPOOL_R_OPEN_PRINTER;
-/* SPOOL_Q_OPEN_PRINTER_EX request to open a printer */
-typedef struct spool_q_open_printer_ex
-{
- uint32 printername_ptr;
- UNISTR2 printername;
+/********************************************/
+
+typedef struct {
+ UNISTR2 *printername;
PRINTER_DEFAULT printer_default;
uint32 user_switch;
SPOOL_USER_CTR user_ctr;
-}
-SPOOL_Q_OPEN_PRINTER_EX;
+} SPOOL_Q_OPEN_PRINTER_EX;
-/* SPOOL_R_OPEN_PRINTER_EX reply to an open printer */
-typedef struct spool_r_open_printer_ex
-{
+typedef struct {
POLICY_HND handle; /* handle used along all transactions (20*uint8) */
WERROR status;
-}
-SPOOL_R_OPEN_PRINTER_EX;
+} SPOOL_R_OPEN_PRINTER_EX;
+
+/********************************************/
typedef struct spool_notify_option_type
{
@@ -614,15 +600,6 @@ typedef struct s_header_type
}
HEADER_TYPE;
-typedef struct new_buffer
-{
- uint32 ptr;
- uint32 size;
- prs_struct prs;
- uint32 struct_start;
- uint32 string_at_end;
-}
-NEW_BUFFER;
typedef struct spool_q_getprinterdata
{
@@ -1014,7 +991,7 @@ typedef struct spool_q_enumprinters
uint32 servername_ptr;
UNISTR2 servername;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPRINTERS;
@@ -1033,7 +1010,7 @@ PRINTER_INFO_CTR;
typedef struct spool_r_enumprinters
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed; /* bytes needed */
uint32 returned; /* number of printers */
WERROR status;
@@ -1045,7 +1022,7 @@ typedef struct spool_q_getprinter
{
POLICY_HND handle;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_GETPRINTER;
@@ -1063,7 +1040,7 @@ typedef struct printer_info_info
typedef struct spool_r_getprinter
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
} SPOOL_R_GETPRINTER;
@@ -1137,7 +1114,7 @@ typedef struct spool_q_getprinterdriver2
uint32 architecture_ptr;
UNISTR2 architecture;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
uint32 clientmajorversion;
uint32 clientminorversion;
@@ -1146,7 +1123,7 @@ SPOOL_Q_GETPRINTERDRIVER2;
typedef struct spool_r_getprinterdriver2
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 servermajorversion;
uint32 serverminorversion;
@@ -1167,14 +1144,14 @@ typedef struct spool_q_addjob
{
POLICY_HND handle;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ADDJOB;
typedef struct spool_r_addjob
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
}
@@ -1251,7 +1228,7 @@ typedef struct spool_q_enumjobs
uint32 firstjob;
uint32 numofjobs;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMJOBS;
@@ -1269,7 +1246,7 @@ typedef struct job_info_ctr_info
typedef struct spool_r_enumjobs
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 returned;
WERROR status;
@@ -1316,7 +1293,7 @@ typedef struct spool_q_enumports
uint32 name_ptr;
UNISTR2 name;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPORTS;
@@ -1335,7 +1312,7 @@ PORT_INFO_CTR;
typedef struct spool_r_enumports
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed; /* bytes needed */
uint32 returned; /* number of printers */
WERROR status;
@@ -1385,14 +1362,14 @@ typedef struct spool_q_enumprinterdrivers
uint32 environment_ptr;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPRINTERDRIVERS;
typedef struct spool_r_enumprinterdrivers
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 returned;
WERROR status;
@@ -1420,14 +1397,14 @@ typedef struct spool_q_enumforms
{
POLICY_HND handle;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMFORMS;
typedef struct spool_r_enumforms
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 numofforms;
WERROR status;
@@ -1439,14 +1416,14 @@ typedef struct spool_q_getform
POLICY_HND handle;
UNISTR2 formname;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_GETFORM;
typedef struct spool_r_getform
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
}
@@ -1601,28 +1578,6 @@ typedef struct spool_printer_driver_info_level
SPOOL_PRINTER_DRIVER_INFO_LEVEL;
-/* this struct is undocumented */
-/* thanks to the ddk ... */
-typedef struct spool_user_level_1
-{
- uint32 size;
- uint32 client_name_ptr;
- uint32 user_name_ptr;
- uint32 build;
- uint32 major;
- uint32 minor;
- uint32 processor;
- UNISTR2 client_name;
- UNISTR2 user_name;
-}
-SPOOL_USER_LEVEL_1;
-
-typedef struct spool_user_level
-{
- SPOOL_USER_LEVEL_1 *user_level_1;
-}
-SPOOL_USER_LEVEL;
-
typedef struct spool_q_setprinter
{
POLICY_HND handle;
@@ -1642,70 +1597,46 @@ typedef struct spool_r_setprinter
}
SPOOL_R_SETPRINTER;
-typedef struct spool_q_addprinter
-{
- UNISTR2 server_name;
- uint32 level;
- SPOOL_PRINTER_INFO_LEVEL info;
- DEVMODE_CTR devmode_ctr;
- SEC_DESC_BUF *secdesc_ctr;
- uint32 user_level;
- SPOOL_USER_LEVEL user;
-}
-SPOOL_Q_ADDPRINTER;
-
-typedef struct spool_r_addprinter
-{
- WERROR status;
-}
-SPOOL_R_ADDPRINTER;
+/********************************************/
-typedef struct spool_q_deleteprinter
-{
+typedef struct {
POLICY_HND handle;
-}
-SPOOL_Q_DELETEPRINTER;
+} SPOOL_Q_DELETEPRINTER;
-typedef struct spool_r_deleteprinter
-{
+typedef struct {
POLICY_HND handle;
WERROR status;
-}
-SPOOL_R_DELETEPRINTER;
+} SPOOL_R_DELETEPRINTER;
-typedef struct spool_q_abortprinter
-{
+/********************************************/
+
+typedef struct {
POLICY_HND handle;
-}
-SPOOL_Q_ABORTPRINTER;
+} SPOOL_Q_ABORTPRINTER;
-typedef struct spool_r_abortprinter
-{
+typedef struct {
WERROR status;
-}
-SPOOL_R_ABORTPRINTER;
+} SPOOL_R_ABORTPRINTER;
-typedef struct spool_q_addprinterex
-{
- uint32 server_name_ptr;
- UNISTR2 server_name;
+/********************************************/
+
+typedef struct {
+ UNISTR2 *server_name;
uint32 level;
SPOOL_PRINTER_INFO_LEVEL info;
DEVMODE_CTR devmode_ctr;
SEC_DESC_BUF *secdesc_ctr;
uint32 user_switch;
SPOOL_USER_CTR user_ctr;
-}
-SPOOL_Q_ADDPRINTEREX;
+} SPOOL_Q_ADDPRINTEREX;
-typedef struct spool_r_addprinterex
-{
+typedef struct {
POLICY_HND handle;
WERROR status;
-}
-SPOOL_R_ADDPRINTEREX;
+} SPOOL_R_ADDPRINTEREX;
+/********************************************/
typedef struct spool_q_addprinterdriver
{
@@ -1758,14 +1689,14 @@ typedef struct spool_q_getprinterdriverdirectory
uint32 environment_ptr;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_GETPRINTERDRIVERDIR;
typedef struct spool_r_getprinterdriverdirectory
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
}
@@ -1795,7 +1726,7 @@ typedef struct spool_q_enumprintprocessors
uint32 environment_ptr;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPRINTPROCESSORS;
@@ -1808,7 +1739,7 @@ PRINTPROCESSOR_1;
typedef struct spool_r_enumprintprocessors
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 returned;
WERROR status;
@@ -1822,7 +1753,7 @@ typedef struct spool_q_enumprintprocdatatypes
uint32 processor_ptr;
UNISTR2 processor;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPRINTPROCDATATYPES;
@@ -1835,7 +1766,7 @@ PRINTPROCDATATYPE_1;
typedef struct spool_r_enumprintprocdatatypes
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 returned;
WERROR status;
@@ -1861,14 +1792,14 @@ typedef struct spool_q_enumprintmonitors
uint32 name_ptr;
UNISTR2 name;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_ENUMPRINTMONITORS;
typedef struct spool_r_enumprintmonitors
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
uint32 returned;
WERROR status;
@@ -1996,7 +1927,7 @@ typedef struct spool_q_getjob
POLICY_HND handle;
uint32 jobid;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_GETJOB;
@@ -2016,7 +1947,7 @@ PJOB_INFO;
typedef struct spool_r_getjob
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
}
@@ -2217,14 +2148,14 @@ typedef struct spool_q_getprintprocessordirectory
UNISTR2 name;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 offered;
}
SPOOL_Q_GETPRINTPROCESSORDIRECTORY;
typedef struct spool_r_getprintprocessordirectory
{
- NEW_BUFFER *buffer;
+ RPC_BUFFER *buffer;
uint32 needed;
WERROR status;
}
diff --git a/source/include/rpc_srvsvc.h b/source/include/rpc_srvsvc.h
index 5ebb77a8c21..f84054b878b 100644
--- a/source/include/rpc_srvsvc.h
+++ b/source/include/rpc_srvsvc.h
@@ -29,6 +29,7 @@
#define SRV_NET_FILE_ENUM 0x09
#define SRV_NET_FILE_CLOSE 0x0b
#define SRV_NET_SESS_ENUM 0x0c
+#define SRV_NET_SESS_DEL 0x0d
#define SRV_NET_SHARE_ADD 0x0e
#define SRV_NET_SHARE_ENUM_ALL 0x0f
#define SRV_NET_SHARE_GET_INFO 0x10
@@ -193,6 +194,27 @@ typedef struct r_net_sess_enum_info
} SRV_R_NET_SESS_ENUM;
+/* SRV_Q_NET_SESS_DEL */
+typedef struct q_net_sess_del
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* server name */
+
+ uint32 ptr_cli_name; /* pointer (to qualifier name) */
+ UNISTR2 uni_cli_name; /* qualifier name "\\qualifier" */
+
+ uint32 ptr_user_name; /* pointer (to user name */
+ UNISTR2 uni_user_name; /* user name */
+
+} SRV_Q_NET_SESS_DEL;
+
+/* SRV_R_NET_SESS_DEL */
+typedef struct r_net_sess_del
+{
+ WERROR status; /* return status */
+
+} SRV_R_NET_SESS_DEL;
+
/* CONN_INFO_0 (pointers to level 0 connection info strings) */
typedef struct ptr_conn_info0
{
diff --git a/source/include/rpc_svcctl.h b/source/include/rpc_svcctl.h
new file mode 100644
index 00000000000..90b90bd24b1
--- /dev/null
+++ b/source/include/rpc_svcctl.h
@@ -0,0 +1,246 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997,
+ Copyright (C) Gerald (Jerry) Carter 2005
+
+ 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 _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
+#define _RPC_SVCCTL_H
+
+
+/* svcctl pipe */
+
+#define SVCCTL_CLOSE_SERVICE 0x00
+#define SVCCTL_CONTROL_SERVICE 0x01
+#define SVCCTL_QUERY_STATUS 0x06
+#define SVCCTL_ENUM_DEPENDENT_SERVICES_W 0x0d
+#define SVCCTL_ENUM_SERVICES_STATUS_W 0x0e
+#define SVCCTL_OPEN_SCMANAGER_W 0x0f
+#define SVCCTL_OPEN_SERVICE_W 0x10
+#define SVCCTL_QUERY_SERVICE_CONFIG_W 0x11
+#define SVCCTL_START_SERVICE_W 0x13
+#define SVCCTL_GET_DISPLAY_NAME 0x14
+#define SVCCTL_QUERY_SERVICE_CONFIG2_W 0x27
+
+/* ANSI versions not implemented currently
+#define SVCCTL_ENUM_SERVICES_STATUS_A 0x0e
+#define SVCCTL_OPEN_SCMANAGER_A 0x1b
+*/
+
+/* SERVER_STATUS - type */
+
+#define SVCCTL_TYPE_WIN32 0x00000030
+#define SVCCTL_TYPE_DRIVER 0x0000000f
+
+/* SERVER_STATUS - state */
+#define SVCCTL_STATE_ACTIVE 0x00000001
+#define SVCCTL_STATE_INACTIVE 0x00000002
+#define SVCCTL_STATE_ALL ( SVCCTL_STATE_ACTIVE | SVCCTL_STATE_INACTIVE )
+
+/* SERVER_STATUS - CurrentState */
+
+#define SVCCTL_STOPPED 0x00000001
+#define SVCCTL_START_PENDING 0x00000002
+#define SVCCTL_STOP_PENDING 0x00000003
+#define SVCCTL_RUNNING 0x00000004
+#define SVCCTL_CONTINUE_PENDING 0x00000005
+#define SVCCTL_PAUSE_PENDING 0x00000006
+#define SVCCTL_PAUSED 0x00000007
+
+/* SERVER_STATUS - ControlAccepted */
+
+#define SVCCTL_ACCEPT_STOP 0x00000001
+#define SVCCTL_ACCEPT_PAUSE_CONTINUE 0x00000002
+#define SVCCTL_ACCEPT_SHUTDOWN 0x00000004
+#define SVCCTL_ACCEPT_PARAMCHANGE 0x00000008
+#define SVCCTL_ACCEPT_NETBINDCHANGE 0x00000010
+#define SVCCTL_ACCEPT_HARDWAREPROFILECHANGE 0x00000020
+#define SVCCTL_ACCEPT_POWEREVENT 0x00000040
+
+/* Service Controls */
+
+#define SVCCTL_CONTROL_STOP 0x00000001
+#define SVCCTL_CONTROL_PAUSE 0x00000002
+#define SVCCTL_CONTROL_CONTINUE 0x00000003
+
+/* utility structures for RPCs */
+
+typedef struct {
+ uint32 type;
+ uint32 state;
+ uint32 controls_accepted;
+ uint32 win32_exit_code;
+ uint32 service_exit_code;
+ uint32 check_point;
+ uint32 wait_hint;
+} SERVICE_STATUS;
+
+typedef struct {
+ UNISTR servicename;
+ UNISTR displayname;
+ SERVICE_STATUS status;
+} ENUM_SERVICES_STATUS;
+
+typedef struct {
+ uint32 service_type;
+ uint32 start_type;
+ uint32 error_control;
+ UNISTR2 *executablepath;
+ UNISTR2 *loadordergroup;
+ uint32 tag_id;
+ UNISTR2 *dependencies;
+ UNISTR2 *startname;
+ UNISTR2 *displayname;
+} SERVICE_CONFIG;
+
+
+/* rpc structures */
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+} SVCCTL_Q_CLOSE_SERVICE;
+
+typedef struct {
+ WERROR status;
+} SVCCTL_R_CLOSE_SERVICE;
+
+/**************************/
+
+typedef struct {
+ UNISTR2 *servername;
+ UNISTR2 *database;
+ uint32 access;
+} SVCCTL_Q_OPEN_SCMANAGER;
+
+typedef struct {
+ POLICY_HND handle;
+ WERROR status;
+} SVCCTL_R_OPEN_SCMANAGER;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ UNISTR2 servicename;
+ uint32 display_name_len;
+} SVCCTL_Q_GET_DISPLAY_NAME;
+
+typedef struct {
+ UNISTR2 displayname;
+ uint32 display_name_len;
+ WERROR status;
+} SVCCTL_R_GET_DISPLAY_NAME;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ UNISTR2 servicename;
+ uint32 access;
+} SVCCTL_Q_OPEN_SERVICE;
+
+typedef struct {
+ POLICY_HND handle;
+ WERROR status;
+} SVCCTL_R_OPEN_SERVICE;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 parmcount;
+ UNISTR4_ARRAY *parameters;
+} SVCCTL_Q_START_SERVICE;
+
+typedef struct {
+ WERROR status;
+} SVCCTL_R_START_SERVICE;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 control;
+} SVCCTL_Q_CONTROL_SERVICE;
+
+typedef struct {
+ SERVICE_STATUS svc_status;
+ WERROR status;
+} SVCCTL_R_CONTROL_SERVICE;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+} SVCCTL_Q_QUERY_STATUS;
+
+typedef struct {
+ SERVICE_STATUS svc_status;
+ WERROR status;
+} SVCCTL_R_QUERY_STATUS;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 type;
+ uint32 state;
+ uint32 buffer_size;
+ uint32 *resume;
+} SVCCTL_Q_ENUM_SERVICES_STATUS;
+
+typedef struct {
+ RPC_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ uint32 *resume;
+ WERROR status;
+} SVCCTL_R_ENUM_SERVICES_STATUS;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 state;
+ uint32 buffer_size;
+} SVCCTL_Q_ENUM_DEPENDENT_SERVICES;
+
+typedef struct {
+ RPC_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ WERROR status;
+} SVCCTL_R_ENUM_DEPENDENT_SERVICES;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+ uint32 buffer_size;
+} SVCCTL_Q_QUERY_SERVICE_CONFIG;
+
+typedef struct {
+ SERVICE_CONFIG config;
+ uint32 needed;
+ WERROR status;
+} SVCCTL_R_QUERY_SERVICE_CONFIG;
+
+#endif /* _RPC_SVCCTL_H */
+
diff --git a/source/include/smb.h b/source/include/smb.h
index 91ec52df237..80b20756517 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -103,6 +103,7 @@ typedef int BOOL;
#define DOS_OPEN_RDONLY 0
#define DOS_OPEN_WRONLY 1
#define DOS_OPEN_RDWR 2
+#define DOS_OPEN_EXEC 3
#define DOS_OPEN_FCB 0xF
/* define shifts and masks for share and open modes. */
@@ -193,6 +194,9 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PIPE_NETDFS "\\PIPE\\netdfs"
#define PIPE_ECHO "\\PIPE\\rpcecho"
#define PIPE_SHUTDOWN "\\PIPE\\initshutdown"
+#define PIPE_EPM "\\PIPE\\epmapper"
+#define PIPE_SVCCTL "\\PIPE\\svcctl"
+#define PIPE_EVENTLOG "\\PIPE\\eventlog"
#define PIPE_NETLOGON_PLAIN "\\NETLOGON"
@@ -207,7 +211,9 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PI_NETDFS 8
#define PI_ECHO 9
#define PI_SHUTDOWN 10
-#define PI_MAX_PIPES 11
+#define PI_SVCCTL 11
+#define PI_EVENTLOG 12
+#define PI_MAX_PIPES 13
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
typedef struct nttime_info
@@ -281,10 +287,28 @@ typedef struct sid_info
} DOM_SID;
-typedef struct sid_list {
- uint32 count;
- DOM_SID *list;
-} SID_LIST;
+/* Some well-known SIDs */
+extern const DOM_SID global_sid_World_Domain;
+extern const DOM_SID global_sid_World;
+extern const DOM_SID global_sid_Creator_Owner_Domain;
+extern const DOM_SID global_sid_NT_Authority;
+extern const DOM_SID global_sid_System;
+extern const DOM_SID global_sid_NULL;
+extern const DOM_SID global_sid_Authenticated_Users;
+extern const DOM_SID global_sid_Network;
+extern const DOM_SID global_sid_Creator_Owner;
+extern const DOM_SID global_sid_Creator_Group;
+extern const DOM_SID global_sid_Anonymous;
+extern const DOM_SID global_sid_Builtin;
+extern const DOM_SID global_sid_Builtin_Administrators;
+extern const DOM_SID global_sid_Builtin_Users;
+extern const DOM_SID global_sid_Builtin_Guests;
+extern const DOM_SID global_sid_Builtin_Power_Users;
+extern const DOM_SID global_sid_Builtin_Account_Operators;
+extern const DOM_SID global_sid_Builtin_Server_Operators;
+extern const DOM_SID global_sid_Builtin_Print_Operators;
+extern const DOM_SID global_sid_Builtin_Backup_Operators;
+extern const DOM_SID global_sid_Builtin_Replicator;
/*
* The complete list of SIDS belonging to this user.
@@ -355,14 +379,14 @@ typedef struct time_info
} UTIME;
/* Structure used when SMBwritebmpx is active */
-typedef struct
-{
- size_t wr_total_written; /* So we know when to discard this */
- int32 wr_timeout;
- int32 wr_errclass;
- int32 wr_error; /* Cached errors */
- BOOL wr_mode; /* write through mode) */
- BOOL wr_discard; /* discard all further data */
+typedef struct {
+ size_t wr_total_written; /* So we know when to discard this */
+ int32 wr_timeout;
+ int32 wr_errclass; /* Cached errors */
+ int32 wr_error; /* Cached errors */
+ NTSTATUS wr_status; /* Cached errors */
+ BOOL wr_mode; /* write through mode) */
+ BOOL wr_discard; /* discard all further data */
} write_bmpx_struct;
typedef struct write_cache
@@ -1382,13 +1406,6 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
*/
#define COPYBUF_SIZE (8*1024)
-/*
- * Values used to override error codes.
- */
-extern int unix_ERR_class;
-extern int unix_ERR_code;
-extern NTSTATUS unix_ERR_ntstatus;
-
/*
* Used in chaining code.
*/
@@ -1717,6 +1734,11 @@ struct ea_struct {
DATA_BLOB value;
};
+struct ea_list {
+ struct ea_list *next, *prev;
+ struct ea_struct ea;
+};
+
/* EA names used internally in Samba. KEEP UP TO DATE with prohibited_ea_names in trans2.c !. */
#define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
/* EA to use for DOS attributes */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 4fa9ffa5ace..ab4ee5ee73b 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -43,7 +43,7 @@
* @note You are explicitly allowed to pass NULL pointers -- they will
* always be ignored.
**/
-#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(CONST_DISCARD(void *, (x))); x=NULL;} } while(0)
#endif
/* zero a structure */
@@ -76,16 +76,20 @@
#define OPEN_CONN(conn) ((conn) && (conn)->open)
#define IS_IPC(conn) ((conn) && (conn)->ipc)
#define IS_PRINT(conn) ((conn) && (conn)->printer)
+/* you must add the following extern declaration to files using this macro
+ * extern struct current_user current_user;
+ */
#define FSP_BELONGS_CONN(fsp,conn) do {\
- extern struct current_user current_user;\
if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
return(ERROR_DOS(ERRDOS,ERRbadfid));\
} while(0)
#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
+/* you must add the following extern declaration to files using this macro
+ * extern struct current_user current_user;
+ */
#define CHECK_FSP(fsp,conn) do {\
- extern struct current_user current_user;\
if (!FNUM_OK(fsp,conn)) \
return(ERROR_DOS(ERRDOS,ERRbadfid)); \
else if((fsp)->fd == -1) \
@@ -97,9 +101,6 @@
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
return(ERROR_DOS(ERRDOS,ERRbadaccess))
-#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
- return(CACHED_ERROR(fsp))
-
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
@@ -158,25 +159,23 @@
#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_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,False,__LINE__,__FILE__)
-#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,NT_STATUS_OK,class,code,True,__LINE__,__FILE__)
-#define ERROR_NT(status) error_packet(outbuf,status,0,0,False,__LINE__,__FILE__)
-#define ERROR_BOTH(status,class,code) error_packet(outbuf,status,class,code,False,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
+#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_INVALID,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
+#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
+#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
/* this is how errors are generated */
-#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
+#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
+
+/* these are the datagram types */
+#define DGRAM_DIRECT_UNIQUE 0x10
#define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x))
@@ -290,6 +289,8 @@ copy an IP address from one buffer to another
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array_((ctx),(ptr),sizeof(type),(count))
#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem_((ps),sizeof(type),(count))
+#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem_((ps),(size),1)
+
/* Get medieval on our ass about malloc.... */
@@ -338,6 +339,7 @@ copy an IP address from one buffer to another
#define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)talloc_realloc_array((ctx),(ptr),sizeof(type),(count))
#define PRS_ALLOC_MEM(ps, type, count) (type *)prs_alloc_mem((ps),sizeof(type),(count))
+#define PRS_ALLOC_MEM_VOID(ps, size) prs_alloc_mem((ps),(size),1)
/* Regular malloc code. */
@@ -349,4 +351,14 @@ copy an IP address from one buffer to another
#endif
+#define ADD_TO_ARRAY(mem_ctx, type, elem, array, num) \
+do { \
+ *(array) = ((mem_ctx) != NULL) ? \
+ TALLOC_REALLOC_ARRAY(mem_ctx, (*(array)), type, (*(num))+1) : \
+ SMB_REALLOC_ARRAY((*(array)), type, (*(num))+1); \
+ SMB_ASSERT((*(array)) != NULL); \
+ (*(array))[*(num)] = (elem); \
+ (*(num)) += 1; \
+} while (0)
+
#endif /* _SMB_MACROS_H */
diff --git a/source/include/trans2.h b/source/include/trans2.h
index 68358344f4e..2aae1137dd7 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -226,6 +226,9 @@ Byte offset Type name description
#define SMB_QUERY_FILE_STREAM_INFO 0x109
#define SMB_QUERY_COMPRESSION_INFO 0x10b
+#define SMB_FIND_INFO_STANDARD 1
+#define SMB_FIND_EA_SIZE 2
+#define SMB_FIND_EA_LIST 3
#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
#define SMB_FIND_FILE_NAMES_INFO 0x103
@@ -437,6 +440,9 @@ Offset Size Name
#define SMB_QUERY_XATTR 0x205 /* need for non-user XATTRs */
#define SMB_QUERY_ATTR_FLAGS 0x206 /* chflags, chattr */
#define SMB_SET_ATTR_FLAGS 0x206
+#define SMB_QUERY_POSIX_PERMISSION 0x207
+#define SMB_QUERY_POSIX_LOCK 0x208
+#define SMB_SET_POSIX_LOCK 0x208
/* Transact 2 Find First levels */
#define SMB_FIND_FILE_UNIX 0x202
@@ -461,6 +467,12 @@ Offset Size Name
#define CIFS_UNIX_FCNTL_LOCKS_CAP 0x1
#define CIFS_UNIX_POSIX_ACLS_CAP 0x2
+#define CIFS_UNIX_XATTTR_CAP 0x4 /* for support of other xattr
+ namespaces such as system,
+ security and trusted */
+#define CIFS_UNIX_EXTATTR_CAP 0x8 /* for support of chattr
+ (chflags) and lsattr */
+
#define SMB_QUERY_POSIX_FS_INFO 0x201
diff --git a/source/intl/lang_tdb.c b/source/intl/lang_tdb.c
index d3422f0d78a..d8f7fc8c933 100644
--- a/source/intl/lang_tdb.c
+++ b/source/intl/lang_tdb.c
@@ -231,7 +231,7 @@ const char *lang_msg(const char *msgid)
void lang_msg_free(const char *msgstr)
{
if (!tdb) return;
- free((void *)msgstr);
+ free(CONST_DISCARD(void *, msgstr));
}
@@ -248,7 +248,7 @@ const char *lang_msg_rotate(const char *msgid)
static pstring bufs[NUM_LANG_BUFS];
static int next;
- msgstr = (char *)lang_msg(msgid);
+ msgstr = CONST_DISCARD(char *, lang_msg(msgid));
if (!msgstr) return msgid;
pstrcpy(bufs[next], msgstr);
diff --git a/source/lib/access.c b/source/lib/access.c
index fcc795d1f26..d8e40c99f76 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -133,7 +133,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
/* client_match - match host name and address against token */
static BOOL client_match(const char *tok, const char *item)
{
- const char **client = (const char **)item;
+ const char **client = CONST_ADD(const char **, item);
BOOL match;
char invalid_char = '\0';
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index 72d6e77ddda..423dc1675a6 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -24,14 +24,6 @@ static TDB_CONTEXT *tdb;
#define DATABASE_VERSION 2
-extern DOM_SID global_sid_World;
-extern DOM_SID global_sid_Builtin_Administrators;
-extern DOM_SID global_sid_Builtin_Account_Operators;
-extern DOM_SID global_sid_Builtin_Server_Operators;
-extern DOM_SID global_sid_Builtin_Print_Operators;
-extern DOM_SID global_sid_Builtin_Backup_Operators;
-
-
/****************************************************************************
Set default for a field if it is empty
****************************************************************************/
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index b9b9d90db67..4fbad0f3d18 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -1269,6 +1269,21 @@ size_t pull_utf8_allocate(char **dest, const char *src)
}
/**
+ * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
+ *
+ * @param dest always set at least to NULL
+ *
+ * @returns The number of bytes occupied by the string in the destination
+ **/
+
+size_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+{
+ size_t src_len = strlen(src)+1;
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest, True);
+}
+
+/**
Copy a string from a char* src to a unicode or ascii
dos codepage destination choosing unicode or ascii based on the
flags in the SMB buffer starting at base_ptr.
diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c
index a1c3af2d492..35805f861c5 100644
--- a/source/lib/data_blob.c
+++ b/source/lib/data_blob.c
@@ -47,7 +47,7 @@ DATA_BLOB data_blob(const void *p, size_t length)
if (p) {
ret.data = smb_xmemdup(p, length);
} else {
- ret.data = SMB_XMALLOC_ARRAY(char, length);
+ ret.data = SMB_XMALLOC_ARRAY(unsigned char, length);
}
ret.length = length;
ret.free = free_data_blob;
diff --git a/source/lib/iconv.c b/source/lib/iconv.c
index d58165fed03..f23e4351c02 100644
--- a/source/lib/iconv.c
+++ b/source/lib/iconv.c
@@ -135,7 +135,7 @@ static size_t sys_iconv(void *cd,
{
#ifdef HAVE_NATIVE_ICONV
size_t ret = iconv((iconv_t)cd,
- (char **)inbuf, inbytesleft,
+ CONST_DISCARD(char **, inbuf), inbytesleft,
outbuf, outbytesleft);
if (ret == (size_t)-1) {
int saved_errno = errno;
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index a0cbfd2ee21..c7cf54d26b5 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -146,7 +146,7 @@ static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n,
return -1;
}
-int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol,
+int ms_fnmatch(const char *pattern, const char *string, BOOL translate_pattern,
BOOL is_case_sensitive)
{
wpstring p, s;
@@ -179,7 +179,7 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot
return -1;
}
- if (protocol <= PROTOCOL_LANMAN2) {
+ if (translate_pattern) {
/*
for older negotiated protocols it is possible to
translate the pattern to produce a "new style"
diff --git a/source/lib/privileges.c b/source/lib/privileges.c
index 8b5348e1f25..e01561de06f 100644
--- a/source/lib/privileges.c
+++ b/source/lib/privileges.c
@@ -95,7 +95,12 @@ PRIVS privs[] = {
{SE_END, "", ""}
};
-typedef struct priv_sid_list {
+typedef struct {
+ int count;
+ DOM_SID *list;
+} SID_LIST;
+
+typedef struct {
SE_PRIV privilege;
SID_LIST sids;
} PRIV_SID_LIST;
@@ -492,7 +497,7 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s
return 0;
}
- add_sid_to_array( &sid, &priv->sids.list, &priv->sids.count );
+ add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count );
return 0;
}
diff --git a/source/lib/secace.c b/source/lib/secace.c
index e44d9aa940e..c550dcce311 100644
--- a/source/lib/secace.c
+++ b/source/lib/secace.c
@@ -57,7 +57,7 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
Sets up a SEC_ACE structure.
********************************************************************/
-void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
{
t->type = type;
t->flags = flag;
diff --git a/source/lib/secdesc.c b/source/lib/secdesc.c
index 686a4edf77c..ace0aee8664 100644
--- a/source/lib/secdesc.c
+++ b/source/lib/secdesc.c
@@ -179,7 +179,7 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU
********************************************************************/
SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type,
- DOM_SID *owner_sid, DOM_SID *grp_sid,
+ const DOM_SID *owner_sid, const DOM_SID *grp_sid,
SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
{
SEC_DESC *dst;
@@ -269,7 +269,7 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
Creates a SEC_DESC structure with typical defaults.
********************************************************************/
-SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, DOM_SID *owner_sid, DOM_SID *grp_sid,
+SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
SEC_ACL *dacl, size_t *sd_size)
{
return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
diff --git a/source/lib/select.c b/source/lib/select.c
index f3d119bdb15..2e55f9753db 100644
--- a/source/lib/select.c
+++ b/source/lib/select.c
@@ -99,20 +99,23 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s
FD_ZERO(writefds);
if (errorfds)
FD_ZERO(errorfds);
- }
-
- if (FD_ISSET(select_pipe[0], readfds2)) {
+ } else if (FD_ISSET(select_pipe[0], readfds2)) {
char c;
saved_errno = errno;
if (read(select_pipe[0], &c, 1) == 1) {
pipe_read++;
- }
- errno = saved_errno;
- FD_CLR(select_pipe[0], readfds2);
- ret--;
- if (ret == 0) {
+ /* Mark Weaver <mark-clist@npsl.co.uk> pointed out a critical
+ fix to ensure we don't lose signals. We must always
+ return -1 when the select pipe is set, otherwise if another
+ fd is also ready (so ret == 2) then we used to eat the
+ byte in the pipe and lose the signal. JRA.
+ */
ret = -1;
errno = EINTR;
+ } else {
+ FD_CLR(select_pipe[0], readfds2);
+ ret--;
+ errno = saved_errno;
}
}
@@ -167,7 +170,12 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf
ptval->tv_usec = tdif % 1000000;
}
- ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
+ /* We must use select and not sys_select here. If we use
+ sys_select we'd lose the fact a signal occurred when sys_select
+ read a byte from the pipe. Fix from Mark Weaver
+ <mark-clist@npsl.co.uk>
+ */
+ ret = select(maxfd, readfds2, writefds2, errorfds2, ptval);
} while (ret == -1 && errno == EINTR);
if (readfds)
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 68084b04045..cf2f03e0a24 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -1066,7 +1066,9 @@ int smbldap_search(struct smbldap_state *ldap_state,
while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
- utf8_filter, attrs, attrsonly, res);
+ utf8_filter,
+ CONST_DISCARD(char **, attrs),
+ attrsonly, res);
SAFE_FREE(utf8_filter);
return rc;
@@ -1471,7 +1473,8 @@ static BOOL smbldap_check_root_dse(struct smbldap_state *ldap_state, const char
}
rc = ldap_search_s(ldap_state->ldap_struct, "", LDAP_SCOPE_BASE,
- "(objectclass=*)", attrs, 0 , &msg);
+ "(objectclass=*)", CONST_DISCARD(char **, attrs),
+ 0 , &msg);
if (rc != LDAP_SUCCESS) {
DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 615a8d73b0a..af30e900ace 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -21,6 +21,8 @@
#include "includes.h"
+extern struct current_user current_user;
+
fstring local_machine="";
fstring remote_arch="UNKNOWN";
userdom_struct current_user_info;
@@ -800,7 +802,6 @@ char *alloc_sub_conn(connection_struct *conn, const char *str)
void standard_sub_snum(int snum, char *str, size_t len)
{
- extern struct current_user current_user;
static uid_t cached_uid = -1;
static fstring cached_user;
/* calling uidtoname() on every substitute would be too expensive, so
diff --git a/source/lib/system.c b/source/lib/system.c
index 7434cbe35ee..a2e5352aa5f 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -1373,10 +1373,17 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
{
#if defined(HAVE_GETXATTR)
return getxattr(path, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FILE)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_get_file(path, attrnamespace, attrname, value, size);
#elif defined(HAVE_ATTR_GET)
int retval, flags = 0;
int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1393,10 +1400,17 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s
{
#if defined(HAVE_LGETXATTR)
return lgetxattr(path, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_LINK)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_get_link(path, attrnamespace, attrname, value, size);
#elif defined(HAVE_ATTR_GET)
int retval, flags = ATTR_DONTFOLLOW;
int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1413,10 +1427,17 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
{
#if defined(HAVE_FGETXATTR)
return fgetxattr(filedes, name, value, size);
+#elif defined(HAVE_EXTATTR_GET_FD)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_get_fd(filedes, attrnamespace, attrname, value, size);
#elif defined(HAVE_ATTR_GETF)
int retval, flags = 0;
int valuelength = (int)size;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1429,6 +1450,99 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
#endif
}
+#if defined(HAVE_EXTATTR_LIST_FILE)
+
+#define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
+
+static struct {
+ int space;
+ const char *name;
+ size_t len;
+}
+extattr[] = {
+ { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
+ { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
+};
+
+typedef union {
+ const char *path;
+ int filedes;
+} extattr_arg;
+
+static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
+{
+ ssize_t list_size, total_size = 0;
+ int i, t, len;
+ char *buf;
+ /* Iterate through extattr(2) namespaces */
+ for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
+ switch(type) {
+#if defined(HAVE_EXTATTR_LIST_FILE)
+ case 0:
+ list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
+ break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_LINK)
+ case 1:
+ list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
+ break;
+#endif
+#if defined(HAVE_EXTATTR_LIST_FD)
+ case 2:
+ list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
+ break;
+#endif
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+ /* Some error happend. Errno should be set by the previous call */
+ if(list_size < 0)
+ return -1;
+ /* No attributes */
+ if(list_size == 0)
+ continue;
+ /* XXX: Call with an empty buffer may be used to calculate
+ necessary buffer size. Unfortunately, we can't say, how
+ many attributes were returned, so here is the potential
+ problem with the emulation.
+ */
+ if(list == NULL) {
+ /* Take the worse case of one char attribute names -
+ two bytes per name plus one more for sanity.
+ */
+ total_size += list_size + (list_size/2 + 1)*extattr[t].len;
+ continue;
+ }
+ /* Count necessary offset to fit namespace prefixes */
+ len = 0;
+ for(i = 0; i < list_size; i += list[i] + 1)
+ len += extattr[t].len;
+
+ total_size += list_size + len;
+ /* Buffer is too small to fit the results */
+ if(total_size > size) {
+ errno = ERANGE;
+ return -1;
+ }
+ /* Shift the results back, so we can prepend prefixes */
+ buf = memmove(list + len, list, list_size);
+
+ for(i = 0; i < list_size; i += len + 1) {
+ len = buf[i];
+ strncpy(list, extattr[t].name, extattr[t].len + 1);
+ list += extattr[t].len;
+ strncpy(list, buf + i + 1, len);
+ list[len] = '\0';
+ list += len + 1;
+ }
+ size -= total_size;
+ }
+ return total_size;
+}
+
+#endif
+
#if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
static char attr_buffer[ATTR_MAX_VALUELEN];
@@ -1501,6 +1615,10 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
{
#if defined(HAVE_LISTXATTR)
return listxattr(path, list, size);
+#elif defined(HAVE_EXTATTR_LIST_FILE)
+ extattr_arg arg;
+ arg.path = path;
+ return bsd_attr_list(0, arg, list, size);
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
return irix_attr_list(path, 0, list, size, 0);
#else
@@ -1513,6 +1631,10 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
{
#if defined(HAVE_LLISTXATTR)
return llistxattr(path, list, size);
+#elif defined(HAVE_EXTATTR_LIST_LINK)
+ extattr_arg arg;
+ arg.path = path;
+ return bsd_attr_list(1, arg, list, size);
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
#else
@@ -1525,6 +1647,10 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size)
{
#if defined(HAVE_FLISTXATTR)
return flistxattr(filedes, list, size);
+#elif defined(HAVE_EXTATTR_LIST_FD)
+ extattr_arg arg;
+ arg.filedes = filedes;
+ return bsd_attr_list(2, arg, list, size);
#elif defined(HAVE_ATTR_LISTF)
return irix_attr_list(NULL, filedes, list, size, 0);
#else
@@ -1537,9 +1663,16 @@ int sys_removexattr (const char *path, const char *name)
{
#if defined(HAVE_REMOVEXATTR)
return removexattr(path, name);
+#elif defined(HAVE_EXTATTR_DELETE_FILE)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_delete_file(path, attrnamespace, attrname);
#elif defined(HAVE_ATTR_REMOVE)
int flags = 0;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1554,9 +1687,16 @@ int sys_lremovexattr (const char *path, const char *name)
{
#if defined(HAVE_LREMOVEXATTR)
return lremovexattr(path, name);
+#elif defined(HAVE_EXTATTR_DELETE_LINK)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_delete_link(path, attrnamespace, attrname);
#elif defined(HAVE_ATTR_REMOVE)
int flags = ATTR_DONTFOLLOW;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1571,9 +1711,16 @@ int sys_fremovexattr (int filedes, const char *name)
{
#if defined(HAVE_FREMOVEXATTR)
return fremovexattr(filedes, name);
+#elif defined(HAVE_EXTATTR_DELETE_FD)
+ char *s;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ return extattr_delete_fd(filedes, attrnamespace, attrname);
#elif defined(HAVE_ATTR_REMOVEF)
int flags = 0;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
@@ -1593,9 +1740,18 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
{
#if defined(HAVE_SETXATTR)
return setxattr(path, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_FILE)
+ char *s;
+ int retval = 0;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ retval = extattr_set_file(path, attrnamespace, attrname, value, size);
+ return (retval < 0) ? -1 : 0;
#elif defined(HAVE_ATTR_SET)
int myflags = 0;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
@@ -1612,9 +1768,18 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
{
#if defined(HAVE_LSETXATTR)
return lsetxattr(path, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_LINK)
+ char *s;
+ int retval = 0;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ retval = extattr_set_link(path, attrnamespace, attrname, value, size);
+ return (retval < 0) ? -1 : 0;
#elif defined(HAVE_ATTR_SET)
int myflags = ATTR_DONTFOLLOW;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
@@ -1631,9 +1796,18 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
{
#if defined(HAVE_FSETXATTR)
return fsetxattr(filedes, name, value, size, flags);
+#elif defined(HAVE_EXTATTR_SET_FD)
+ char *s;
+ int retval = 0;
+ int attrnamespace = (strncmp(name, "system", 6) == 0) ?
+ EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
+ const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
+
+ retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
+ return (retval < 0) ? -1 : 0;
#elif defined(HAVE_ATTR_SETF)
int myflags = 0;
- char *attrname = strchr(name,'.') +1;
+ char *attrname = strchr(name,'.') + 1;
if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
index c83eecf1733..f124983006d 100644
--- a/source/lib/system_smbd.c
+++ b/source/lib/system_smbd.c
@@ -178,10 +178,10 @@ BOOL getgroups_user(const char *user, gid_t primary_gid,
groups = NULL;
/* Add in primary group first */
- add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+ add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
for (i=0; i<max_grp; i++)
- add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+ add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
*ngroups = ngrp;
*ret_groups = groups;
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index cafe0654790..f5e21299b5a 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -338,6 +338,19 @@ char *talloc_strdup(TALLOC_CTX *t, const char *p)
return NULL;
}
+/* strndup with a talloc */
+char *talloc_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t maxlen)
+{
+ size_t len = strnlen(str, maxlen);
+ void *ret = TALLOC(mem_ctx, len+1);
+
+ if (ret != NULL) {
+ memcpy(ret, str, len);
+ ((char *)ret)[len] = '\0';
+ }
+ return ret;
+}
+
/** strdup_upper with a talloc */
char *talloc_strdup_upper(TALLOC_CTX *t, const char *p)
{
diff --git a/source/lib/time.c b/source/lib/time.c
index 84004a099be..9f94791b581 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -791,3 +791,25 @@ SMB_BIG_INT usec_time_diff(struct timeval *larget, struct timeval *smallt)
SMB_BIG_INT sec_diff = larget->tv_sec - smallt->tv_sec;
return (sec_diff * 1000000) + (SMB_BIG_INT)(larget->tv_usec - smallt->tv_usec);
}
+
+
+/****************************************************************************
+ convert ASN.1 GeneralizedTime string to unix-time
+ returns 0 on failure; Currently ignores timezone.
+****************************************************************************/
+time_t generalized_to_unix_time(const char *str)
+{
+ struct tm tm;
+
+ ZERO_STRUCT(tm);
+
+ if (sscanf(str, "%4d%2d%2d%2d%2d%2d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+ return 0;
+ }
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+
+ return timegm(&tm);
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 42ead313a92..d244e390d22 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -23,6 +23,11 @@
#include "includes.h"
+extern fstring local_machine;
+extern char *global_clobber_region_function;
+extern unsigned int global_clobber_region_line;
+extern fstring remote_arch;
+
/* Max allowable allococation - 256mb - 0x10000000 */
#define MAX_ALLOC_SIZE (1024*1024*256)
@@ -230,7 +235,6 @@ BOOL set_netbios_aliases(const char **str_array)
BOOL init_names(void)
{
- extern fstring local_machine;
char *p;
int n;
@@ -274,28 +278,11 @@ const char *tmpdir(void)
}
/****************************************************************************
- Determine whether we are in the specified group.
-****************************************************************************/
-
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
-{
- int i;
-
- if (group == current_gid)
- return(True);
-
- for (i=0;i<ngroups;i++)
- if (group == groups[i])
- return(True);
-
- return(False);
-}
-
-/****************************************************************************
Add a gid to an array of gids if it's not already there.
****************************************************************************/
-void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num)
+void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+ gid_t **gids, int *num)
{
int i;
@@ -303,8 +290,11 @@ void add_gid_to_array_unique(gid_t gid, gid_t **gids, int *num)
if ((*gids)[i] == gid)
return;
}
-
- *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num+1);
+
+ if (mem_ctx != NULL)
+ *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num+1);
+ else
+ *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num+1);
if (*gids == NULL)
return;
@@ -617,7 +607,7 @@ void unix_clean_name(char *s)
Make a dir struct.
****************************************************************************/
-void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date)
+void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL uc)
{
char *p;
pstring mask2;
@@ -641,7 +631,9 @@ void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T si
put_dos_date(buf,22,date);
SSVAL(buf,26,size & 0xFFFF);
SSVAL(buf,28,(size >> 16)&0xFFFF);
- push_ascii(buf+30,fname,12,0);
+ /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf.
+ Strange, but verified on W2K3. Needed for OS/2. JRA. */
+ push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0);
DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname));
}
@@ -1465,8 +1457,6 @@ void smb_panic2(const char *why, BOOL decrement_pid_count )
#ifdef DEVELOPER
{
- extern char *global_clobber_region_function;
- extern unsigned int global_clobber_region_line;
if (global_clobber_region_function) {
DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
@@ -1931,7 +1921,6 @@ void ra_lanman_string( const char *native_lanman )
void set_remote_arch(enum remote_arch_types type)
{
- extern fstring remote_arch;
ra_type = type;
switch( type ) {
case RA_WFWG:
@@ -2172,8 +2161,12 @@ BOOL reg_split_key(const char *full_keyname, uint32 *reg_type, char *key_name)
if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
(*reg_type) = HKEY_LOCAL_MACHINE;
+ else if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT"))
+ (*reg_type) = HKEY_CLASSES_ROOT;
else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
(*reg_type) = HKEY_USERS;
+ else if (strequal(tmp, "HKPD")||strequal(tmp, "HKEY_PERFORMANCE_DATA"))
+ (*reg_type) = HKEY_PERFORMANCE_DATA;
else {
DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
return False;
@@ -2469,7 +2462,23 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
if (strcmp(pattern,".") == 0)
return False;
- return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0;
+ return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
+}
+
+/*******************************************************************
+ A wrapper that handles case sensitivity and the special handling
+ of the ".." name. Varient that is only called by old search code which requires
+ pattern translation.
+*******************************************************************/
+
+BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
+{
+ if (strcmp(string,"..") == 0)
+ string = ".";
+ if (strcmp(pattern,".") == 0)
+ return False;
+
+ return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
}
/*******************************************************************
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
index b5a9010b5c4..73fc45c844d 100644
--- a/source/lib/util_seaccess.c
+++ b/source/lib/util_seaccess.c
@@ -21,7 +21,7 @@
#include "includes.h"
-extern DOM_SID global_sid_Builtin;
+extern NT_USER_TOKEN anonymous_token;
/*********************************************************************************
Check an ACE against a SID. We return the remaining needed permission
@@ -214,7 +214,6 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted,
NTSTATUS *status)
{
- extern NT_USER_TOKEN anonymous_token;
size_t i;
SEC_ACL *the_acl;
fstring sid_str;
@@ -316,3 +315,41 @@ BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
return False;
}
+
+/*******************************************************************
+ samr_make_sam_obj_sd
+ ********************************************************************/
+
+NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
+{
+ DOM_SID adm_sid;
+ DOM_SID act_sid;
+
+ SEC_ACE ace[3];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ /*basic access for every one*/
+ init_sec_access(&mask, GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ);
+ init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /*full access for builtin aliases Administrators and Account Operators*/
+ init_sec_access(&mask, GENERIC_RIGHTS_SAM_ALL_ACCESS);
+ init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 0ba774e184d..1838da1313d 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -28,29 +28,51 @@
* Some useful sids
*/
-DOM_SID global_sid_World_Domain; /* Everyone domain */
-DOM_SID global_sid_World; /* Everyone */
-DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
-DOM_SID global_sid_NT_Authority; /* NT Authority */
-DOM_SID global_sid_System; /* System */
-DOM_SID global_sid_NULL; /* NULL sid */
-DOM_SID global_sid_Authenticated_Users; /* All authenticated rids */
-DOM_SID global_sid_Network; /* Network rids */
-
-DOM_SID global_sid_Creator_Owner; /* Creator Owner */
-DOM_SID global_sid_Creator_Group; /* Creator Group */
-DOM_SID global_sid_Anonymous; /* Anonymous login */
-
-DOM_SID global_sid_Builtin; /* Local well-known domain */
-DOM_SID global_sid_Builtin_Administrators; /* Builtin administrators */
-DOM_SID global_sid_Builtin_Users; /* Builtin users */
-DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */
-DOM_SID global_sid_Builtin_Power_Users; /* Builtin power users */
-DOM_SID global_sid_Builtin_Account_Operators; /* Builtin account operators */
-DOM_SID global_sid_Builtin_Server_Operators; /* Builtin server operators */
-DOM_SID global_sid_Builtin_Print_Operators; /* Builtin print operators */
-DOM_SID global_sid_Builtin_Backup_Operators; /* Builtin backup operators */
-DOM_SID global_sid_Builtin_Replicator; /* Builtin replicator */
+
+const DOM_SID global_sid_World_Domain = /* Everyone domain */
+{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_World = /* Everyone */
+{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Creator_Owner_Domain = /* Creator Owner domain */
+{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_NT_Authority = /* NT Authority */
+{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_System = /* System */
+{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_NULL = /* NULL sid */
+{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Authenticated_Users = /* All authenticated rids */
+{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Network = /* Network rids */
+{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+const DOM_SID global_sid_Creator_Owner = /* Creator Owner */
+{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Creator_Group = /* Creator Group */
+{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Anonymous = /* Anonymous login */
+{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+const DOM_SID global_sid_Builtin = /* Local well-known domain */
+{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Administrators = /* Builtin administrators */
+{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Users = /* Builtin users */
+{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Guests = /* Builtin guest users */
+{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Power_Users = /* Builtin power users */
+{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Account_Operators = /* Builtin account operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Server_Operators = /* Builtin server operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Print_Operators = /* Builtin print operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators */
+{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
+{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
#define SECURITY_NULL_SID_AUTHORITY 0
#define SECURITY_WORLD_SID_AUTHORITY 1
@@ -62,18 +84,15 @@ DOM_SID global_sid_Builtin_Replicator; /* Builtin replicator */
* An NT compatible anonymous token.
*/
-static DOM_SID anon_sid_array[3];
-
-NT_USER_TOKEN anonymous_token = {
- 3,
- anon_sid_array
-};
+static DOM_SID anon_sid_array[3] =
+{ { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
+ { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
+ { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
+NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
-static DOM_SID system_sid_array[4];
-NT_USER_TOKEN system_token = {
- 1,
- system_sid_array
-};
+static DOM_SID system_sid_array[1] =
+{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
+NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
/****************************************************************************
Lookup string names for SID types.
@@ -111,66 +130,12 @@ const char *sid_type_lookup(uint32 sid_type)
return "SID *TYPE* is INVALID";
}
-/****************************************************************************
- Creates some useful well known sids
-****************************************************************************/
-
-void generate_wellknown_sids(void)
-{
- static BOOL initialised = False;
-
- if (initialised)
- return;
-
- /* SECURITY_NULL_SID_AUTHORITY */
- string_to_sid(&global_sid_NULL, "S-1-0-0");
-
- /* SECURITY_WORLD_SID_AUTHORITY */
- string_to_sid(&global_sid_World_Domain, "S-1-1");
- string_to_sid(&global_sid_World, "S-1-1-0");
-
- /* SECURITY_CREATOR_SID_AUTHORITY */
- string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
- string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
- string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
-
- /* SECURITY_NT_AUTHORITY */
- string_to_sid(&global_sid_NT_Authority, "S-1-5");
- string_to_sid(&global_sid_Network, "S-1-5-2");
- string_to_sid(&global_sid_Anonymous, "S-1-5-7");
- string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
- string_to_sid(&global_sid_System, "S-1-5-18");
-
- /* SECURITY_BUILTIN_DOMAIN_RID */
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
- string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544");
- string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545");
- string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
- string_to_sid(&global_sid_Builtin_Power_Users, "S-1-5-32-547");
- string_to_sid(&global_sid_Builtin_Account_Operators, "S-1-5-32-548");
- string_to_sid(&global_sid_Builtin_Server_Operators, "S-1-5-32-549");
- string_to_sid(&global_sid_Builtin_Print_Operators, "S-1-5-32-550");
- string_to_sid(&global_sid_Builtin_Backup_Operators, "S-1-5-32-551");
- string_to_sid(&global_sid_Builtin_Replicator, "S-1-5-32-552");
-
- /* Create the anon token. */
- sid_copy( &anonymous_token.user_sids[0], &global_sid_World);
- sid_copy( &anonymous_token.user_sids[1], &global_sid_Network);
- sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous);
-
- /* Create the system token. */
- sid_copy( &system_token.user_sids[0], &global_sid_System);
-
- initialised = True;
-}
-
/**************************************************************************
Create the SYSTEM token.
***************************************************************************/
NT_USER_TOKEN *get_system_token(void)
{
- generate_wellknown_sids(); /* The token is initialised here */
return &system_token;
}
@@ -351,6 +316,19 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
return True;
}
+DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
+{
+ DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
+
+ if (result == NULL)
+ return NULL;
+
+ if (!string_to_sid(result, sidstr))
+ return NULL;
+
+ return result;
+}
+
/*****************************************************************
Add a rid to the end of a sid
*****************************************************************/
@@ -652,9 +630,14 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
Add SID to an array SIDs
********************************************************************/
-void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
+void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ DOM_SID **sids, int *num)
{
- *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
+ if (mem_ctx != NULL)
+ *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
+ (*num)+1);
+ else
+ *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
if (*sids == NULL)
return;
@@ -670,7 +653,8 @@ void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
Add SID to an array SIDs ensuring that it is not already there
********************************************************************/
-void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
+void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ DOM_SID **sids, int *num_sids)
{
int i;
@@ -679,7 +663,7 @@ void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
return;
}
- add_sid_to_array(sid, sids, num_sids);
+ add_sid_to_array(mem_ctx, sid, sids, num_sids);
}
/********************************************************************
diff --git a/source/lib/util_smbd.c b/source/lib/util_smbd.c
index 586362c1e4c..c6f6bc0a32a 100644
--- a/source/lib/util_smbd.c
+++ b/source/lib/util_smbd.c
@@ -73,10 +73,10 @@ BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int
groups = NULL;
/* Add in primary group first */
- add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+ add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
for (i=0; i<max_grp; i++)
- add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+ add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
*ngroups = ngrp;
*ret_groups = groups;
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index f99c2d1fb32..12ee3dc162e 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -45,7 +45,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
if (!ptr)
return(False);
- s = (char *)*ptr;
+ s = CONST_DISCARD(char *, *ptr);
/* default to simple separators */
if (!sep)
@@ -109,7 +109,7 @@ void set_first_token(char *ptr)
char **toktocliplist(int *ctok, const char *sep)
{
- char *s=(char *)last_ptr;
+ char *s = CONST_DISCARD(char *, last_ptr);
int ictok=0;
char **ret, **iret;
@@ -132,7 +132,7 @@ char **toktocliplist(int *ctok, const char *sep)
} while(*s);
*ctok=ictok;
- s=(char *)last_ptr;
+ s = CONST_DISCARD(char *, last_ptr);
if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
return NULL;
@@ -363,16 +363,16 @@ BOOL strisnormal(const char *s, int case_default)
NOTE: oldc and newc must be 7 bit characters
**/
-void string_replace(pstring s,char oldc,char newc)
+void string_replace( pstring s, char oldc, char newc )
{
- unsigned char *p;
+ char *p;
/* this is quite a common operation, so we want it to be
fast. We optimise for the ascii case, knowing that all our
supported multi-byte character sets are ascii-compatible
(ie. they match for the first 128 chars) */
- for (p = (unsigned char *)s; *p; p++) {
+ for (p = s; *p; p++) {
if (*p & 0x80) /* mb string - slow path. */
break;
if (*p == oldc)
@@ -799,7 +799,7 @@ DATA_BLOB strhex_to_data_blob(const char *strhex)
{
DATA_BLOB ret_blob = data_blob(NULL, strlen(strhex)/2+1);
- ret_blob.length = strhex_to_str(ret_blob.data,
+ ret_blob.length = strhex_to_str((char*)ret_blob.data,
strlen(strhex),
strhex);
@@ -826,7 +826,7 @@ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
Check if a string is part of a list.
**/
-BOOL in_list(char *s,char *list,BOOL casesensitive)
+BOOL in_list(const char *s, const char *list, BOOL casesensitive)
{
pstring tok;
const char *p=list;
@@ -1221,7 +1221,7 @@ char *strchr_m(const char *src, char c)
for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
if (*s == c)
- return (char *)s;
+ return CONST_DISCARD(char *, s);
}
if (!*s)
@@ -1238,7 +1238,7 @@ char *strchr_m(const char *src, char c)
return NULL;
*p = 0;
pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ return CONST_DISCARD(char *, (s+strlen(s2)));
}
char *strrchr_m(const char *s, char c)
@@ -1275,7 +1275,7 @@ char *strrchr_m(const char *s, char c)
break;
}
/* No - we have a match ! */
- return (char *)cp;
+ return CONST_DISCARD(char *, cp);
}
} while (cp-- != s);
if (!got_mb)
@@ -1294,7 +1294,7 @@ char *strrchr_m(const char *s, char c)
return NULL;
*p = 0;
pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ return CONST_DISCARD(char *, (s+strlen(s2)));
}
}
@@ -1315,7 +1315,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
return NULL;
*p = 0;
pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
+ return CONST_DISCARD(char *, (s+strlen(s2)));
}
/***********************************************************************
@@ -1334,7 +1334,7 @@ char *strstr_m(const char *src, const char *findstr)
/* for correctness */
if (!findstr[0]) {
- return src;
+ return CONST_DISCARD(char *, src);
}
/* Samba does single character findstr calls a *lot*. */
@@ -1351,7 +1351,7 @@ char *strstr_m(const char *src, const char *findstr)
findstr_len = strlen(findstr);
if (strncmp(s, findstr, findstr_len) == 0) {
- return (char *)s;
+ return CONST_DISCARD(char *, s);
}
}
}
@@ -1392,7 +1392,7 @@ char *strstr_m(const char *src, const char *findstr)
DEBUG(0,("strstr_m: dest malloc fail\n"));
return NULL;
}
- retp = (char *)(s+strlen(s2));
+ retp = CONST_DISCARD(char *, (s+strlen(s2)));
SAFE_FREE(src_w);
SAFE_FREE(find_w);
SAFE_FREE(s2);
@@ -1695,6 +1695,20 @@ void str_list_free(char ***list)
}
/******************************************************************************
+ *****************************************************************************/
+
+int str_list_count( const char **list )
+{
+ int i = 0;
+
+ /* count the number of list members */
+
+ for ( i=0; *list; i++, list++ );
+
+ return i;
+}
+
+/******************************************************************************
version of standard_sub_basic() for string lists; uses alloc_sub_basic()
for the work
*****************************************************************************/
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index 55a21ebcbbc..0b4552e1f5d 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -283,6 +283,19 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
}
/*******************************************************************
+ Convert a (little-endian) UNISTR3 structure to an ASCII string
+********************************************************************/
+void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen)
+{
+ if (str == NULL) {
+ *dest='\0';
+ return;
+ }
+ pull_ucs2(NULL, dest, str->str.buffer, maxlen, str->uni_str_len*2,
+ STR_NOALIGN);
+}
+
+/*******************************************************************
give a static string for displaying a UNISTR2
********************************************************************/
const char *unistr2_static(const UNISTR2 *str)
@@ -311,18 +324,6 @@ char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
/*******************************************************************
-Return a number stored in a buffer
-********************************************************************/
-
-uint32 buffer2_to_uint32(BUFFER2 *str)
-{
- if (str->buf_len == 4)
- return IVAL(str->buffer, 0);
- else
- return 0;
-}
-
-/*******************************************************************
Convert a wchar to upper case.
********************************************************************/
@@ -397,10 +398,10 @@ size_t strnlen_w(const smb_ucs2_t *src, size_t max)
smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
while (*s != 0) {
- if (c == *s) return (smb_ucs2_t *)s;
+ if (c == *s) return CONST_DISCARD(smb_ucs2_t *, s);
s++;
}
- if (c == *s) return (smb_ucs2_t *)s;
+ if (c == *s) return CONST_DISCARD(smb_ucs2_t *, s);
return NULL;
}
@@ -421,7 +422,7 @@ smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
if (len == 0) return NULL;
p += (len - 1);
do {
- if (c == *p) return (smb_ucs2_t *)p;
+ if (c == *p) return CONST_DISCARD(smb_ucs2_t *, p);
} while (p-- != s);
return NULL;
}
@@ -442,7 +443,7 @@ smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n)
n--;
if (!n)
- return (smb_ucs2_t *)p;
+ return CONST_DISCARD(smb_ucs2_t *, p);
} while (p-- != s);
return NULL;
}
@@ -460,7 +461,7 @@ smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins)
return NULL;
inslen = strlen_w(ins);
- r = (smb_ucs2_t *)s;
+ r = CONST_DISCARD(smb_ucs2_t *, s);
while ((r = strchr_w(r, *ins))) {
if (strncmp_w(r, ins, inslen) == 0)
@@ -731,7 +732,7 @@ smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p)
int i;
for (i=0; p[i] && *s != UCS2_CHAR(p[i]); i++)
;
- if (p[i]) return (smb_ucs2_t *)s;
+ if (p[i]) return CONST_DISCARD(smb_ucs2_t *, s);
s++;
}
return NULL;
@@ -746,7 +747,7 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins)
return NULL;
inslen = strlen(ins);
- r = (smb_ucs2_t *)s;
+ r = CONST_DISCARD(smb_ucs2_t *, s);
while ((r = strchr_w(r, UCS2_CHAR(*ins)))) {
if (strncmp_wa(r, ins, inslen) == 0)
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
index df70740b33c..8b8e70a36ef 100644
--- a/source/lib/util_uuid.c
+++ b/source/lib/util_uuid.c
@@ -94,7 +94,7 @@ BOOL smb_string_to_uuid(const char *in, struct uuid* uu)
{
BOOL ret = False;
const char *ptr = in;
- char *end = (char *)in;
+ char *end = CONST_DISCARD(char *, in);
int i;
unsigned v1, v2;
diff --git a/source/lib/wins_srv.c b/source/lib/wins_srv.c
index b82e04e13cc..c139f427ca8 100644
--- a/source/lib/wins_srv.c
+++ b/source/lib/wins_srv.c
@@ -22,6 +22,8 @@
#include "includes.h"
+extern struct in_addr loopback_ip;
+
/*
This is pretty much a complete rewrite of the earlier code. The main
aim of the rewrite is to add support for having multiple wins server
@@ -280,7 +282,6 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
/* if we are a wins server then we always just talk to ourselves */
if (lp_wins_support()) {
- extern struct in_addr loopback_ip;
return loopback_ip;
}
diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c
index 4c9997e080e..18820d9e312 100644
--- a/source/libads/kerberos.c
+++ b/source/libads/kerberos.c
@@ -88,7 +88,8 @@ int kerberos_kinit_password(const char *principal,
return code;
}
- if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password,
+ if ((code = krb5_get_init_creds_password(ctx, &my_creds, me,
+ CONST_DISCARD(char *, password),
kerb_prompter,
NULL, 0, NULL, NULL))) {
krb5_free_principal(ctx, me);
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 6e1b011c37c..7a59da5a6d3 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -481,15 +481,15 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
ber_printf(cookie_be, "{io}", (ber_int_t) 1000, "", 0);
}
ber_flatten(cookie_be, &cookie_bv);
- PagedResults.ldctl_oid = ADS_PAGE_CTL_OID;
+ PagedResults.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
PagedResults.ldctl_iscritical = (char) 1;
PagedResults.ldctl_value.bv_len = cookie_bv->bv_len;
PagedResults.ldctl_value.bv_val = cookie_bv->bv_val;
- NoReferrals.ldctl_oid = ADS_NO_REFERRALS_OID;
+ NoReferrals.ldctl_oid = CONST_DISCARD(char *, ADS_NO_REFERRALS_OID);
NoReferrals.ldctl_iscritical = (char) 0;
NoReferrals.ldctl_value.bv_len = 0;
- NoReferrals.ldctl_value.bv_val = "";
+ NoReferrals.ldctl_value.bv_val = CONST_DISCARD(char *, "");
controls[0] = &NoReferrals;
@@ -831,7 +831,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
need to reset it to NULL before doing ldap modify */
mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
- return mods;
+ return (ADS_MODLIST)mods;
}
@@ -868,7 +868,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
memset(&modlist[curmod], 0,
ADS_MODLIST_ALLOC_SIZE*sizeof(LDAPMod *));
modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
- *mods = modlist;
+ *mods = (ADS_MODLIST)modlist;
}
if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod)))
@@ -962,7 +962,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods)
non-existent attribute (but allowable for the object) to run
*/
LDAPControl PermitModify = {
- ADS_PERMIT_MODIFY_OID,
+ CONST_DISCARD(char *, ADS_PERMIT_MODIFY_OID),
{0, NULL},
(char) 1};
LDAPControl *controls[2];
@@ -1006,7 +1006,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
/* make sure the end of the list is NULL */
mods[i] = NULL;
- ret = ldap_add_s(ads->ld, utf8_dn, mods);
+ ret = ldap_add_s(ads->ld, utf8_dn, (LDAPMod**)mods);
SAFE_FREE(utf8_dn);
return ADS_ERROR(ret);
}
@@ -1267,7 +1267,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
ADS_STATUS ret;
TALLOC_CTX *ctx;
LDAPMessage *res = NULL;
- char *host_spn, *host_upn, *psp1, *psp2, *psp3;
+ char *host_spn, *psp1, *psp2, *psp3;
ADS_MODLIST mods;
fstring my_fqdn;
char *dn_string = NULL;
@@ -1297,11 +1297,6 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
ads_msgfree(ads, res);
return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
}
- if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) {
- talloc_destroy(ctx);
- ads_msgfree(ads, res);
- return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
- }
/* Add the extra principal */
psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name);
diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c
index 68e67358910..61275e40d11 100644
--- a/source/libads/ldap_printer.c
+++ b/source/libads/ldap_printer.c
@@ -61,8 +61,10 @@ ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
/* For the moment only display all printers */
- ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
- "(objectCategory=printQueue))";
+ ldap_expr =
+ CONST_DISCARD(char *,
+ "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
+ "(objectCategory=printQueue))");
return ads_search(ads, res, ldap_expr, attrs);
}
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
index 97ba9c92862..e657f2114e6 100644
--- a/source/libads/sasl.c
+++ b/source/libads/sasl.c
@@ -18,6 +18,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */
+
#include "includes.h"
#ifdef HAVE_LDAP
@@ -173,7 +175,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
DATA_BLOB blob;
char *principal = NULL;
char *OIDs[ASN1_MAX_OIDS];
+#ifdef HAVE_KRB5
BOOL got_kerberos_mechanism = False;
+#endif
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
@@ -202,10 +206,12 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
/* make sure the server understands kerberos */
for (i=0;OIDs[i];i++) {
DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i]));
+#ifdef HAVE_KRB5
if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
strcmp(OIDs[i], OID_KERBEROS5) == 0) {
got_kerberos_mechanism = True;
}
+#endif
free(OIDs[i]);
}
DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal));
@@ -281,7 +287,8 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
ENCTYPE_DES_CBC_MD5,
ENCTYPE_NULL};
gss_OID_desc nt_principal =
- {10, "\052\206\110\206\367\022\001\002\002\002"};
+ {10, CONST_DISCARD(char *,
+ "\052\206\110\206\367\022\001\002\002\002")};
/* we need to fetch a service ticket as the ldap user in the
servers realm, regardless of our realm */
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index dce51a2c8bb..5a9992d4e03 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -23,6 +23,7 @@
#include "includes.h"
+extern pstring user_socket_options;
static const struct {
int prot;
@@ -702,7 +703,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
char *principal;
char *OIDs[ASN1_MAX_OIDS];
int i;
+#ifdef HAVE_KRB5
BOOL got_kerberos_mechanism = False;
+#endif
DATA_BLOB blob;
DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
@@ -731,10 +734,12 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
/* make sure the server understands kerberos */
for (i=0;OIDs[i];i++) {
DEBUG(3,("got OID=%s\n", OIDs[i]));
+#ifdef HAVE_KRB5
if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
strcmp(OIDs[i], OID_KERBEROS5) == 0) {
got_kerberos_mechanism = True;
}
+#endif
free(OIDs[i]);
}
DEBUG(3,("got principal=%s\n", principal));
@@ -1196,7 +1201,6 @@ BOOL cli_session_request(struct cli_state *cli,
{
char *p;
int len = 4;
- extern pstring user_socket_options;
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
@@ -1286,7 +1290,6 @@ BOOL cli_session_request(struct cli_state *cli,
BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
- extern pstring user_socket_options;
int name_type = 0x20;
char *p;
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index b7bc780a1a1..e787650c2f5 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -22,6 +22,8 @@
#include "includes.h"
+extern int smb_read_error;
+
/****************************************************************************
Change the timeout (in milliseconds).
****************************************************************************/
@@ -81,7 +83,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
BOOL cli_receive_smb(struct cli_state *cli)
{
- extern int smb_read_error;
BOOL ret;
/* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index 9d20ed3adcd..93492ec0822 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -1071,7 +1071,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
****************************************************************************/
BOOL cli_getattrE(struct cli_state *cli, int fd,
- uint16 *attr, SMB_BIG_UINT *size,
+ uint16 *attr, SMB_OFF_T *size,
time_t *c_time, time_t *a_time, time_t *m_time)
{
memset(cli->outbuf,'\0',smb_size);
@@ -1122,7 +1122,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
****************************************************************************/
BOOL cli_getatr(struct cli_state *cli, const char *fname,
- uint16 *attr, size_t *size, time_t *t)
+ uint16 *attr, SMB_OFF_T *size, time_t *t)
{
char *p;
diff --git a/source/libsmb/clifsinfo.c b/source/libsmb/clifsinfo.c
index 22c8bff3ba0..2874ee6ca1c 100644
--- a/source/libsmb/clifsinfo.c
+++ b/source/libsmb/clifsinfo.c
@@ -132,3 +132,118 @@ cleanup:
return ret;
}
+
+BOOL cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number)
+{
+ BOOL ret = False;
+ uint16 setup;
+ char param[2];
+ char *rparam=NULL, *rdata=NULL;
+ unsigned int rparam_count=0, rdata_count=0;
+ unsigned char nlen;
+
+ setup = TRANSACT2_QFSINFO;
+
+ SSVAL(param,0,SMB_INFO_VOLUME);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL,
+ 0, 0,
+ &setup, 1, 0,
+ param, 2, 0,
+ NULL, 0, 560)) {
+ goto cleanup;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &rparam_count,
+ &rdata, &rdata_count)) {
+ goto cleanup;
+ }
+
+ if (cli_is_error(cli)) {
+ ret = False;
+ goto cleanup;
+ } else {
+ ret = True;
+ }
+
+ if (rdata_count < 5) {
+ goto cleanup;
+ }
+
+ if (pserial_number) {
+ *pserial_number = IVAL(rdata,0);
+ }
+ nlen = CVAL(rdata,l2_vol_cch);
+ clistr_pull(cli, volume_name, rdata + l2_vol_szVolLabel, sizeof(fstring), nlen, STR_NOALIGN);
+
+ /* todo: but not yet needed
+ * return the other stuff
+ */
+
+cleanup:
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return ret;
+}
+
+BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate)
+{
+ BOOL ret = False;
+ uint16 setup;
+ char param[2];
+ char *rparam=NULL, *rdata=NULL;
+ unsigned int rparam_count=0, rdata_count=0;
+ unsigned int nlen;
+
+ setup = TRANSACT2_QFSINFO;
+
+ SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL,
+ 0, 0,
+ &setup, 1, 0,
+ param, 2, 0,
+ NULL, 0, 560)) {
+ goto cleanup;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &rparam_count,
+ &rdata, &rdata_count)) {
+ goto cleanup;
+ }
+
+ if (cli_is_error(cli)) {
+ ret = False;
+ goto cleanup;
+ } else {
+ ret = True;
+ }
+
+ if (rdata_count < 19) {
+ goto cleanup;
+ }
+
+ if (pdate) {
+ *pdate = interpret_long_date(rdata);
+ }
+ if (pserial_number) {
+ *pserial_number = IVAL(rdata,8);
+ }
+ nlen = IVAL(rdata,12);
+ clistr_pull(cli, volume_name, rdata + 18, sizeof(fstring), nlen, STR_UNICODE);
+
+ /* todo: but not yet needed
+ * return the other stuff
+ */
+
+cleanup:
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return ret;
+}
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index 66c16b69aef..c35b53a9dd8 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -19,6 +19,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */
+#define KRB5_DEPRECATED 1 /* this file uses DEPRECATED interfaces! */
+
#include "includes.h"
#ifdef HAVE_KRB5
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index 0f1b9efed0e..79c2ef66a19 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -22,6 +22,8 @@
#include "includes.h"
+extern file_info def_finfo;
+
/****************************************************************************
Interpret a long filename structure - this is mostly guesses at the moment.
The length of the structure is returned
@@ -32,7 +34,6 @@
static size_t 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;
@@ -332,7 +333,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo)
{
- extern file_info def_finfo;
*finfo = def_finfo;
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index 8e6742d4380..06b683b0385 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -382,7 +382,7 @@ send a qpathinfo call
****************************************************************************/
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)
+ SMB_OFF_T *size, uint16 *mode)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
@@ -462,7 +462,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
****************************************************************************/
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,
+ time_t *w_time, SMB_OFF_T *size, uint16 *mode,
SMB_INO_T *ino)
{
unsigned int data_len = 0;
@@ -501,22 +501,22 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
}
if (c_time) {
- *c_time = interpret_long_date(rdata+0) - cli->serverzone;
+ *c_time = interpret_long_date(rdata+0);
}
if (a_time) {
- *a_time = interpret_long_date(rdata+8) - cli->serverzone;
+ *a_time = interpret_long_date(rdata+8);
}
if (m_time) {
- *m_time = interpret_long_date(rdata+16) - cli->serverzone;
+ *m_time = interpret_long_date(rdata+16);
}
if (w_time) {
- *w_time = interpret_long_date(rdata+24) - cli->serverzone;
+ *w_time = interpret_long_date(rdata+24);
}
if (mode) {
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 48);
+ *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
}
if (ino) {
*ino = IVAL(rdata, 64);
@@ -546,11 +546,11 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum,
SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO);
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 */
- NULL, data_len, cli->max_xmit /* data, length, max */
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ NULL, data_len, cli->max_xmit /* data, length, max */
)) {
return False;
}
@@ -575,7 +575,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum,
send a qfileinfo call
****************************************************************************/
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
- uint16 *mode, size_t *size,
+ uint16 *mode, SMB_OFF_T *size,
time_t *c_time, time_t *a_time, time_t *m_time,
time_t *w_time, SMB_INO_T *ino)
{
@@ -596,11 +596,11 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
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 */
- NULL, data_len, cli->max_xmit /* data, length, max */
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ NULL, data_len, cli->max_xmit /* data, length, max */
)) {
return False;
}
@@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 48);
+ *size = IVAL2_TO_SMB_BIG_UINT(rdata,48);
}
if (ino) {
*ino = IVAL(rdata, 64);
diff --git a/source/libsmb/clirap2.c b/source/libsmb/clirap2.c
index 12a3d63aff3..d8a85195502 100644
--- a/source/libsmb/clirap2.c
+++ b/source/libsmb/clirap2.c
@@ -329,6 +329,70 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char
return res;
}
+int cli_RNetGroupEnum0(struct cli_state *cli,
+ void (*fn)(const char *, void *),
+ void *state)
+{
+ char param[WORDSIZE /* api number */
+ +sizeof(RAP_NetGroupEnum_REQ) /* parm string */
+ +sizeof(RAP_GROUP_INFO_L0) /* return string */
+ +WORDSIZE /* info level */
+ +WORDSIZE]; /* buffer size */
+ char *p;
+ char *rparam = NULL;
+ char *rdata = NULL;
+ unsigned int rprcnt, rdrcnt;
+ int res = -1;
+
+
+ memset(param, '\0', sizeof(param));
+ p = make_header(param, RAP_WGroupEnum,
+ RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0);
+ PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this
+ is the resume count, at least
+ that's what smbd believes... */
+ PUTWORD(p,0xFFE0); /* Return buffer size */
+
+ if (cli_api(cli,
+ param, PTR_DIFF(p,param),8,
+ NULL, 0, 0xFFE0 /* data area size */,
+ &rparam, &rprcnt,
+ &rdata, &rdrcnt)) {
+ res = GETRES(rparam);
+ cli->rap_error = res;
+ if(cli->rap_error == 234)
+ DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
+ else if (cli->rap_error != 0) {
+ DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
+ }
+ }
+
+ if (rdata) {
+ if (res == 0 || res == ERRmoredata) {
+ int i, converter, count;
+
+ p = rparam + WORDSIZE; /* skip result */
+ GETWORD(p, converter);
+ GETWORD(p, count);
+
+ for (i=0,p=rdata;i<count;i++) {
+ char groupname[RAP_GROUPNAME_LEN];
+ GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
+ fn(groupname, cli);
+ }
+ } else {
+ DEBUG(4,("NetGroupEnum res=%d\n", res));
+ }
+ } else {
+ DEBUG(4,("NetGroupEnum no data returned\n"));
+ }
+
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return res;
+}
+
int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
{
char *rparam = NULL;
@@ -768,6 +832,66 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char
return res;
}
+int cli_RNetUserEnum0(struct cli_state *cli,
+ void (*fn)(const char *, void *),
+ void *state)
+{
+ char param[WORDSIZE /* api number */
+ +sizeof(RAP_NetUserEnum_REQ) /* parm string */
+ +sizeof(RAP_USER_INFO_L0) /* return string */
+ +WORDSIZE /* info level */
+ +WORDSIZE]; /* buffer size */
+ char *p;
+ char *rparam = NULL;
+ char *rdata = NULL;
+ unsigned int rprcnt, rdrcnt;
+ int res = -1;
+
+
+ memset(param, '\0', sizeof(param));
+ p = make_header(param, RAP_WUserEnum,
+ RAP_NetUserEnum_REQ, RAP_USER_INFO_L0);
+ PUTWORD(p,0); /* Info level 1 */
+ PUTWORD(p,0xFF00); /* Return buffer size */
+
+/* BB Fix handling of large numbers of users to be returned */
+ if (cli_api(cli,
+ param, PTR_DIFF(p,param),8,
+ NULL, 0, CLI_BUFFER_SIZE,
+ &rparam, &rprcnt,
+ &rdata, &rdrcnt)) {
+ res = GETRES(rparam);
+ cli->rap_error = res;
+ if (cli->rap_error != 0) {
+ DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
+ }
+ }
+ if (rdata) {
+ if (res == 0 || res == ERRmoredata) {
+ int i, converter, count;
+ char username[RAP_USERNAME_LEN];
+
+ p = rparam + WORDSIZE; /* skip result */
+ GETWORD(p, converter);
+ GETWORD(p, count);
+
+ for (i=0,p=rdata;i<count;i++) {
+ GETSTRINGF(p, username, RAP_USERNAME_LEN);
+ fn(username, cli);
+ }
+ } else {
+ DEBUG(4,("NetUserEnum res=%d\n", res));
+ }
+ } else {
+ DEBUG(4,("NetUserEnum no data returned\n"));
+ }
+
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return res;
+}
+
/****************************************************************************
call a NetFileClose2 - close open file on another session to server
****************************************************************************/
diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c
index 85b7bd9e1ee..5d07999bc3a 100644
--- a/source/libsmb/clispnego.c
+++ b/source/libsmb/clispnego.c
@@ -338,7 +338,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset,
return retval;
/* wrap that up in a nice GSS-API wrapping */
- tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
+ tkt_wrapped = spnego_gen_krb5_wrap(
+ tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ));
/* and wrap that in a shiny SPNEGO wrapper */
*targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);
diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c
index 96c052c7c56..0dca2653483 100644
--- a/source/libsmb/doserr.c
+++ b/source/libsmb/doserr.c
@@ -31,6 +31,7 @@ typedef const struct
werror_code_struct dos_errs[] =
{
{ "WERR_OK", WERR_OK },
+ { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE },
{ "WERR_BADFILE", WERR_BADFILE },
{ "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED },
{ "WERR_BADFID", WERR_BADFID },
@@ -69,6 +70,7 @@ werror_code_struct dos_errs[] =
{ "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
{ "WERR_IO_PENDING", WERR_IO_PENDING },
+ { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL },
{ NULL, W_ERROR(0) }
};
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 3761074e04f..3e8e604ab11 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -80,6 +80,9 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
return False;
}
+static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file);
+static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence);
+
extern BOOL in_client;
/*
@@ -555,6 +558,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
int tried_reverse = 0;
int port_try_first;
int port_try_next;
+ const char *username_used;
zero_ip(&ip);
ZERO_STRUCT(c);
@@ -709,16 +713,26 @@ SMBCSRV *smbc_server(SMBCCTX *context,
return NULL;
}
- if (!cli_session_setup(&c, username,
+ username_used = username;
+
+ if (!cli_session_setup(&c, username_used,
password, strlen(password),
password, strlen(password),
- workgroup) &&
- /* Try an anonymous login if it failed and this was allowed by flags. */
- ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
- !cli_session_setup(&c, "", "", 1,"", 0, workgroup))) {
- cli_shutdown(&c);
- errno = EPERM;
- return NULL;
+ workgroup)) {
+
+ /* Failed. Try an anonymous login, if allowed by flags. */
+ username_used = "";
+
+ if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
+ !cli_session_setup(&c, username_used,
+ password, 1,
+ password, 0,
+ workgroup)) {
+
+ cli_shutdown(&c);
+ errno = EPERM;
+ return NULL;
+ }
}
DEBUG(4,(" session setup ok\n"));
@@ -750,7 +764,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
/* now add it to the cache (internal or external) */
/* Let the cache function set errno if it wants to */
errno = 0;
- if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) {
+ if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) {
int saved_errno = errno;
DEBUG(3, (" Failed to add server to cache\n"));
errno = saved_errno;
@@ -968,6 +982,37 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m
file->file = True;
DLIST_ADD(context->internal->_files, file);
+
+ /*
+ * If the file was opened in O_APPEND mode, all write
+ * operations should be appended to the file. To do that,
+ * though, using this protocol, would require a getattrE()
+ * call for each and every write, to determine where the end
+ * of the file is. (There does not appear to be an append flag
+ * in the protocol.) Rather than add all of that overhead of
+ * retrieving the current end-of-file offset prior to each
+ * write operation, we'll assume that most append operations
+ * will continuously write, so we'll just set the offset to
+ * the end of the file now and hope that's adequate.
+ *
+ * Note to self: If this proves inadequate, and O_APPEND
+ * should, in some cases, be forced for each write, add a
+ * field in the context options structure, for
+ * "strict_append_mode" which would select between the current
+ * behavior (if FALSE) or issuing a getattrE() prior to each
+ * write and forcing the write to the end of the file (if
+ * TRUE). Adding that capability will likely require adding
+ * an "append" flag into the _SMBCFILE structure to track
+ * whether a file was opened in O_APPEND mode. -- djl
+ */
+ if (flags & O_APPEND) {
+ if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) {
+ (void) smbc_close_ctx(context, file);
+ errno = ENXIO;
+ return NULL;
+ }
+ }
+
return file;
}
@@ -1017,6 +1062,17 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
{
int ret;
+ /*
+ * offset:
+ *
+ * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) --
+ * appears to pass file->offset (which is type off_t) differently than
+ * a local variable of type off_t. Using local variable "offset" in
+ * the call to cli_read() instead of file->offset fixes a problem
+ * retrieving data at an offset greater than 4GB.
+ */
+ off_t offset = file->offset;
+
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -1043,7 +1099,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
}
- ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count);
+ ret = cli_read(&file->srv->cli, file->cli_fd, buf, offset, count);
if (ret < 0) {
@@ -1067,6 +1123,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t
static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
{
int ret;
+ off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -1092,7 +1149,7 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_
}
- ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count);
+ ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, offset, count);
if (ret <= 0) {
@@ -1165,7 +1222,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file)
* and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
*/
static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path,
- uint16 *mode, size_t *size,
+ uint16 *mode, SMB_OFF_T *size,
time_t *c_time, time_t *a_time, time_t *m_time,
SMB_INO_T *ino)
{
@@ -1272,7 +1329,7 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
if (errno == EACCES) { /* Check if the file is a directory */
int saverr = errno;
- size_t size = 0;
+ SMB_OFF_T size = 0;
uint16 mode = 0;
time_t m_time = 0, a_time = 0, c_time = 0;
SMB_INO_T ino = 0;
@@ -1396,7 +1453,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence)
{
- size_t size;
+ SMB_OFF_T size;
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -1482,7 +1539,8 @@ ino_t smbc_inode(SMBCCTX *context, const char *name)
*/
static
-int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode)
+int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname,
+ SMB_OFF_T size, int mode)
{
st->st_mode = 0;
@@ -1532,7 +1590,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
fstring server, share, user, password, workgroup;
pstring path;
time_t m_time = 0, a_time = 0, c_time = 0;
- size_t size = 0;
+ SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T ino = 0;
@@ -1602,7 +1660,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
{
time_t c_time, a_time, m_time;
- size_t size;
+ SMB_OFF_T size;
uint16 mode;
SMB_INO_T ino = 0;
@@ -1629,15 +1687,12 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
if (!cli_qfileinfo(&file->srv->cli, file->cli_fd,
&mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) {
- SMB_BIG_UINT b_size = size;
if (!cli_getattrE(&file->srv->cli, file->cli_fd,
- &mode, &b_size, &c_time, &a_time, &m_time)) {
+ &mode, &size, &c_time, &a_time, &m_time)) {
errno = EINVAL;
return -1;
- } else
- size = b_size;
-
+ }
}
st->st_ino = ino;
@@ -1960,7 +2015,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
}
for (i = 0; i < count && i < max_lmb_count; i++) {
- DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
+ DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip)));
cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info);
/* cli == NULL is the master browser refused to talk or
@@ -1983,12 +2038,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
srv = smbc_server(context, server,
"IPC$", workgroup, user, password);
if (!srv) {
-
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
+ continue;
}
dir->srv = srv;
@@ -1999,13 +2049,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn,
(void *)dir)) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
-
- return NULL;
-
+ continue;
}
}
} else {
@@ -3233,7 +3277,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
SMBCSRV *srv)
{
time_t m_time = 0, a_time = 0, c_time = 0;
- size_t size = 0;
+ SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T inode = 0;
DOS_ATTR_DESC *ret;
@@ -3245,7 +3289,8 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
}
/* Obtain the DOS attributes */
- if (!smbc_getatr(context, srv, filename, &mode, &size,
+ if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename),
+ &mode, &size,
&c_time, &a_time, &m_time, &inode)) {
errno = smbc_errno(context, &srv->cli);
@@ -3314,42 +3359,124 @@ retrieve the acls for a file
*******************************************************/
static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
struct cli_state *ipc_cli, POLICY_HND *pol,
- char *filename, char *name, char *buf, int bufsize)
+ char *filename, char *attr_name, char *buf, int bufsize)
{
uint32 i;
int n = 0;
int n_used;
BOOL all;
BOOL all_nt;
+ BOOL all_nt_acls;
BOOL all_dos;
BOOL some_nt;
BOOL some_dos;
+ BOOL exclude_nt_revision = False;
+ BOOL exclude_nt_owner = False;
+ BOOL exclude_nt_group = False;
+ BOOL exclude_nt_acl = False;
+ BOOL exclude_dos_mode = False;
+ BOOL exclude_dos_size = False;
+ BOOL exclude_dos_ctime = False;
+ BOOL exclude_dos_atime = False;
+ BOOL exclude_dos_mtime = False;
+ BOOL exclude_dos_inode = False;
BOOL numeric = True;
BOOL determine_size = (bufsize == 0);
int fnum = -1;
SEC_DESC *sd;
fstring sidstr;
+ fstring name_sandbox;
+ char *name;
+ char *pExclude;
char *p;
time_t m_time = 0, a_time = 0, c_time = 0;
- size_t size = 0;
+ SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T ino = 0;
struct cli_state *cli = &srv->cli;
+ /* Copy name so we can strip off exclusions (if any are specified) */
+ strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1);
+
+ /* Ensure name is null terminated */
+ name_sandbox[sizeof(name_sandbox) - 1] = '\0';
+
+ /* Play in the sandbox */
+ name = name_sandbox;
+
+ /* If there are any exclusions, point to them and mask them from name */
+ if ((pExclude = strchr(name, '!')) != NULL)
+ {
+ *pExclude++ = '\0';
+ }
+
all = (StrnCaseCmp(name, "system.*", 8) == 0);
all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0);
+ all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0);
all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0);
some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0);
some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0);
numeric = (* (name + strlen(name) - 1) != '+');
+ /* Look for exclusions from "all" requests */
+ if (all || all_nt || all_dos) {
+
+ /* Exclusions are delimited by '!' */
+ for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) {
+
+ /* Find end of this exclusion name */
+ if ((p = strchr(pExclude, '!')) != NULL)
+ {
+ *p = '\0';
+ }
+
+ /* Which exclusion name is this? */
+ if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) {
+ exclude_nt_revision = True;
+ }
+ else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) {
+ exclude_nt_owner = True;
+ }
+ else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) {
+ exclude_nt_group = True;
+ }
+ else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) {
+ exclude_nt_acl = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) {
+ exclude_dos_mode = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) {
+ exclude_dos_size = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.c_time") == 0) {
+ exclude_dos_ctime = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.a_time") == 0) {
+ exclude_dos_atime = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.m_time") == 0) {
+ exclude_dos_mtime = True;
+ }
+ else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) {
+ exclude_dos_inode = True;
+ }
+ else {
+ DEBUG(5, ("cacl_get received unknown exclusion: %s\n",
+ pExclude));
+ errno = ENOATTR;
+ return -1;
+ }
+ }
+ }
+
n_used = 0;
/*
* If we are (possibly) talking to an NT or new system and some NT
* attributes have been requested...
*/
- if (ipc_cli && (all || some_nt)) {
+ if (ipc_cli && (all || some_nt || all_nt_acls)) {
/* Point to the portion after "system.nt_sec_desc." */
name += 19; /* if (all) this will be invalid but unused */
@@ -3374,139 +3501,105 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
cli_close(cli, fnum);
- if (all || all_nt) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "REVISION:%d",
- sd->revision);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ if (! exclude_nt_revision) {
+ if (all || all_nt) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ "REVISION:%d",
+ sd->revision);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "REVISION:%d", sd->revision);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "REVISION:%d", sd->revision);
- }
- } else if (StrCaseCmp(name, "revision") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%d", sd->revision);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "revision") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%d",
+ sd->revision);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%d",
+ sd->revision);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%d", sd->revision);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
-
- /* Get owner and group sid */
-
- if (sd->owner_sid) {
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, sd->owner_sid);
- } else {
- fstrcpy(sidstr, "");
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- if (all || all_nt) {
- if (determine_size) {
- p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",OWNER:%s", sidstr);
- }
- } else if (StrnCaseCmp(name, "owner", 5) == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
- }
- n = strlen(p);
+ if (! exclude_nt_owner) {
+ /* Get owner and group sid */
+ if (sd->owner_sid) {
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr,
+ numeric,
+ sd->owner_sid);
} else {
- n = snprintf(buf, bufsize, "%s", sidstr);
+ fstrcpy(sidstr, "");
}
- }
-
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
- }
- buf += n;
- n_used += n;
- bufsize -= n;
- if (sd->grp_sid) {
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, sd->grp_sid);
- } else {
- fstrcpy(sidstr, "");
- }
-
- if (all || all_nt) {
- if (determine_size) {
- p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ if (all || all_nt) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, ",OWNER:%s",
+ sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",OWNER:%s", sidstr);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",GROUP:%s", sidstr);
- }
- } else if (StrnCaseCmp(name, "group", 5) == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%s", sidstr);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrnCaseCmp(name, "owner", 5) == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%s", sidstr);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%s",
+ sidstr);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%s", sidstr);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- /* Add aces to value buffer */
- for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- SEC_ACE *ace = &sd->dacl->ace[i];
- convert_sid_to_string(ipc_cli, pol,
- sidstr, numeric, &ace->trustee);
+ if (! exclude_nt_group) {
+ if (sd->grp_sid) {
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr, numeric,
+ sd->grp_sid);
+ } else {
+ fstrcpy(sidstr, "");
+ }
if (all || all_nt) {
if (determine_size) {
- p = talloc_asprintf(ctx,
- ",ACL:"
- "%s:%d/%d/0x%08x",
- sidstr,
- ace->type,
- ace->flags,
- ace->info.mask);
+ p = talloc_asprintf(ctx, ",GROUP:%s",
+ sidstr);
if (!p) {
errno = ENOMEM;
return -1;
@@ -3514,36 +3607,22 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
n = strlen(p);
} else {
n = snprintf(buf, bufsize,
- ",ACL:%s:%d/%d/0x%08x",
- sidstr,
- ace->type,
- ace->flags,
- ace->info.mask);
+ ",GROUP:%s", sidstr);
}
- } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
- StrCaseCmp(name + 3, sidstr) == 0) ||
- (StrnCaseCmp(name, "acl+", 4) == 0 &&
- StrCaseCmp(name + 4, sidstr) == 0)) {
+ } else if (StrnCaseCmp(name, "group", 5) == 0) {
if (determine_size) {
- p = talloc_asprintf(ctx,
- "%d/%d/0x%08x",
- ace->type,
- ace->flags,
- ace->info.mask);
+ p = talloc_asprintf(ctx, "%s", sidstr);
if (!p) {
errno = ENOMEM;
return -1;
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "%d/%d/0x%08x",
- ace->type,
- ace->flags,
- ace->info.mask);
+ n = snprintf(buf, bufsize, "%s", sidstr);
}
}
- if (n > bufsize) {
+
+ if (!determine_size && n > bufsize) {
errno = ERANGE;
return -1;
}
@@ -3552,6 +3631,97 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
bufsize -= n;
}
+ if (! exclude_nt_acl) {
+ /* Add aces to value buffer */
+ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+
+ SEC_ACE *ace = &sd->dacl->ace[i];
+ convert_sid_to_string(ipc_cli, pol,
+ sidstr, numeric,
+ &ace->trustee);
+
+ if (all || all_nt) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ ",ACL:"
+ "%s:%d/%d/0x%08x",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(
+ buf, bufsize,
+ ",ACL:%s:%d/%d/0x%08x",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ }
+ } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
+ StrCaseCmp(name + 3, sidstr) == 0) ||
+ (StrnCaseCmp(name, "acl+", 4) == 0 &&
+ StrCaseCmp(name + 4, sidstr) == 0)) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ "%d/%d/0x%08x",
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%d/%d/0x%08x",
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ }
+ } else if (all_nt_acls) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ "%s%s:%d/%d/0x%08x",
+ i ? "," : "",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%s%s:%d/%d/0x%08x",
+ i ? "," : "",
+ sidstr,
+ ace->type,
+ ace->flags,
+ ace->info.mask);
+ }
+ }
+ if (n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
+ }
+ }
+
/* Restore name pointer to its original value */
name -= 19;
}
@@ -3569,231 +3739,250 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
}
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "%sMODE:0x%x",
- (ipc_cli &&
- (all || some_nt)
- ? ","
- : ""),
- mode);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ if (! exclude_dos_mode) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ "%sMODE:0x%x",
+ (ipc_cli &&
+ (all || some_nt)
+ ? ","
+ : ""),
+ mode);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%sMODE:0x%x",
+ (ipc_cli &&
+ (all || some_nt)
+ ? ","
+ : ""),
+ mode);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "%sMODE:0x%x",
- (ipc_cli &&
- (all || some_nt)
- ? ","
- : ""),
- mode);
- }
- } else if (StrCaseCmp(name, "mode") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "0x%x", mode);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "mode") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "0x%x", mode);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "0x%x", mode);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "0x%x", mode);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",SIZE:%llu",
- (unsigned long long) size);
- if (!p) {
- errno = ENOMEM;
- return -1;
+
+ if (! exclude_dos_size) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ ",SIZE:%llu",
+ (unsigned long long) size);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",SIZE:%llu",
+ (unsigned long long) size);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",SIZE:%llu",
- (unsigned long long) size);
- }
- } else if (StrCaseCmp(name, "size") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "%llu",
- (unsigned long long) size);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "size") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ "%llu",
+ (unsigned long long) size);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%llu",
+ (unsigned long long) size);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "%llu",
- (unsigned long long) size);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",C_TIME:%lu", c_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+
+ if (! exclude_dos_ctime) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ ",C_TIME:%lu",
+ c_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",C_TIME:%lu", c_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",C_TIME:%lu", c_time);
- }
- } else if (StrCaseCmp(name, "c_time") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%lu", c_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "c_time") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%lu", c_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%lu", c_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%lu", c_time);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",A_TIME:%lu", a_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+
+ if (! exclude_dos_atime) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ ",A_TIME:%lu",
+ a_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",A_TIME:%lu", a_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",A_TIME:%lu", a_time);
- }
- } else if (StrCaseCmp(name, "a_time") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%lu", a_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "a_time") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%lu", a_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%lu", a_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%lu", a_time);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",M_TIME:%lu", m_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+
+ if (! exclude_dos_mtime) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx,
+ ",M_TIME:%lu",
+ m_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",M_TIME:%lu", m_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",M_TIME:%lu", m_time);
- }
- } else if (StrCaseCmp(name, "m_time") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx, "%lu", m_time);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "m_time") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(ctx, "%lu", m_time);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize, "%lu", m_time);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize, "%lu", m_time);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
-
- if (all || all_dos) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- ",INODE:%llu",
- (unsigned long long) ino);
- if (!p) {
- errno = ENOMEM;
- return -1;
+
+ if (! exclude_dos_inode) {
+ if (all || all_dos) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ ",INODE:%llu",
+ (unsigned long long) ino);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ ",INODE:%llu",
+ (unsigned long long) ino);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- ",INODE:%llu",
- (unsigned long long) ino);
- }
- } else if (StrCaseCmp(name, "inode") == 0) {
- if (determine_size) {
- p = talloc_asprintf(ctx,
- "%llu",
- (unsigned long long) ino);
- if (!p) {
- errno = ENOMEM;
- return -1;
+ } else if (StrCaseCmp(name, "inode") == 0) {
+ if (determine_size) {
+ p = talloc_asprintf(
+ ctx,
+ "%llu",
+ (unsigned long long) ino);
+ if (!p) {
+ errno = ENOMEM;
+ return -1;
+ }
+ n = strlen(p);
+ } else {
+ n = snprintf(buf, bufsize,
+ "%llu",
+ (unsigned long long) ino);
}
- n = strlen(p);
- } else {
- n = snprintf(buf, bufsize,
- "%llu",
- (unsigned long long) ino);
}
- }
- if (!determine_size && n > bufsize) {
- errno = ERANGE;
- return -1;
+ if (!determine_size && n > bufsize) {
+ errno = ERANGE;
+ return -1;
+ }
+ buf += n;
+ n_used += n;
+ bufsize -= n;
}
- buf += n;
- n_used += n;
- bufsize -= n;
/* Restore name pointer to its original value */
name -= 16;
@@ -3840,7 +4029,8 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
the_acl = p + 1;
}
- sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl);
+ sd = sec_desc_parse(ctx, ipc_cli, pol, numeric,
+ CONST_DISCARD(char *, the_acl));
if (!sd) {
errno = EINVAL;
@@ -4347,9 +4537,13 @@ int smbc_getxattr_ctx(SMBCCTX *context,
/* Are they requesting a supported attribute? */
if (StrCaseCmp(name, "system.*") == 0 ||
+ StrnCaseCmp(name, "system.*!", 9) == 0 ||
StrCaseCmp(name, "system.*+") == 0 ||
+ StrnCaseCmp(name, "system.*+!", 10) == 0 ||
StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 ||
StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
+ StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 ||
StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 ||
@@ -4358,6 +4552,7 @@ int smbc_getxattr_ctx(SMBCCTX *context,
StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 ||
StrCaseCmp(name, "system.dos_attr.*") == 0 ||
+ StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 ||
StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
StrCaseCmp(name, "system.dos_attr.size") == 0 ||
StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
@@ -4368,7 +4563,9 @@ int smbc_getxattr_ctx(SMBCCTX *context,
/* Yup. */
ret = cacl_get(context, ctx, srv,
ipc_srv == NULL ? NULL : &ipc_srv->cli,
- &pol, path, name, (const char *) value, size);
+ &pol, path,
+ CONST_DISCARD(char *, name),
+ CONST_DISCARD(char *, value), size);
if (ret < 0 && errno == 0) {
errno = smbc_errno(context, &srv->cli);
}
@@ -4507,6 +4704,7 @@ int smbc_listxattr_ctx(SMBCCTX *context,
"system.nt_sec_desc.owner+\0"
"system.nt_sec_desc.group\0"
"system.nt_sec_desc.group+\0"
+ "system.nt_sec_desc.acl.*\0"
"system.nt_sec_desc.acl\0"
"system.nt_sec_desc.acl+\0"
"system.nt_sec_desc.*\0"
@@ -4982,10 +5180,25 @@ SMBCCTX * smbc_init_context(SMBCCTX * context)
* defaults ...
*/
- if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- DEBUG(5, ("Could not load either config file: %s or %s\n",
- conf, dyn_CONFIGFILE));
- }
+ if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
+ DEBUG(5, ("Could not load either config file: "
+ "%s or %s\n",
+ conf, dyn_CONFIGFILE));
+ } else {
+ /*
+ * We loaded the global config file. Now lets
+ * load user-specific modifications to the
+ * global config.
+ */
+ slprintf(conf, sizeof(conf),
+ "%s/.smb/smb.conf.append", home);
+ if (!lp_load(conf, True, False, False)) {
+ DEBUG(10,
+ ("Could not append config file: "
+ "%s\n",
+ conf));
+ }
+ }
}
reopen_logs(); /* Get logging working ... */
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 1c93f7b1e2b..164f85be7bf 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -21,6 +21,9 @@
#include "includes.h"
+extern struct in_addr lastip;
+extern int lastport;
+
int num_good_sends = 0;
int num_good_receives = 0;
@@ -692,8 +695,6 @@ void free_packet(struct packet_struct *packet)
struct packet_struct *parse_packet(char *buf,int length,
enum packet_type packet_type)
{
- extern struct in_addr lastip;
- extern int lastport;
struct packet_struct *p;
BOOL ok=False;
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index 500ff7cc6e2..f0f2024e7b9 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -255,7 +255,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
const size_t offset_end_of_sig = (smb_ss_field + 8);
unsigned char sequence_buf[8];
struct MD5Context md5_ctx;
+#if 0
+ /* JRA - apparently this is incorrect. */
unsigned char key_buf[16];
+#endif
/*
* Firstly put the sequence number into the first 4 bytes.
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index d4b05574118..55e06ffe972 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -513,7 +513,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
*new_pw_len is the length in bytes of the possibly mulitbyte
returned password including termination.
************************************************************/
-BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
+BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
int new_pwrd_size, uint32 *new_pw_len,
int string_flags)
{
diff --git a/source/libsmb/spnego.c b/source/libsmb/spnego.c
index a0f5565d4f3..0387e8f67d8 100644
--- a/source/libsmb/spnego.c
+++ b/source/libsmb/spnego.c
@@ -42,12 +42,14 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
asn1_start_tag(asn1, ASN1_CONTEXT(0));
asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- token->mechTypes = SMB_MALLOC_P(char *);
+ token->mechTypes = SMB_MALLOC_P(const char *);
for (i = 0; !asn1->has_error &&
0 < asn1_tag_remaining(asn1); i++) {
token->mechTypes =
- SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2);
- asn1_read_OID(asn1, token->mechTypes + i);
+ SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2);
+ asn1_read_OID(asn1,
+ CONST_DISCARD(char **,
+ (token->mechTypes + i)));
}
token->mechTypes[i] = NULL;
@@ -182,7 +184,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
break;
case ASN1_CONTEXT(1):
asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_OID(asn1, &token->supportedMech);
+ asn1_read_OID(asn1, CONST_DISCARD(char **, &token->supportedMech));
asn1_end_tag(asn1);
break;
case ASN1_CONTEXT(2):
@@ -317,7 +319,8 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego)
if (spnego->negTokenInit.mechTypes) {
int i;
for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) {
- free(spnego->negTokenInit.mechTypes[i]);
+ free(CONST_DISCARD(void *,
+ spnego->negTokenInit.mechTypes[i]));
}
free(spnego->negTokenInit.mechTypes);
}
@@ -326,7 +329,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego)
break;
case SPNEGO_NEG_TOKEN_TARG:
if (spnego->negTokenTarg.supportedMech) {
- free(spnego->negTokenTarg.supportedMech);
+ free(CONST_DISCARD(void *, spnego->negTokenTarg.supportedMech));
}
data_blob_free(&spnego->negTokenTarg.responseToken);
data_blob_free(&spnego->negTokenTarg.mechListMIC);
diff --git a/source/modules/getdate.c b/source/modules/getdate.c
index 491c51294e9..2ce07f898ca 100644
--- a/source/modules/getdate.c
+++ b/source/modules/getdate.c
@@ -120,11 +120,10 @@
the right thing about local DST. Unlike previous versions, this
version is reentrant. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# endif
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
#endif
/* Since the code of getdate.y is not included in the Emacs executable
diff --git a/source/modules/getdate.y b/source/modules/getdate.y
index aab37f4d235..ecae7311ac8 100644
--- a/source/modules/getdate.y
+++ b/source/modules/getdate.y
@@ -25,11 +25,10 @@
the right thing about local DST. Unlike previous versions, this
version is reentrant. */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-# ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-# endif
+#include <config.h>
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
#endif
/* Since the code of getdate.y is not included in the Emacs executable
diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c
new file mode 100644
index 00000000000..f77739b23a4
--- /dev/null
+++ b/source/modules/vfs_catia.c
@@ -0,0 +1,317 @@
+/*
+ * Catia VFS module
+ *
+ * Implement a fixed mapping of forbidden NT characters in filenames that are
+ * used a lot by the CAD package Catia.
+ *
+ * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
+ * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
+ * under Windows...
+ *
+ * Copyright (C) Volker Lendecke, 2005
+ *
+ * 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 "includes.h"
+
+static void catia_string_replace(char *s, unsigned char oldc, unsigned
+ char newc)
+{
+ static smb_ucs2_t tmpbuf[sizeof(pstring)];
+ smb_ucs2_t *ptr = tmpbuf;
+ smb_ucs2_t old = oldc;
+
+ push_ucs2(NULL, tmpbuf, s, sizeof(tmpbuf), STR_TERMINATE);
+
+ for (;*ptr;ptr++)
+ if (*ptr==old) *ptr=newc;
+
+ pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+}
+
+static void from_unix(char *s)
+{
+ catia_string_replace(s, '\x22', '\xa8');
+ catia_string_replace(s, '\x2a', '\xa4');
+ catia_string_replace(s, '\x2f', '\xf8');
+ catia_string_replace(s, '\x3a', '\xf7');
+ catia_string_replace(s, '\x3c', '\xab');
+ catia_string_replace(s, '\x3e', '\xbb');
+ catia_string_replace(s, '\x3f', '\xbf');
+ catia_string_replace(s, '\x5c', '\xff');
+ catia_string_replace(s, '\x7c', '\xa6');
+ catia_string_replace(s, ' ', '\xb1');
+}
+
+static void to_unix(char *s)
+{
+ catia_string_replace(s, '\xa8', '\x22');
+ catia_string_replace(s, '\xa4', '\x2a');
+ catia_string_replace(s, '\xf8', '\x2f');
+ catia_string_replace(s, '\xf7', '\x3a');
+ catia_string_replace(s, '\xab', '\x3c');
+ catia_string_replace(s, '\xbb', '\x3e');
+ catia_string_replace(s, '\xbf', '\x3f');
+ catia_string_replace(s, '\xff', '\x5c');
+ catia_string_replace(s, '\xa6', '\x7c');
+ catia_string_replace(s, '\xb1', ' ');
+}
+
+static DIR *catia_opendir(vfs_handle_struct *handle, connection_struct
+ *conn, const char *fname)
+{
+ pstring name;
+ pstrcpy(name, fname);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_OPENDIR(handle, conn, name);
+}
+
+static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
+ connection_struct *conn, DIR *dirp)
+{
+ SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
+
+ if (result == NULL)
+ return result;
+
+ from_unix(result->d_name);
+ return result;
+}
+
+static int catia_open(vfs_handle_struct *handle, connection_struct *conn,
+ const char *fname, int flags, mode_t mode)
+{
+ pstring name;
+
+ pstrcpy(name, fname);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_OPEN(handle, conn, name, flags, mode);
+}
+
+static int catia_rename(vfs_handle_struct *handle, connection_struct *conn,
+ const char *old, const char *new)
+{
+ pstring oname, nname;
+
+ pstrcpy(oname, old);
+ to_unix(oname);
+ pstrcpy(nname, new);
+ to_unix(nname);
+
+ DEBUG(10, ("converted old name: %s\n", oname));
+ DEBUG(10, ("converted new name: %s\n", nname));
+
+ return SMB_VFS_NEXT_RENAME(handle, conn, oname, nname);
+}
+
+static int catia_stat(vfs_handle_struct *handle, connection_struct *conn,
+ const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ pstring name;
+ pstrcpy(name, fname);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_STAT(handle, conn, name, sbuf);
+}
+
+static int catia_lstat(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, SMB_STRUCT_STAT *sbuf)
+{
+ pstring name;
+ pstrcpy(name, path);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_LSTAT(handle, conn, name, sbuf);
+}
+
+static int catia_unlink(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path)
+{
+ pstring name;
+ pstrcpy(name, path);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_UNLINK(handle, conn, name);
+}
+
+static int catia_chmod(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, mode_t mode)
+{
+ pstring name;
+ pstrcpy(name, path);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_CHMOD(handle, conn, name, mode);
+}
+
+static int catia_chown(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, uid_t uid, gid_t gid)
+{
+ pstring name;
+ pstrcpy(name, path);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_CHOWN(handle, conn, name, uid, gid);
+}
+
+static int catia_chdir(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path)
+{
+ pstring name;
+ pstrcpy(name, path);
+ to_unix(name);
+
+ return SMB_VFS_NEXT_CHDIR(handle, conn, name);
+}
+
+static char *catia_getwd(vfs_handle_struct *handle, connection_struct *conn,
+ char *buf)
+{
+ return SMB_VFS_NEXT_GETWD(handle, conn, buf);
+}
+
+static int catia_utime(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, struct utimbuf *times)
+{
+ return SMB_VFS_NEXT_UTIME(handle, conn, path, times);
+}
+
+static BOOL catia_symlink(vfs_handle_struct *handle, connection_struct *conn,
+ const char *oldpath, const char *newpath)
+{
+ return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
+}
+
+static BOOL catia_readlink(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, char *buf, size_t bufsiz)
+{
+ return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
+}
+
+static int catia_link(vfs_handle_struct *handle, connection_struct *conn,
+ const char *oldpath, const char *newpath)
+{
+ return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
+}
+
+static int catia_mknod(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, mode_t mode, SMB_DEV_T dev)
+{
+ return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev);
+}
+
+static char *catia_realpath(vfs_handle_struct *handle, connection_struct *conn,
+ const char *path, char *resolved_path)
+{
+ return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
+}
+
+static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ const char *name, uint32 security_info,
+ struct security_descriptor_info **ppdesc)
+{
+ return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info,
+ ppdesc);
+}
+
+static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ const char *name, uint32 security_info_sent,
+ struct security_descriptor_info *psd)
+{
+ return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent,
+ psd);
+}
+
+static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
+ const char *name, mode_t mode)
+{
+ /* If the underlying VFS doesn't have ACL support... */
+ if (!handle->vfs_next.ops.chmod_acl) {
+ errno = ENOSYS;
+ return -1;
+ }
+ return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode);
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple catia_op_tuples[] = {
+
+ /* Directory operations */
+
+ {SMB_VFS_OP(catia_opendir), SMB_VFS_OP_OPENDIR,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_readdir), SMB_VFS_OP_READDIR,
+SMB_VFS_LAYER_TRANSPARENT},
+
+ /* File operations */
+
+ {SMB_VFS_OP(catia_open), SMB_VFS_OP_OPEN,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_stat), SMB_VFS_OP_STAT,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_lstat), SMB_VFS_OP_LSTAT,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_unlink), SMB_VFS_OP_UNLINK,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_chmod), SMB_VFS_OP_CHMOD,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_chown), SMB_VFS_OP_CHOWN,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_chdir), SMB_VFS_OP_CHDIR,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_getwd), SMB_VFS_OP_GETWD,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_utime), SMB_VFS_OP_UTIME,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_symlink), SMB_VFS_OP_SYMLINK,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_readlink), SMB_VFS_OP_READLINK,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_link), SMB_VFS_OP_LINK,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_mknod), SMB_VFS_OP_MKNOD,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_realpath), SMB_VFS_OP_REALPATH,
+SMB_VFS_LAYER_TRANSPARENT},
+
+ /* NT File ACL operations */
+
+ {SMB_VFS_OP(catia_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
+SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(catia_set_nt_acl), SMB_VFS_OP_SET_NT_ACL,
+SMB_VFS_LAYER_TRANSPARENT},
+
+ /* POSIX ACL operations */
+
+ {SMB_VFS_OP(catia_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
+SMB_VFS_LAYER_TRANSPARENT},
+
+
+ {NULL, SMB_VFS_OP_NOOP,
+SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS init_module(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
+catia_op_tuples);
+}
diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c
index 740218dcd41..4d10ea5f337 100644
--- a/source/modules/vfs_fake_perms.c
+++ b/source/modules/vfs_fake_perms.c
@@ -24,6 +24,8 @@
#include "includes.h"
+extern struct current_user current_user;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
@@ -33,8 +35,6 @@ static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, c
ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
if (ret == 0) {
- extern struct current_user current_user;
-
if (S_ISDIR(sbuf->st_mode)) {
sbuf->st_mode = S_IFDIR | S_IRWXU;
} else {
@@ -53,8 +53,6 @@ static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd
ret = SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf);
if (ret == 0) {
- extern struct current_user current_user;
-
if (S_ISDIR(sbuf->st_mode)) {
sbuf->st_mode = S_IFDIR | S_IRWXU;
} else {
diff --git a/source/modules/weird.c b/source/modules/weird.c
index 3c59fd9d61f..e4809a64c42 100644
--- a/source/modules/weird.c
+++ b/source/modules/weird.c
@@ -26,8 +26,8 @@ static struct {
char *to;
int len;
} weird_table[] = {
- {'q', "^q^", 3},
- {'Q', "^Q^", 3},
+ {'q', CONST_DISCARD(char *, "^q^"), 3},
+ {'Q', CONST_DISCARD(char *, "^Q^"), 3},
{0, NULL}
};
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index f8006a22a9e..532b578f3c7 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -27,6 +27,8 @@ int ClientNMB = -1;
int ClientDGRAM = -1;
int global_nmb_port = -1;
+extern BOOL rescan_listen_set;
+extern struct in_addr loopback_ip;
extern BOOL global_in_nmbd;
extern BOOL override_logfile;
@@ -196,8 +198,6 @@ static BOOL reload_interfaces(time_t t)
static time_t lastt;
int n;
struct subnet_record *subrec;
- extern BOOL rescan_listen_set;
- extern struct in_addr loopback_ip;
if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
lastt = t;
diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c
index ecfd92719bf..b53a6d7328f 100644
--- a/source/nmbd/nmbd_subnetdb.c
+++ b/source/nmbd/nmbd_subnetdb.c
@@ -25,6 +25,7 @@
#include "includes.h"
+extern struct in_addr loopback_ip;
extern int ClientNMB;
extern int ClientDGRAM;
extern int global_nmb_port;
@@ -211,7 +212,6 @@ BOOL create_subnets(void)
int num_interfaces = iface_count();
int i;
struct in_addr unicast_ip, ipzero;
- extern struct in_addr loopback_ip;
if(num_interfaces == 0) {
DEBUG(0,("create_subnets: No local interfaces !\n"));
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index c6bcb3e5742..33690133bf8 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -29,6 +29,8 @@
#include "includes.h"
+extern fstring local_machine;
+
struct sync_record {
struct sync_record *next, *prev;
unstring workgroup;
@@ -65,7 +67,6 @@ static void sync_child(char *name, int nm_type,
struct in_addr ip, BOOL local, BOOL servers,
char *fname)
{
- extern fstring local_machine;
fstring unix_workgroup;
static struct cli_state cli;
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 3a920c1134b..5e08c0853e1 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -28,8 +28,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
-extern DOM_SID global_sid_NULL; /* NULL sid */
-
NSS_STATUS winbindd_request(int req_type,
struct winbindd_request *request,
struct winbindd_response *response);
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 9caf7affc39..6ba0cbbf428 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -26,6 +26,9 @@
#include "winbind_client.h"
+#define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr)))
+#define CONST_ADD(type, ptr) ((type) ((const void *) (ptr)))
+
/* Global variables. These are effectively the client state information */
int winbindd_fd = -1; /* fd for winbindd socket */
@@ -606,14 +609,14 @@ NSS_STATUS winbindd_request(int req_type,
BOOL winbind_off( void )
{
- static char *s = WINBINDD_DONT_ENV "=1";
+ static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=1");
return putenv(s) != -1;
}
BOOL winbind_on( void )
{
- static char *s = WINBINDD_DONT_ENV "=0";
+ static char *s = CONST_DISCARD(char *, WINBINDD_DONT_ENV "=0");
return putenv(s) != -1;
}
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 6f4a0a27533..6840dd91871 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -898,8 +898,6 @@ int main(int argc, char **argv)
idmap_proxyonly();
}
- generate_wellknown_sids();
-
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index cd1d16e3441..863ae35fed4 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -245,7 +245,6 @@ struct winbindd_idmap_methods {
#include "nsswitch/winbindd_proto.h"
#include "rpc_parse.h"
-#include "rpc_client.h"
#define WINBINDD_ESTABLISH_LOOP 30
#define WINBINDD_RESCAN_FREQ 300
diff --git a/source/nsswitch/winbindd_acct.c b/source/nsswitch/winbindd_acct.c
index 2c8b7cae287..cd0b5b7e066 100644
--- a/source/nsswitch/winbindd_acct.c
+++ b/source/nsswitch/winbindd_acct.c
@@ -222,7 +222,7 @@ static WINBINDD_GR* string2group( char *string )
gr_members = SMB_XMALLOC_ARRAY(char*, num_gr_members+1);
i = 0;
- while ( next_token(&str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
+ while ( next_token((const char **) &str, buffer, ",", sizeof(buffer)) && i<num_gr_members ) {
gr_members[i++] = smb_xstrdup(buffer);
}
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index 88a7d3ed3b1..4daf4ba9890 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -27,6 +27,8 @@
#ifdef HAVE_ADS
+extern struct winbindd_methods msrpc_methods, cache_methods;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -76,7 +78,6 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
status = ads_connect(ads);
if (!ADS_ERR_OK(status) || !ads->config.realm) {
- extern struct winbindd_methods msrpc_methods, cache_methods;
DEBUG(1,("ads_connect for domain %s failed: %s\n",
domain->name, ads_errstr(status)));
ads_destroy(&ads);
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 3fc62df005f..cc385a1dd72 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -26,6 +26,12 @@
#include "includes.h"
#include "winbindd.h"
+extern BOOL opt_nocache;
+extern struct winbindd_methods msrpc_methods;
+extern struct winbindd_methods ads_methods;
+extern BOOL opt_dual_daemon;
+extern BOOL background_process;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -47,8 +53,6 @@ static struct winbind_cache *wcache;
/* flush the cache */
void wcache_flush_cache(void)
{
- extern BOOL opt_nocache;
-
if (!wcache)
return;
if (wcache->tdb) {
@@ -102,11 +106,9 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
struct winbind_cache *ret = wcache;
if (!domain->backend) {
- extern struct winbindd_methods msrpc_methods;
switch (lp_security()) {
#ifdef HAVE_ADS
case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
/* always obey the lp_security parameter for our domain */
if (domain->primary) {
domain->backend = &ads_methods;
@@ -469,13 +471,11 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
centry->sequence_number = centry_uint32(centry);
if (centry_expired(domain, kstr, centry)) {
- extern BOOL opt_dual_daemon;
DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
kstr, domain->name ));
if (opt_dual_daemon) {
- extern BOOL background_process;
background_process = True;
DEBUG(10,("wcache_fetch: background processing expired entry %s for domain %s\n",
kstr, domain->name ));
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 51618bd00fd..f0d3bc43ea6 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -920,6 +920,52 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
+static BOOL enum_alias_memberships(const DOM_SID *member_sid,
+ DOM_SID **aliases, int *num_aliases)
+{
+ TALLOC_CTX *mem_ctx = talloc_init("enum_alias_memberships");
+
+ uint32 *rids = NULL;
+ int i, num_rids = 0;
+
+ BOOL result = False;
+
+ if (mem_ctx == NULL)
+ return False;
+
+ *aliases = NULL;
+ *num_aliases = 0;
+
+ if (!pdb_enum_alias_memberships(mem_ctx, get_global_sam_sid(),
+ member_sid, 1, &rids, &num_rids))
+ goto done;
+
+ for (i=0; i<num_rids; i++) {
+ DOM_SID alias_sid;
+ sid_copy(&alias_sid, get_global_sam_sid());
+ sid_append_rid(&alias_sid, rids[i]);
+ add_sid_to_array(NULL, &alias_sid, aliases, num_aliases);
+ }
+
+ if (!pdb_enum_alias_memberships(mem_ctx, &global_sid_Builtin,
+ member_sid, 1, &rids, &num_rids))
+ goto done;
+
+ for (i=0; i<num_rids; i++) {
+ DOM_SID alias_sid;
+ sid_copy(&alias_sid, &global_sid_Builtin);
+ sid_append_rid(&alias_sid, rids[i]);
+ add_sid_to_array(NULL, &alias_sid, aliases, num_aliases);
+ }
+
+ result = True;
+ done:
+ if (mem_ctx != NULL)
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
{
gid_t gid;
@@ -937,7 +983,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
/* Add nested group memberships */
- if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
+ if (!enum_alias_memberships(sid, &aliases, &num_aliases))
return;
for (j=0; j<num_aliases; j++) {
@@ -953,7 +999,7 @@ static void add_local_gids_from_sid(DOM_SID *sid, gid_t **gids, int *num)
continue;
}
- add_gid_to_array_unique(gid, gids, num);
+ add_gid_to_array_unique(NULL, gid, gids, num);
}
SAFE_FREE(aliases);
}
@@ -974,7 +1020,7 @@ static void add_gids_from_group_sid(DOM_SID *sid, gid_t **gids, int *num)
sid_string_static(sid)));
if (NT_STATUS_IS_OK(idmap_sid_to_gid(sid, &gid, 0)))
- add_gid_to_array_unique(gid, gids, num);
+ add_gid_to_array_unique(NULL, gid, gids, num);
add_local_gids_from_sid(sid, gids, num);
}
@@ -1178,7 +1224,7 @@ static void add_local_sids_from_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DOM_SID *aliases = NULL;
int i, num_aliases = 0;
- if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
+ if (!enum_alias_memberships(sid, &aliases, &num_aliases))
return;
if (num_aliases == 0)
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index 88e3254d24a..06ebd68f8f8 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -11,7 +11,7 @@
*/
#ifndef SAFE_FREE
-#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
+#define SAFE_FREE(x) do { if(x) {free(CONST_DISCARD(void *, (x))); x=NULL;} } while(0)
#endif
#ifndef _WINBINDD_NTDOM_H
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 99d12563c6c..1dfa810a8d3 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -788,7 +788,8 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
to.tv_sec = 10;
to.tv_usec = 0;
- if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
+ if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
+ CONST_DISCARD(char **, &attrs[0]), 0, &to, &res))
goto done;
if (ldap_count_entries(ldp, res) != 1)
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 11da05ac3b4..68560c040e4 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -24,6 +24,9 @@
#include "includes.h"
#include "winbindd.h"
+extern struct winbindd_methods cache_methods;
+extern struct winbindd_methods passdb_methods;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@@ -85,25 +88,17 @@ void free_domain_list(void)
static BOOL is_internal_domain(const DOM_SID *sid)
{
- extern DOM_SID global_sid_Builtin;
-
if (sid == NULL)
return False;
- if (sid_compare_domain(sid, get_global_sam_sid()) == 0)
- return True;
-
- if (sid_compare_domain(sid, &global_sid_Builtin) == 0)
- return True;
-
- return False;
+ return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
}
/* Add a trusted domain to our list of domains */
static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
struct winbindd_methods *methods,
- DOM_SID *sid)
+ const DOM_SID *sid)
{
struct winbindd_domain *domain;
const char *alternative_name = NULL;
@@ -183,7 +178,6 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
static void add_trusted_domains( struct winbindd_domain *domain )
{
- extern struct winbindd_methods cache_methods;
TALLOC_CTX *mem_ctx;
NTSTATUS result;
time_t t;
@@ -284,9 +278,6 @@ void rescan_trusted_domains( void )
/* Look up global info for the winbind daemon */
BOOL init_domain_list(void)
{
- extern DOM_SID global_sid_Builtin;
- extern struct winbindd_methods cache_methods;
- extern struct winbindd_methods passdb_methods;
struct winbindd_domain *domain;
/* Free existing list */
@@ -636,7 +627,7 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
*/
void fill_domain_username(fstring name, const char *domain, const char *user)
{
- strlower_m( user );
+ strlower_m(CONST_DISCARD(char *, user));
if (assume_domain(domain)) {
strlcpy(name, user, sizeof(fstring));
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 493f1142daa..619a9ccb3d1 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -58,6 +58,7 @@ BOOL bLoaded = False;
extern userdom_struct current_user_info;
extern pstring user_socket_options;
+extern enum protocol_types Protocol;
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
@@ -73,7 +74,7 @@ extern pstring user_socket_options;
/* some helpful bits */
#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
-#define VALID(i) ServicePtrs[i]->valid
+#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
int keepalive = DEFAULT_KEEPALIVE;
BOOL use_getwd_cache = True;
@@ -183,8 +184,16 @@ typedef struct
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
+ char *szEventLogOpenCommand;
+ char *szEventLogReadCommand;
+ char *szEventLogClearCommand;
+ char *szEventLogNumRecordsCommand;
+ char *szEventLogOldestRecordCommand;
+ char *szEventLogCloseCommand;
+ char **szEventLogs;
char *szGuestaccount;
char *szManglingMethod;
+ char **szServicesList;
int mangle_prefix;
int max_log_size;
char *szLogLevel;
@@ -272,6 +281,7 @@ typedef struct
BOOL bNTPipeSupport;
BOOL bNTStatusSupport;
BOOL bStatCache;
+ int iMaxStatCacheSize;
BOOL bKernelOplocks;
BOOL bAllowTrustedDomains;
BOOL bLanmanAuth;
@@ -413,6 +423,7 @@ typedef struct
BOOL bBlockingLocks;
BOOL bInheritPerms;
BOOL bInheritACLS;
+ BOOL bInheritOwner;
BOOL bMSDfsRoot;
BOOL bUseClientDriver;
BOOL bDefaultDevmode;
@@ -539,6 +550,7 @@ static service sDefault = {
True, /* bBlockingLocks */
False, /* bInheritPerms */
False, /* bInheritACLS */
+ False, /* bInheritOwner */
False, /* bMSDfsRoot */
False, /* bUseClientDriver */
False, /* bDefaultDevmode */
@@ -581,6 +593,7 @@ static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr
static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
static BOOL handle_acl_compatibility( int snum, const char *pszParmValue, char **ptr);
static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
+static BOOL handle_eventlog( int snum, const char *pszParmValue, char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
@@ -864,6 +877,7 @@ static struct parm_struct parm_table[] = {
{"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
{"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
@@ -932,6 +946,8 @@ static struct parm_struct parm_table[] = {
{"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
{"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
+ {"enable svcctl", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
+
{N_("Tuning Options"), P_SEP, P_SEPARATOR},
{"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
@@ -975,6 +991,7 @@ static struct parm_struct parm_table[] = {
{"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
{"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
{"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
{"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
{"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
{"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
@@ -1017,6 +1034,7 @@ static struct parm_struct parm_table[] = {
{"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
+ {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
{"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
@@ -1110,6 +1128,14 @@ static struct parm_struct parm_table[] = {
{"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
{"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
+ {N_("EventLog Options"), P_SEP, P_SEPARATOR},
+ {"eventlog open command", P_STRING, P_GLOBAL, &Globals.szEventLogOpenCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog read command", P_STRING, P_GLOBAL, &Globals.szEventLogReadCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog clear command", P_STRING, P_GLOBAL, &Globals.szEventLogClearCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog num records command", P_STRING, P_GLOBAL, &Globals.szEventLogNumRecordsCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog oldest record command", P_STRING, P_GLOBAL, &Globals.szEventLogOldestRecordCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
@@ -1378,7 +1404,7 @@ static void init_globals(void)
Globals.AlgorithmicRidBase = BASE_RID;
Globals.bLoadPrinters = True;
- Globals.PrintcapCacheTime = 0;
+ Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
/* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
@@ -1438,6 +1464,7 @@ static void init_globals(void)
Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
Globals.bNTStatusSupport = True; /* Use NT status by default. */
Globals.bStatCache = True; /* use stat cache by default */
+ Globals.iMaxStatCacheSize = 0; /* unlimited size in kb by default. */
Globals.restrict_anonymous = 0;
Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
@@ -1527,6 +1554,12 @@ static void init_globals(void)
string_set(&Globals.szAclCompat, "");
string_set(&Globals.szCupsServer, "");
+ string_set(&Globals.szEventLogOpenCommand, "");
+ string_set(&Globals.szEventLogReadCommand, "");
+ string_set(&Globals.szEventLogClearCommand, "");
+ string_set(&Globals.szEventLogNumRecordsCommand, "");
+ string_set(&Globals.szEventLogOldestRecordCommand, "");
+
Globals.winbind_cache_time = 300; /* 5 minutes */
Globals.bWinbindEnableLocalAccounts = False;
Globals.bWinbindEnumUsers = True;
@@ -1553,6 +1586,8 @@ static void init_globals(void)
operations as root */
Globals.bEnablePrivileges = False;
+
+ Globals.szServicesList = str_list_make( "Spooler NETLOGON", NULL );
}
static TALLOC_CTX *lp_talloc;
@@ -1719,6 +1754,7 @@ FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
+
FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
@@ -1738,6 +1774,14 @@ FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
+FN_GLOBAL_STRING(lp_eventlog_open_cmd, &Globals.szEventLogOpenCommand)
+FN_GLOBAL_STRING(lp_eventlog_read_cmd, &Globals.szEventLogReadCommand)
+FN_GLOBAL_STRING(lp_eventlog_clear_cmd, &Globals.szEventLogClearCommand)
+FN_GLOBAL_STRING(lp_eventlog_num_records_cmd, &Globals.szEventLogNumRecordsCommand)
+FN_GLOBAL_STRING(lp_eventlog_oldest_record_cmd, &Globals.szEventLogOldestRecordCommand)
+FN_GLOBAL_STRING(lp_eventlog_close_cmd, &Globals.szEventLogCloseCommand)
+FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
+
FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
@@ -1773,6 +1817,7 @@ FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
+FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
@@ -1835,6 +1880,7 @@ FN_LOCAL_STRING(lp_username, szUsername)
FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
FN_LOCAL_LIST(lp_valid_users, szValidUsers)
FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
+FN_GLOBAL_LIST(lp_enable_svcctl, &Globals.szServicesList)
FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
@@ -1907,6 +1953,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_inherit_acls, bInheritACLS)
+FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
@@ -2765,6 +2812,12 @@ static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
return True;
}
+static BOOL handle_eventlog(int snum, const char *pszParmValue, char **ptr)
+{
+ string_set(ptr, pszParmValue);
+ return True;
+}
+
static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
{
BOOL ret;
@@ -4311,7 +4364,6 @@ const char *lp_printcapname(void)
BOOL lp_use_sendfile(int snum)
{
- extern enum protocol_types Protocol;
/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
if (Protocol < PROTOCOL_NT1) {
return False;
diff --git a/source/param/params.c b/source/param/params.c
index 9d21d25a240..3b736113bef 100644
--- a/source/param/params.c
+++ b/source/param/params.c
@@ -81,6 +81,8 @@
#include "includes.h"
+extern BOOL in_client;
+
/* -------------------------------------------------------------------------- **
* Constants...
*/
@@ -523,7 +525,6 @@ static BOOL Parse( myFILE *InFile,
static myFILE *OpenConfFile( const char *FileName )
{
const char *func = "params.c:OpenConfFile() -";
- extern BOOL in_client;
int lvl = in_client?1:0;
myFILE *ret;
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index ae0b16273f2..ecc7d291f6d 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -86,8 +86,6 @@ static DOM_SID *pdb_generate_sam_sid(void)
if(!(sam_sid=SMB_MALLOC_P(DOM_SID)))
return NULL;
- generate_wellknown_sids();
-
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index deac2bbd6e3..203fa2bf21e 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -1894,7 +1894,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
/* Change from V1 is addition of password history field. */
account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
- char *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
+ uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
ret = False;
goto done;
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 4b59b5fdf95..99afac133ac 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -1195,7 +1195,7 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
/* We need to make sure we don't have a race condition here - the
account policy history length can change between when the pw_history
was first loaded into the SAM_ACCOUNT struct and now.... JRA. */
- pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
+ pwhistory = CONST_DISCARD(uchar *, pdb_get_pw_history(sampass, &current_history_len));
if (current_history_len != pwHistLen) {
/* After closing and reopening SAM_ACCOUNT the history
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 84d398ccd64..301dc101eb4 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -48,7 +48,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
static void pdb_force_pw_initialization(SAM_ACCOUNT *pass)
{
- const char *lm_pwd, *nt_pwd;
+ const uint8 *lm_pwd, *nt_pwd;
/* only reset a password if the last set time has been
explicitly been set to zero. A default last set time
@@ -233,7 +233,7 @@ static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sa
static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- const char *lm_pw, *nt_pw;
+ const uint8 *lm_pw, *nt_pw;
uint16 acb_flags;
if ((!context) || (!context->pdb_methods)) {
@@ -262,7 +262,7 @@ static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT
static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- const char *lm_pw, *nt_pw;
+ const uint8 *lm_pw, *nt_pw;
uint16 acb_flags;
if (!context) {
@@ -643,9 +643,12 @@ static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
}
static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
const DOM_SID *members,
int num_members,
- DOM_SID **aliases, int *num)
+ uint32 **alias_rids,
+ int *num_alias_rids)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -655,8 +658,29 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
}
return context->pdb_methods->
- enum_alias_memberships(context->pdb_methods, members,
- num_members, aliases, num);
+ enum_alias_memberships(context->pdb_methods, mem_ctx,
+ domain_sid, members, num_members,
+ alias_rids, num_alias_rids);
+}
+
+static NTSTATUS context_lookup_rids(struct pdb_context *context,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->lookup_rids(context->pdb_methods,
+ mem_ctx, domain_sid, num_rids,
+ rids, names, attrs);
}
/******************************************************************
@@ -788,6 +812,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_del_aliasmem = context_del_aliasmem;
(*context)->pdb_enum_aliasmem = context_enum_aliasmem;
(*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
+ (*context)->pdb_lookup_rids = context_lookup_rids;
(*context)->free_fn = free_pdb_context;
@@ -1252,8 +1277,9 @@ BOOL pdb_enum_aliasmem(const DOM_SID *alias,
members, num_members));
}
-BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
- DOM_SID **aliases, int *num)
+BOOL pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
+ const DOM_SID *members, int num_members,
+ uint32 **alias_rids, int *num_alias_rids)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1262,9 +1288,28 @@ BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_alias_memberships(pdb_context, members,
- num_members,
- aliases, num));
+ pdb_enum_alias_memberships(pdb_context, mem_ctx,
+ domain_sid,
+ members, num_members,
+ alias_rids,
+ num_alias_rids));
+}
+
+NTSTATUS pdb_lookup_rids(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ return pdb_context->pdb_lookup_rids(pdb_context, mem_ctx, domain_sid,
+ num_rids, rids, names, attrs);
}
/***************************************************************
@@ -1439,6 +1484,65 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
return NT_STATUS_OK;
}
+NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs)
+{
+ int i;
+ NTSTATUS result;
+ BOOL have_mapped = False;
+ BOOL have_unmapped = False;
+
+ (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
+ (*attrs) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_rids);
+
+ if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
+ return NT_STATUS_NO_MEMORY;
+
+ if (!sid_equal(domain_sid, get_global_sam_sid())) {
+ /* TODO: Sooner or later we need to look up BUILTIN rids as
+ * well. -- vl */
+ goto done;
+ }
+
+ for (i = 0; i < num_rids; i++) {
+ fstring tmpname;
+ fstring domname;
+ DOM_SID sid;
+ enum SID_NAME_USE type;
+
+ (*attrs)[i] = SID_NAME_UNKNOWN;
+
+ sid_copy(&sid, domain_sid);
+ sid_append_rid(&sid, rids[i]);
+
+ if (lookup_sid(&sid, domname, tmpname, &type)) {
+ (*attrs)[i] = (uint32)type;
+ (*names)[i] = talloc_strdup(mem_ctx, tmpname);
+ if ((*names)[i] == NULL)
+ return NT_STATUS_NO_MEMORY;
+ DEBUG(5,("lookup_rids: %s:%d\n", (*names)[i],
+ (*attrs)[i]));
+ have_mapped = True;
+ } else {
+ have_unmapped = True;
+ }
+ }
+
+ done:
+
+ result = NT_STATUS_NONE_MAPPED;
+
+ if (have_mapped)
+ result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
+
+ return result;
+}
+
NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
{
*methods = TALLOC_P(mem_ctx, struct pdb_methods);
@@ -1478,6 +1582,365 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->del_aliasmem = pdb_default_del_aliasmem;
(*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
(*methods)->enum_alias_memberships = pdb_default_alias_memberships;
+ (*methods)->lookup_rids = pdb_default_lookup_rids;
return NT_STATUS_OK;
}
+
+struct pdb_search *pdb_search_users(uint16 acct_flags);
+struct pdb_search *pdb_search_groups(void);
+struct pdb_search *pdb_search_aliases(const DOM_SID *sid);
+uint32 pdb_search_entries(struct pdb_search *search, uint32 start_idx, uint32 max_entries, struct samr_displayentry **result);
+void pdb_search_destroy(struct pdb_search *search);
+
+static struct pdb_search *pdb_search_init(enum pdb_search_type type)
+{
+ TALLOC_CTX *mem_ctx;
+ struct pdb_search *result;
+
+ mem_ctx = talloc_init("pdb_search");
+ if (mem_ctx == NULL) {
+ DEBUG(0, ("talloc_init failed\n"));
+ return NULL;
+ }
+
+ result = TALLOC_P(mem_ctx, struct pdb_search);
+ if (result == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->mem_ctx = mem_ctx;
+ result->type = type;
+ result->cache = NULL;
+ result->cache_size = 0;
+ result->search_ended = False;
+
+ return result;
+}
+
+static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
+ uint16 acct_flags,
+ const char *account_name,
+ const char *fullname,
+ const char *description,
+ struct samr_displayentry *entry)
+{
+ entry->rid = rid;
+ entry->acct_flags = acct_flags;
+
+ if (account_name != NULL)
+ entry->account_name = talloc_strdup(mem_ctx, account_name);
+
+ if (fullname != NULL)
+ entry->fullname = talloc_strdup(mem_ctx, fullname);
+
+ if (description != NULL)
+ entry->description = talloc_strdup(mem_ctx, description);
+}
+
+static BOOL user_search_in_progress = False;
+struct user_search {
+ uint16 acct_flags;
+};
+
+struct pdb_search *pdb_search_users(uint16 acct_flags)
+{
+ struct pdb_search *result;
+ struct user_search *state;
+
+ if (user_search_in_progress) {
+ DEBUG(1, ("user search in progress\n"));
+ return NULL;
+ }
+
+ if (!pdb_setsampwent(False, acct_flags))
+ return NULL;
+
+ user_search_in_progress = True;
+
+ result = pdb_search_init(PDB_USER_SEARCH);
+ if (result == NULL)
+ return NULL;
+
+ state = TALLOC_P(result->mem_ctx, struct user_search);
+ if (state == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+
+ state->acct_flags = acct_flags;
+
+ result->private = state;
+ return result;
+}
+
+static BOOL pdb_search_entry_users(struct pdb_search *s, TALLOC_CTX *mem_ctx,
+ struct samr_displayentry *entry)
+{
+ struct user_search *state = s->private;
+ SAM_ACCOUNT *user = NULL;
+ NTSTATUS status;
+
+ next:
+ status = pdb_init_sam(&user);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Could not pdb_init_sam\n"));
+ return False;
+ }
+
+ if (!pdb_getsampwent(user)) {
+ pdb_free_sam(&user);
+ return False;
+ }
+
+ if ((state->acct_flags != 0) &&
+ ((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
+ pdb_free_sam(&user);
+ goto next;
+ }
+
+ fill_displayentry(mem_ctx, pdb_get_user_rid(user),
+ pdb_get_acct_ctrl(user), pdb_get_username(user),
+ pdb_get_fullname(user), pdb_get_acct_desc(user),
+ entry);
+
+ pdb_free_sam(&user);
+ return True;
+}
+
+static void pdb_search_end_users(struct pdb_search *search)
+{
+ pdb_endsampwent();
+ user_search_in_progress = False;
+}
+
+struct group_search {
+ GROUP_MAP *groups;
+ int num_groups, current_group;
+};
+
+struct pdb_search *pdb_search_groups(void)
+{
+ struct pdb_search *result;
+ struct group_search *state;
+
+ result = pdb_search_init(PDB_GROUP_SEARCH);
+ if (result == NULL)
+ return NULL;
+
+ state = TALLOC_P(result->mem_ctx, struct group_search);
+ if (state == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+
+ if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &state->groups,
+ &state->num_groups, True)) {
+ DEBUG(0, ("Could not enum groups\n"));
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+
+ state->current_group = 0;
+ result->private = state;
+ return result;
+}
+
+static BOOL pdb_search_entry_group(struct pdb_search *s, TALLOC_CTX *mem_ctx,
+ struct samr_displayentry *entry)
+{
+ struct group_search *state = s->private;
+ uint32 rid;
+ GROUP_MAP *map = &state->groups[state->current_group];
+
+ if (state->current_group == state->num_groups)
+ return False;
+
+ sid_peek_rid(&map->sid, &rid);
+
+ fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+ entry);
+
+ state->current_group += 1;
+ return True;
+}
+
+static void pdb_search_end_groups(struct pdb_search *search)
+{
+ struct group_search *state = search->private;
+ SAFE_FREE(state->groups);
+}
+
+struct alias_search {
+ GROUP_MAP *aliases;
+ int num_aliases, current_alias;
+};
+
+struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+{
+ struct pdb_search *result;
+ struct alias_search *state;
+ enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+ DOM_SID builtin_sid;
+
+ if (sid_equal(sid, get_global_sam_sid()))
+ type = SID_NAME_ALIAS;
+
+ string_to_sid(&builtin_sid, "S-1-5-32");
+
+ if (sid_equal(sid, &builtin_sid))
+ type = SID_NAME_WKN_GRP;
+
+ if (type == SID_NAME_UNKNOWN) {
+ DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
+ return NULL;
+ }
+
+ result = pdb_search_init(PDB_ALIAS_SEARCH);
+ if (result == NULL)
+ return NULL;
+
+ state = TALLOC_P(result->mem_ctx, struct alias_search);
+ if (state == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+
+ if (!pdb_enum_group_mapping(type, &state->aliases,
+ &state->num_aliases, False)) {
+ DEBUG(0, ("Could not enum aliases\n"));
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+
+ state->current_alias = 0;
+ result->private = state;
+ return result;
+}
+
+static BOOL pdb_search_entry_alias(struct pdb_search *s, TALLOC_CTX *mem_ctx,
+ struct samr_displayentry *entry)
+{
+ struct alias_search *state = s->private;
+ uint32 rid;
+ GROUP_MAP *map = &state->aliases[state->current_alias];
+
+ if (state->current_alias == state->num_aliases)
+ return False;
+
+ sid_peek_rid(&map->sid, &rid);
+
+ fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+ entry);
+
+ state->current_alias += 1;
+ return True;
+}
+
+static void pdb_search_end_aliases(struct pdb_search *search)
+{
+ struct alias_search *state = search->private;
+ SAFE_FREE(state->aliases);
+}
+
+static BOOL pdb_search_entry(struct pdb_search *search, TALLOC_CTX *mem_ctx,
+ struct samr_displayentry *entry)
+{
+ BOOL result = False;
+ switch (search->type) {
+ case PDB_USER_SEARCH:
+ result = pdb_search_entry_users(search, mem_ctx, entry);
+ break;
+ case PDB_GROUP_SEARCH:
+ result = pdb_search_entry_group(search, mem_ctx, entry);
+ break;
+ case PDB_ALIAS_SEARCH:
+ result = pdb_search_entry_alias(search, mem_ctx, entry);
+ break;
+ default:
+ DEBUG(0, ("unknown search type: %d\n", search->type));
+ break;
+ }
+ return result;
+}
+
+static void pdb_search_end(struct pdb_search *search)
+{
+ switch (search->type) {
+ case PDB_USER_SEARCH:
+ pdb_search_end_users(search);
+ break;
+ case PDB_GROUP_SEARCH:
+ pdb_search_end_groups(search);
+ break;
+ case PDB_ALIAS_SEARCH:
+ pdb_search_end_aliases(search);
+ break;
+ default:
+ DEBUG(0, ("unknown search type: %d\n", search->type));
+ break;
+ }
+}
+
+static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
+ uint32 idx)
+{
+ if (idx < search->cache_size)
+ return &search->cache[idx];
+
+ if (search->search_ended)
+ return NULL;
+
+ while (idx >= search->cache_size) {
+ struct samr_displayentry entry;
+
+ if (!pdb_search_entry(search, search->mem_ctx, &entry)) {
+ pdb_search_end(search);
+ search->search_ended = True;
+ break;
+ }
+
+ ADD_TO_ARRAY(search->mem_ctx, struct samr_displayentry,
+ entry, &search->cache, &search->cache_size);
+ }
+
+ return (search->cache_size > idx) ? &search->cache[idx] : NULL;
+}
+
+uint32 pdb_search_entries(struct pdb_search *search,
+ uint32 start_idx, uint32 max_entries,
+ struct samr_displayentry **result)
+{
+ struct samr_displayentry *end_entry;
+ uint32 end_idx = start_idx+max_entries-1;
+
+ /* The first entry needs to be searched after the last. Otherwise the
+ * first entry might have moved due to a realloc during the search for
+ * the last entry. */
+
+ end_entry = pdb_search_getentry(search, end_idx);
+ *result = pdb_search_getentry(search, start_idx);
+
+ if (end_entry != NULL)
+ return max_entries;
+
+ if (start_idx >= search->cache_size)
+ return 0;
+
+ return search->cache_size - start_idx;
+}
+
+void pdb_search_destroy(struct pdb_search *search)
+{
+ if (search == NULL)
+ return;
+
+ if (!search->search_ended)
+ pdb_search_end(search);
+
+ talloc_destroy(search->mem_ctx);
+}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 3dab919cb46..3899949058a 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -462,7 +462,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
uint8 hours[MAX_HOURS_LEN];
pstring temp;
LOGIN_CACHE *cache_entry = NULL;
- int pwHistLen;
+ uint32 pwHistLen;
pstring tmpstring;
/*
@@ -694,8 +694,8 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
if (ldap_state->is_nds_ldap) {
char *user_dn;
- size_t pwd_len;
- uchar clear_text_pw[512];
+ int pwd_len;
+ char clear_text_pw[512];
/* Make call to Novell eDirectory ldap extension to get clear text password.
NOTE: This will only work if we have an SSL connection to eDirectory. */
@@ -1086,14 +1086,15 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
}
if (need_update(sampass, PDB_PWHISTORY)) {
- int pwHistLen = 0;
+ uint32 pwHistLen = 0;
account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen == 0) {
/* Remove any password history from the LDAP store. */
memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
temp[64] = '\0';
} else {
- int i, currHistLen = 0;
+ int i;
+ uint32 currHistLen = 0;
const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
if (pwhist != NULL) {
/* We can only store (sizeof(pstring)-1)/64 password history entries. */
@@ -1122,7 +1123,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
}
if (need_update(sampass, PDB_HOURS)) {
- const char *hours = pdb_get_hours(sampass);
+ const uint8 *hours = pdb_get_hours(sampass);
if (hours) {
pdb_sethexhours(temp, hours);
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
@@ -2207,6 +2208,39 @@ static void add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
*num += 1;
}
+static BOOL ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
+ LDAPMessage *entry,
+ const DOM_SID *domain_sid,
+ uint32 *rid)
+{
+ fstring str;
+ DOM_SID sid;
+
+ if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
+ str, sizeof(str)-1)) {
+ DEBUG(10, ("Could not find sambaSID attribute\n"));
+ return False;
+ }
+
+ if (!string_to_sid(&sid, str)) {
+ DEBUG(10, ("Could not convert string %s to sid\n", str));
+ return False;
+ }
+
+ if (sid_compare_domain(&sid, domain_sid) != 0) {
+ DEBUG(10, ("SID %s is not in expected domain %s\n",
+ str, sid_string_static(domain_sid)));
+ return False;
+ }
+
+ if (!sid_peek_rid(&sid, rid)) {
+ DEBUG(10, ("Could not peek into RID\n"));
+ return False;
+ }
+
+ return True;
+}
+
static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const DOM_SID *group,
@@ -2253,26 +2287,16 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
entry != NULL;
entry = ldap_next_entry(conn->ldap_struct, entry))
{
- fstring str;
- DOM_SID sid;
uint32 rid;
- if (!smbldap_get_single_attribute(conn->ldap_struct,
- entry, "sambaSID",
- str, sizeof(str)-1))
- continue;
-
- if (!string_to_sid(&sid, str))
- goto done;
-
- if (!sid_check_is_in_our_domain(&sid)) {
- DEBUG(1, ("Inconsistent SAM -- group member uid not "
- "in our domain\n"));
+ if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
+ entry,
+ get_global_sam_sid(),
+ &rid)) {
+ DEBUG(2, ("Could not find sid from ldap entry\n"));
continue;
}
- sid_peek_rid(&sid, &rid);
-
add_rid_to_array_unique(mem_ctx, rid, member_rids,
num_members);
}
@@ -2412,7 +2436,6 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
LDAPMessage *entry;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
int num_sids, num_gids;
- extern DOM_SID global_sid_NULL;
if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
return pdb_default_enum_group_memberships(methods, username,
@@ -2445,11 +2468,11 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
/* We need to add the primary group as the first gid/sid */
- add_gid_to_array_unique(primary_gid, gids, &num_gids);
+ add_gid_to_array_unique(NULL, primary_gid, gids, &num_gids);
/* This sid will be replaced later */
- add_sid_to_array_unique(&global_sid_NULL, sids, &num_sids);
+ add_sid_to_array_unique(NULL, &global_sid_NULL, sids, &num_sids);
for (entry = ldap_first_entry(conn->ldap_struct, msg);
entry != NULL;
@@ -2481,8 +2504,8 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
if (gid == primary_gid) {
sid_copy(&(*sids)[0], &sid);
} else {
- add_gid_to_array_unique(gid, gids, &num_gids);
- add_sid_to_array_unique(&sid, sids, &num_sids);
+ add_gid_to_array_unique(NULL, gid, gids, &num_gids);
+ add_sid_to_array_unique(NULL, &sid, sids, &num_sids);
}
}
@@ -3028,7 +3051,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
if (!string_to_sid(&member, values[i]))
continue;
- add_sid_to_array(&member, members, num_members);
+ add_sid_to_array(NULL, &member, members, num_members);
}
ldap_value_free(values);
@@ -3038,9 +3061,12 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
}
static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
const DOM_SID *members,
int num_members,
- DOM_SID **aliases, int *num_aliases)
+ uint32 **alias_rids,
+ int *num_alias_rids)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
@@ -3053,12 +3079,6 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
int i;
int rc;
char *filter;
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("ldapsam_alias_memberships");
-
- if (mem_ctx == NULL)
- return NT_STATUS_NO_MEMORY;
/* This query could be further optimized by adding a
(&(sambaSID=<domain-sid>*)) so that only those aliases that are
@@ -3083,9 +3103,6 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
if (rc != LDAP_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
- *aliases = NULL;
- *num_aliases = 0;
-
ldap_struct = ldap_state->smbldap_state->ldap_struct;
for (entry = ldap_first_entry(ldap_struct, result);
@@ -3094,6 +3111,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
{
fstring sid_str;
DOM_SID sid;
+ uint32 rid;
if (!smbldap_get_single_attribute(ldap_struct, entry,
LDAP_ATTRIBUTE_SID,
@@ -3104,13 +3122,207 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
if (!string_to_sid(&sid, sid_str))
continue;
- add_sid_to_array_unique(&sid, aliases, num_aliases);
+ if (!sid_peek_check_rid(domain_sid, &sid, &rid))
+ continue;
+
+ add_rid_to_array_unique(mem_ctx, rid, alias_rids,
+ num_alias_rids);
}
ldap_msgfree(result);
return NT_STATUS_OK;
}
+static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ int num_rids,
+ uint32 *rids,
+ const char ***names,
+ uint32 **attrs)
+{
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)methods->private_data;
+ LDAP *ldap_struct = ldap_state->smbldap_state->ldap_struct;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *entry;
+ char *allsids = NULL;
+ char *tmp;
+ int i, rc, num_mapped;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
+ return pdb_default_lookup_rids(methods, mem_ctx, domain_sid,
+ num_rids, rids, names, attrs);
+
+ if (!sid_equal(domain_sid, get_global_sam_sid())) {
+ /* TODO: Sooner or later we need to look up BUILTIN rids as
+ * well. -- vl */
+ goto done;
+ }
+
+ (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
+ (*attrs) = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
+
+ if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_rids; i++)
+ (*attrs)[i] = SID_NAME_UNKNOWN;
+
+ allsids = strdup("");
+ if (allsids == NULL) return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_rids; i++) {
+ DOM_SID sid;
+ sid_copy(&sid, domain_sid);
+ sid_append_rid(&sid, rids[i]);
+ tmp = allsids;
+ asprintf(&allsids, "%s(sambaSid=%s)", allsids,
+ sid_string_static(&sid));
+ if (allsids == NULL) return NT_STATUS_NO_MEMORY;
+ free(tmp);
+ }
+
+ /* First look for users */
+
+ {
+ char *filter;
+ const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
+
+ asprintf(&filter, ("(&(objectClass=sambaSamAccount)(|%s))"),
+ allsids);
+ if (filter == NULL) return NT_STATUS_NO_MEMORY;
+
+ rc = smbldap_search(ldap_state->smbldap_state,
+ lp_ldap_user_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
+ &msg);
+
+ SAFE_FREE(filter);
+ }
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ num_mapped = 0;
+
+ for (entry = ldap_first_entry(ldap_struct, msg);
+ entry != NULL;
+ entry = ldap_next_entry(ldap_struct, entry))
+ {
+ uint32 rid;
+ int rid_index;
+ fstring str;
+
+ if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
+ get_global_sam_sid(),
+ &rid)) {
+ DEBUG(2, ("Could not find sid from ldap entry\n"));
+ continue;
+ }
+
+ if (!smbldap_get_single_attribute(ldap_struct, entry,
+ "uid", str, sizeof(str)-1)) {
+ DEBUG(2, ("Could not retrieve uid attribute\n"));
+ continue;
+ }
+
+ for (rid_index = 0; rid_index < num_rids; rid_index++) {
+ if (rid == rids[rid_index])
+ break;
+ }
+
+ if (rid_index == num_rids) {
+ DEBUG(2, ("Got a RID not asked for: %d\n", rid));
+ continue;
+ }
+
+ (*attrs)[rid_index] = SID_NAME_USER;
+ (*names)[rid_index] = talloc_strdup(mem_ctx, str);
+ if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+
+ num_mapped += 1;
+ }
+
+ if (num_mapped == num_rids) {
+ /* No need to look for groups anymore -- we're done */
+ result = NT_STATUS_OK;
+ goto done;
+ }
+
+ /* Same game for groups */
+
+ {
+ char *filter;
+ const char *ldap_attrs[] = { "cn", "sambaSid", NULL };
+
+ asprintf(&filter, ("(&(objectClass=sambaGroupMapping)(|%s))"),
+ allsids);
+ if (filter == NULL) return NT_STATUS_NO_MEMORY;
+
+ rc = smbldap_search(ldap_state->smbldap_state,
+ lp_ldap_group_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
+ &msg);
+
+ SAFE_FREE(filter);
+ }
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ for (entry = ldap_first_entry(ldap_struct, msg);
+ entry != NULL;
+ entry = ldap_next_entry(ldap_struct, entry))
+ {
+ uint32 rid;
+ int rid_index;
+ fstring str;
+
+ if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
+ get_global_sam_sid(),
+ &rid)) {
+ DEBUG(2, ("Could not find sid from ldap entry\n"));
+ continue;
+ }
+
+ if (!smbldap_get_single_attribute(ldap_struct, entry,
+ "cn", str, sizeof(str)-1)) {
+ DEBUG(2, ("Could not retrieve cn attribute\n"));
+ continue;
+ }
+
+ for (rid_index = 0; rid_index < num_rids; rid_index++) {
+ if (rid == rids[rid_index])
+ break;
+ }
+
+ if (rid_index == num_rids) {
+ DEBUG(2, ("Got a RID not asked for: %d\n", rid));
+ continue;
+ }
+
+ (*attrs)[rid_index] = SID_NAME_DOM_GRP;
+ (*names)[rid_index] = talloc_strdup(mem_ctx, str);
+ if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+ num_mapped += 1;
+ }
+
+ result = NT_STATUS_NONE_MAPPED;
+
+ if (num_mapped > 0)
+ result = (num_mapped == num_rids) ?
+ NT_STATUS_OK : STATUS_SOME_UNMAPPED;
+ done:
+ SAFE_FREE(allsids);
+
+ if (msg != NULL)
+ ldap_msgfree(msg);
+
+ return result;
+}
+
/**********************************************************************
Housekeeping
*********************************************************************/
@@ -3168,6 +3380,7 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
(*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
(*pdb_method)->enum_group_members = ldapsam_enum_group_members;
(*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
+ (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
/* TODO: Setup private data and free */
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 6be63e4f9d6..c7ff2f80b00 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -84,13 +84,11 @@ BOOL secrets_init(void)
*/
void *secrets_fetch(const char *key, size_t *size)
{
- TDB_DATA kbuf, dbuf;
+ TDB_DATA dbuf;
secrets_init();
if (!tdb)
return NULL;
- kbuf.dptr = (char *)key;
- kbuf.dsize = strlen(key);
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb, string_tdb_data(key));
if (size)
*size = dbuf.dsize;
return dbuf.dptr;
@@ -100,15 +98,11 @@ void *secrets_fetch(const char *key, size_t *size)
*/
BOOL secrets_store(const char *key, const void *data, size_t size)
{
- TDB_DATA kbuf, dbuf;
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = (char *)key;
- kbuf.dsize = strlen(key);
- dbuf.dptr = (char *)data;
- dbuf.dsize = size;
- return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
+ return tdb_store(tdb, string_tdb_data(key), make_tdb_data(data, size),
+ TDB_REPLACE) == 0;
}
@@ -116,13 +110,10 @@ BOOL secrets_store(const char *key, const void *data, size_t size)
*/
BOOL secrets_delete(const char *key)
{
- TDB_DATA kbuf;
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = (char *)key;
- kbuf.dsize = strlen(key);
- return tdb_delete(tdb, kbuf) == 0;
+ return tdb_delete(tdb, string_tdb_data(key)) == 0;
}
BOOL secrets_store_domain_sid(const char *domain, const DOM_SID *sid)
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
index 1fddfc79255..a9e1921e0d0 100644
--- a/source/passdb/util_sam_sid.c
+++ b/source/passdb/util_sam_sid.c
@@ -32,17 +32,11 @@ typedef struct _known_sid_users {
static struct sid_name_map_info
{
- DOM_SID *sid;
+ const DOM_SID *sid;
const char *name;
const known_sid_users *known_users;
} sid_name_map[MAX_SID_NAMES];
-extern DOM_SID global_sid_Builtin; /* Local well-known domain */
-extern DOM_SID global_sid_World_Domain; /* Everyone domain */
-extern DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
-extern DOM_SID global_sid_NT_Authority; /* NT Authority */
-
-
static BOOL sid_name_map_initialized = False;
/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
@@ -99,8 +93,6 @@ static void init_sid_name_map (void)
if (sid_name_map_initialized) return;
- generate_wellknown_sids();
-
if ((lp_security() == SEC_USER) && lp_domain_logons()) {
sid_name_map[i].sid = get_global_sam_sid();
/* This is not lp_workgroup() for good reason:
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index ad911c3b05b..40d815cead1 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -22,7 +22,7 @@
#include "includes.h"
-extern DOM_SID global_sid_World;
+extern struct current_user current_user;
static TDB_CONTEXT *tdb_forms; /* used for forms files */
static TDB_CONTEXT *tdb_drivers; /* used for driver files */
@@ -1494,7 +1494,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);
driver_unix_convert(new_dir, conn, NULL, &bad_path, &st);
- mkdir_internal(conn, new_dir);
+ mkdir_internal(conn, new_dir, bad_path);
/* 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:
@@ -5115,7 +5115,6 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
BOOL result;
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
- extern struct current_user current_user;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
/* If user is NULL then use the current_user structure */
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index 7c5de468701..25f4d9bd464 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -21,6 +21,8 @@
#include "includes.h"
+extern struct current_user current_user;
+
/***************************************************************************
open a print file and setup a fsp for it. This is a wrapper around
print_job_start().
@@ -30,7 +32,6 @@ 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;
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 5483005e1bd..572ecb373a8 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -45,7 +45,7 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
struct print_queue_update_context {
char* sharename;
- enum printing_types printing_type;
+ int printing_type;
char* lpqcommand;
};
@@ -235,7 +235,7 @@ void printing_end(void)
when asked for (and only when supported)
****************************************************************************/
-static struct printif *get_printer_fns_from_type( enum printing_types type )
+static struct printif *get_printer_fns_from_type( int type )
{
struct printif *printer_fns = &generic_printif;
@@ -907,7 +907,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
{
- TDB_DATA data, key;
+ TDB_DATA data;
int max_reported_jobs = lp_max_reported_jobs(pts->snum);
print_queue_struct *queue = pts->queue;
size_t len;
@@ -951,22 +951,19 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
queue[i].fs_file);
}
- key.dptr = "INFO/linear_queue_array";
- key.dsize = strlen(key.dptr);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
+ tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
+ TDB_REPLACE);
SAFE_FREE(data.dptr);
return;
}
static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
{
- TDB_DATA data, key;
+ TDB_DATA data;
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
ZERO_STRUCT(data);
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
SAFE_FREE(data.dptr);
ZERO_STRUCT(data);
@@ -1035,7 +1032,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
if ( check_pending
- && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time )
+ && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time )
&& msg_pending_time > 0
&& msg_pending_time <= time_now
&& (time_now - msg_pending_time) < 60 )
@@ -1382,7 +1379,7 @@ static void print_queue_update(int snum, BOOL force)
size_t len = 0;
size_t newlen;
struct tdb_print_db *pdb;
- enum printing_types type;
+ int type;
struct printif *current_printif;
fstrcpy( sharename, lp_const_servicename(snum));
@@ -1736,10 +1733,10 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
BOOL ret = False;
BOOL gotlock = False;
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
ZERO_STRUCT(data);
+ key = string_tdb_data("INFO/jobs_changed");
+
if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
goto out;
@@ -2057,7 +2054,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
static int get_queue_status(const char* sharename, print_status_struct *status)
{
fstring keystr;
- TDB_DATA data, key;
+ TDB_DATA data;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
int len;
@@ -2066,10 +2063,8 @@ static int get_queue_status(const char* sharename, print_status_struct *status)
if (status) {
ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
+ fstr_sprintf(keystr, "STATUS/%s", sharename);
+ data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
if (data.dptr) {
if (data.dsize == sizeof(print_status_struct))
/* this memcpy is ok since the status struct was
@@ -2179,18 +2174,17 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char
static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
{
- TDB_DATA data, key;
+ TDB_DATA data;
uint32 store_jobid;
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
SIVAL(&store_jobid, 0, jobid);
data.dptr = (char *)&store_jobid;
data.dsize = 4;
DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
- return (tdb_append(pdb->tdb, key, data) == 0);
+ return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
+ data) == 0);
}
/***************************************************************************
@@ -2429,7 +2423,7 @@ fail:
static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
{
- TDB_DATA data, key, cgdata;
+ TDB_DATA data, cgdata;
print_queue_struct *queue = NULL;
uint32 qcount = 0;
uint32 extra_count = 0;
@@ -2449,20 +2443,15 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
ZERO_STRUCT(data);
ZERO_STRUCT(cgdata);
- key.dptr = "INFO/linear_queue_array";
- key.dsize = strlen(key.dptr);
/* Get the stored queue data. */
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
if (data.dptr && data.dsize >= sizeof(qcount))
len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
/* Get the changed jobs list. */
- key.dptr = "INFO/jobs_changed";
- key.dsize = strlen(key.dptr);
-
- cgdata = tdb_fetch(pdb->tdb, key);
+ cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
extra_count = cgdata.dsize/4;
diff --git a/source/python/py_smb.c b/source/python/py_smb.c
index c3d59d4fb8c..ad83e469b24 100644
--- a/source/python/py_smb.c
+++ b/source/python/py_smb.c
@@ -212,7 +212,7 @@ static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw)
static char *kwlist[] = { "fnum", "offset", "size", NULL };
int fnum, offset=0, size=0;
ssize_t result;
- size_t fsize;
+ SMB_OFF_T fsize;
char *data;
PyObject *ret;
diff --git a/source/registry/reg_db.c b/source/registry/reg_db.c
index 5ac83293090..f93b7e1ffba 100644
--- a/source/registry/reg_db.c
+++ b/source/registry/reg_db.c
@@ -65,6 +65,13 @@ static BOOL init_registry_data( void )
return False;
regsubkey_ctr_destroy( &subkeys );
+#ifdef REG_TEST_CODE
+ pstrcpy( keyname, KEY_HKLM );
+ pstrcat( keyname, "/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" );
+ if ( !regdb_store_reg_keys( keyname, &subkeys ))
+ return False;
+#endif
+
regsubkey_ctr_init( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
diff --git a/source/registry/reg_eventlog.c b/source/registry/reg_eventlog.c
new file mode 100644
index 00000000000..cc2ffb5a057
--- /dev/null
+++ b/source/registry/reg_eventlog.c
@@ -0,0 +1,302 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * 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 "includes.h"
+
+/**********************************************************************
+ handle enumeration of values AT KEY_EVENTLOG
+ *********************************************************************/
+
+static int eventlog_topkey_values( char *key, REGVAL_CTR *val )
+{
+ int num_values = 0;
+ char *keystr, *key2 = NULL;
+ char *base, *new_path;
+ fstring evtlogname;
+ UNISTR2 data;
+ int iDisplayNameId;
+ int iMaxSize;
+
+ /*
+ * TODO - callout to get these values...
+ */
+
+ if ( key )
+ {
+ key2 = strdup( key );
+ keystr = key2;
+ reg_split_path( keystr, &base, &new_path );
+
+ iDisplayNameId = 0x00000100;
+ iMaxSize= 0x00080000;
+
+ fstrcpy( evtlogname, base );
+ DEBUG(10,("eventlog_topkey_values: subkey root=> [%s] subkey path=>[%s]\n", base,new_path));
+
+ if ( !new_path )
+ {
+ iDisplayNameId = 0x01;
+ regval_ctr_addvalue( val, "ErrorControl", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) );
+
+ init_unistr2( &data, "EventLog", UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "DisplayName", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ num_values = regval_ctr_numvals( val );
+
+
+ num_values = 0;
+ }
+ }
+
+ SAFE_FREE( key2 );
+ return num_values;
+}
+
+/**********************************************************************
+ handle enumeration of values below KEY_EVENTLOG\<Eventlog>
+ *********************************************************************/
+
+static int eventlog_subkey_values( char *key, REGVAL_CTR *val )
+{
+ int num_values = 0;
+ char *keystr, *key2 = NULL;
+ char *base, *new_path;
+ fstring evtlogname;
+ UNISTR2 data;
+ int iDisplayNameId;
+ int iMaxSize;
+ int iRetention;
+
+ /*
+ * TODO - callout to get these values...
+ */
+
+ if ( !key )
+ return num_values;
+
+ key2 = SMB_STRDUP( key );
+ keystr = key2;
+ reg_split_path( keystr, &base, &new_path );
+
+ iDisplayNameId = 0x00000100;
+ /* MaxSize is limited to 0xFFFF0000 (UINT_MAX - USHRT_MAX) as per MSDN documentation */
+ iMaxSize= 0xFFFF0000;
+ /* records in the samba log are not overwritten */
+ iRetention = 0xFFFFFFFF;
+
+ fstrcpy( evtlogname, base );
+ DEBUG(10,("eventlog_subpath_values_printer: eventlogname [%s]\n", base));
+ DEBUG(10,("eventlog_subpath_values_printer: new_path [%s]\n", new_path));
+ if ( !new_path )
+ {
+#if 0
+ regval_ctr_addvalue( val, "DisplayNameId", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) );
+
+ init_unistr2( &data, "%SystemRoot%\\system32\\els.dll", UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "DisplayNameFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+#endif
+ regval_ctr_addvalue( val, "MaxSize", REG_DWORD, (char*)&iMaxSize, sizeof(int));
+ regval_ctr_addvalue( val, "Retention", REG_DWORD, (char *)&iRetention, sizeof(int));
+#if 0
+ init_unistr2( &data, lp_logfile(), UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "File", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+#endif
+ init_unistr2( &data, base, UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "PrimaryModule", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ init_unistr2( &data, base, UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "Sources", REG_MULTI_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ num_values = regval_ctr_numvals( val );
+
+ }
+ else
+ {
+ iDisplayNameId = 0x07;
+ regval_ctr_addvalue( val, "CategoryCount", REG_DWORD, (char*)&iDisplayNameId, sizeof(int) );
+
+ init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE);
+ regval_ctr_addvalue( val, "CategoryMessageFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ num_values = regval_ctr_numvals( val );
+
+ num_values = 0;
+ }
+
+ SAFE_FREE( key2 );
+ return num_values;
+}
+
+
+/**********************************************************************
+ It is safe to assume that every registry path passed into on of
+ the exported functions here begins with KEY_EVENTLOG else
+ these functions would have never been called. This is a small utility
+ function to strip the beginning of the path and make a copy that the
+ caller can modify. Note that the caller is responsible for releasing
+ the memory allocated here.
+ **********************************************************************/
+
+static char* trim_eventlog_reg_path( char *path )
+{
+ char *p;
+ uint16 key_len = strlen(KEY_EVENTLOG);
+
+ /*
+ * sanity check...this really should never be True.
+ * It is only here to prevent us from accessing outside
+ * the path buffer in the extreme case.
+ */
+
+ if ( strlen(path) < key_len ) {
+ DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
+ DEBUG(0,("trim_reg_path: KEY_EVENTLOG => [%s]!\n", KEY_EVENTLOG));
+ return NULL;
+ }
+
+
+ p = path + strlen( KEY_EVENTLOG );
+
+ if ( *p == '\\' )
+ p++;
+
+ if ( *p )
+ return SMB_STRDUP(p);
+ else
+ return NULL;
+}
+/**********************************************************************
+ Enumerate registry subkey names given a registry path.
+ Caller is responsible for freeing memory to **subkeys
+ *********************************************************************/
+int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
+{
+ char *path;
+ BOOL top_level = False;
+ int num_subkeys = 0;
+ const char **evtlog_list;
+
+ path = trim_eventlog_reg_path( key );
+ DEBUG(10,("eventlog_subkey_info: entire key=>[%s] SUBkey=>[%s]\n", key,path));
+
+ /* check to see if we are dealing with the top level key */
+ num_subkeys = 0;
+
+ if ( !path )
+ top_level = True;
+
+ evtlog_list = lp_eventlog_list();
+ num_subkeys = 0;
+
+ if ( top_level )
+ {
+ /* todo - get the eventlog subkey values from the smb.conf file
+ for ( num_subkeys=0; num_subkeys<MAX_TOP_LEVEL_KEYS; num_subkeys++ )
+ regsubkey_ctr_addkey( subkey_ctr, top_level_keys[num_subkeys] ); */
+ DEBUG(10,("eventlog_subkey_info: Adding eventlog subkeys from globals\n"));
+ /* TODO - make this from the globals.szEventLogs list */
+
+ while (*evtlog_list)
+ {
+ DEBUG(10,("eventlog_subkey_info: Adding subkey =>[%s]\n",*evtlog_list));
+ regsubkey_ctr_addkey( subkey_ctr, *evtlog_list);
+ evtlog_list++;
+ num_subkeys++;
+ }
+ }
+ else
+ {
+ while (*evtlog_list && (0==num_subkeys) )
+ {
+ if (0 == StrCaseCmp(path,*evtlog_list))
+ {
+ DEBUG(10,("eventlog_subkey_info: Adding subkey [%s] for key =>[%s]\n",path,*evtlog_list));
+ regsubkey_ctr_addkey( subkey_ctr, *evtlog_list);
+ num_subkeys = 1;
+ }
+ evtlog_list++;
+ }
+
+ if (0==num_subkeys)
+ DEBUG(10,("eventlog_subkey_info: No match on SUBkey=>[%s]\n", path));
+ }
+
+ SAFE_FREE( path );
+ return num_subkeys;
+}
+
+/**********************************************************************
+ Enumerate registry values given a registry path.
+ Caller is responsible for freeing memory
+ *********************************************************************/
+
+int eventlog_value_info( char *key, REGVAL_CTR *val )
+{
+ char *path;
+ BOOL top_level = False;
+ int num_values = 0;
+
+ DEBUG(10,("eventlog_value_info: key=>[%s]\n", key));
+
+ path = trim_eventlog_reg_path( key );
+
+ /* check to see if we are dealing with the top level key */
+
+ if ( !path )
+ top_level = True;
+ if ( top_level )
+ num_values = eventlog_topkey_values(path,val);
+ else
+ {
+ DEBUG(10,("eventlog_value_info: SUBkey=>[%s]\n", path));
+ num_values = eventlog_subkey_values(path,val);
+ }
+ return num_values;
+}
+
+/**********************************************************************
+ Stub function which always returns failure since we don't want
+ people storing eventlog information directly via registry calls
+ (for now at least)
+ *********************************************************************/
+BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
+{
+ return False;
+}
+
+/**********************************************************************
+ Stub function which always returns failure since we don't want
+ people storing eventlog information directly via registry calls
+ (for now at least)
+ *********************************************************************/
+BOOL eventlog_store_value( char *key, REGVAL_CTR *val )
+{
+ return False;
+}
+
+/*
+ * Table of function pointers for accessing eventlog data
+ */
+REGISTRY_OPS eventlog_ops = {
+ eventlog_subkey_info,
+ eventlog_value_info,
+ eventlog_store_subkey,
+ eventlog_store_value
+};
diff --git a/source/registry/reg_frontend.c b/source/registry/reg_frontend.c
index 1f8c9362901..9f8747ef378 100644
--- a/source/registry/reg_frontend.c
+++ b/source/registry/reg_frontend.c
@@ -26,13 +26,14 @@
#define DBGC_CLASS DBGC_RPC_SRV
extern REGISTRY_OPS printing_ops;
+extern REGISTRY_OPS eventlog_ops;
extern REGISTRY_OPS regdb_ops; /* these are the default */
/* array of REGISTRY_HOOK's which are read into a tree for easy access */
-
REGISTRY_HOOK reg_hooks[] = {
{ KEY_PRINTING, &printing_ops },
+ { KEY_EVENTLOG, &eventlog_ops },
{ NULL, NULL }
};
@@ -124,6 +125,8 @@ BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index
*subkey = NULL;
/* simple caching for performance; very basic heuristic */
+
+ DEBUG(8,("fetch_reg_keys_specific: Looking for key [%d] of [%s]\n", key_index, key->name));
if ( !ctr_init ) {
DEBUG(8,("fetch_reg_keys_specific: Initializing cache of subkeys for [%s]\n", key->name));
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index 45b7509d451..f404b5144a6 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -24,6 +24,7 @@
*/
#include "includes.h"
+#include "rpc_client.h"
/** @defgroup lsa LSA - Local Security Architecture
* @ingroup rpc_client
@@ -636,89 +637,68 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
char ***domain_names, DOM_SID **domain_sids)
{
prs_struct qbuf, rbuf;
- LSA_Q_ENUM_TRUST_DOM q;
- LSA_R_ENUM_TRUST_DOM r;
- NTSTATUS result;
+ LSA_Q_ENUM_TRUST_DOM in;
+ LSA_R_ENUM_TRUST_DOM out;
int i;
+ fstring tmp;
- 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 */
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
/* 64k is enough for about 2000 trusted domains */
- init_q_enum_trust_dom(&q, pol, *enum_ctx, 0x10000);
-
- if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+
+ init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
- result = r.status;
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM,
+ in, out,
+ qbuf, rbuf,
+ lsa_io_q_enum_trust_dom,
+ lsa_io_r_enum_trust_dom,
+ NT_STATUS_UNSUCCESSFUL );
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
- /* An actual error ocured */
+ /* check for an actual error */
- goto done;
+ if ( !NT_STATUS_IS_OK(out.status)
+ && !NT_STATUS_EQUAL(out.status, NT_STATUS_NO_MORE_ENTRIES)
+ && !NT_STATUS_EQUAL(out.status, STATUS_MORE_ENTRIES) )
+ {
+ return out.status;
}
-
+
/* Return output parameters */
- if (r.num_domains) {
+ *num_domains = out.count;
+ *enum_ctx = out.enum_context;
+
+ if ( out.count ) {
/* Allocate memory for trusted domain names and sids */
- *domain_names = TALLOC_ARRAY(mem_ctx, char *, r.num_domains);
-
- if (!*domain_names) {
+ if ( !(*domain_names = TALLOC_ARRAY(mem_ctx, char *, out.count)) ) {
DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
+ return NT_STATUS_NO_MEMORY;
}
- *domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.num_domains);
- if (!domain_sids) {
+ if ( !(*domain_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, out.count)) ) {
DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
+ return NT_STATUS_NO_MEMORY;
}
/* Copy across names and sids */
- for (i = 0; i < r.num_domains; i++) {
- fstring tmp;
+ for (i = 0; i < out.count; i++) {
- unistr2_to_ascii(tmp, &r.uni_domain_name[i],
- sizeof(tmp) - 1);
+ rpcstr_pull( tmp, out.domlist->domains[i].name.string->buffer,
+ sizeof(tmp), out.domlist->domains[i].name.length, 0);
(*domain_names)[i] = talloc_strdup(mem_ctx, tmp);
- sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid);
+
+ sid_copy(&(*domain_sids)[i], &out.domlist->domains[i].sid->sid );
}
}
- *num_domains = r.num_domains;
- *enum_ctx = r.enum_context;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return out.status;
}
@@ -1260,12 +1240,16 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
- privileges = TALLOC_ARRAY(mem_ctx, fstring, *count);
- names = TALLOC_ARRAY(mem_ctx, char *, *count);
+ privileges = TALLOC_ARRAY( mem_ctx, fstring, *count );
+ names = TALLOC_ARRAY( mem_ctx, char *, *count );
+
for ( i=0; i<*count; i++ ) {
- /* ensure NULL termination ... what a hack */
- pull_ucs2(NULL, privileges[i], r.rights.strings[i].string.buffer,
- sizeof(fstring), r.rights.strings[i].string.uni_str_len*2 , 0);
+ UNISTR4 *uni_string = &r.rights->strings[i];
+
+ if ( !uni_string->string )
+ continue;
+
+ rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE );
/* now copy to the return array */
names[i] = talloc_strdup( mem_ctx, privileges[i] );
@@ -1284,7 +1268,8 @@ done:
NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID sid,
- uint32 count, const char **privs_name)
+
+uint32 count, const char **privs_name)
{
prs_struct qbuf, rbuf;
LSA_Q_ADD_ACCT_RIGHTS q;
diff --git a/source/rpc_client/cli_reg.c b/source/rpc_client/cli_reg.c
index 25f56085bac..0d7d194850c 100644
--- a/source/rpc_client/cli_reg.c
+++ b/source/rpc_client/cli_reg.c
@@ -2,11 +2,12 @@
Unix SMB/CIFS implementation.
RPC Pipe client
- Copyright (C) Andrew Tridgell 1992-1998,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- Copyright (C) Paul Ashton 1997-1998.
+ Copyright (C) Andrew Tridgell 1992-2000,
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ Copyright (C) Paul Ashton 1997-2000.
Copyright (C) Jeremy Allison 1999.
Copyright (C) Simo Sorce 2001
+ Copyright (C) Jeremy Cooper 2004
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,6 +28,51 @@
/* Shutdown a server */
+/* internal connect to a registry hive root (open a registry policy) */
+
+static WERROR cli_reg_open_hive_int(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, uint16 op_code,
+ const char *op_name,
+ uint32 access_mask, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_OPEN_HIVE q_o;
+ REG_R_OPEN_HIVE r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ ZERO_STRUCT(q_o);
+ ZERO_STRUCT(r_o);
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ init_reg_q_open_hive(&q_o, access_mask);
+
+ /* Marshall the query parameters */
+ if (!reg_io_q_open_hive("", &q_o, &qbuf, 0))
+ goto done;
+
+ /* Send the request, receive the response */
+ if (!rpc_api_pipe_req(cli, PI_WINREG, op_code, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall the response */
+ if (!reg_io_r_open_hive("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result))
+ *hnd = r_o.pol;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+
WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
const char *msg, uint32 timeout, BOOL do_reboot,
BOOL force)
@@ -90,7 +136,7 @@ WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
!rpc_api_pipe_req(cli, PI_WINREG, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
goto done;
- /* Unmarshall response */
+ /* Unmarshall response */
if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0))
result = r_s.status;
@@ -101,3 +147,670 @@ done:
return result;
}
+
+/* connect to a registry hive root (open a registry policy) */
+
+WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ uint32 reg_type, uint32 access_mask,
+ POLICY_HND *reg_hnd)
+{ uint16 op_code;
+ const char *op_name;
+
+ ZERO_STRUCTP(reg_hnd);
+
+ switch (reg_type)
+ {
+ case HKEY_CLASSES_ROOT:
+ op_code = REG_OPEN_HKCR;
+ op_name = "REG_OPEN_HKCR";
+ break;
+ case HKEY_LOCAL_MACHINE:
+ op_code = REG_OPEN_HKLM;
+ op_name = "REG_OPEN_HKLM";
+ break;
+ case HKEY_USERS:
+ op_code = REG_OPEN_HKU;
+ op_name = "REG_OPEN_HKU";
+ break;
+ case HKEY_PERFORMANCE_DATA:
+ op_code = REG_OPEN_HKPD;
+ op_name = "REG_OPEN_HKPD";
+ break;
+ default:
+ return WERR_INVALID_PARAM;
+ }
+
+ return cli_reg_open_hive_int(cli, mem_ctx, op_code, op_name,
+ access_mask, reg_hnd);
+}
+
+/****************************************************************************
+do a REG Unknown 0xB command. sent after a create key or create value.
+this might be some sort of "sync" or "refresh" command, sent after
+modification of the registry...
+****************************************************************************/
+WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_FLUSH_KEY q_o;
+ REG_R_FLUSH_KEY r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_flush_key(&q_o, hnd);
+
+ if (!reg_io_q_flush_key("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_FLUSH_KEY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (reg_io_r_flush_key("", &r_o, &rbuf, 0))
+ result = r_o.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Query Key
+****************************************************************************/
+WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ char *key_class, uint32 *class_len,
+ uint32 *num_subkeys, uint32 *max_subkeylen,
+ uint32 *max_classlen, uint32 *num_values,
+ uint32 *max_valnamelen, uint32 *max_valbufsize,
+ uint32 *sec_desc, NTTIME *mod_time)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_QUERY_KEY q_o;
+ REG_R_QUERY_KEY r_o;
+ uint32 saved_class_len = *class_len;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_query_key( &q_o, hnd, key_class );
+
+ if (!reg_io_q_query_key("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_QUERY_KEY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_query_key("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER)) {
+ *class_len = r_o.class.string->uni_max_len;
+ goto done;
+ } else if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ *class_len = r_o.class.string->uni_max_len;
+ unistr2_to_ascii(key_class, r_o.class.string, saved_class_len-1);
+ *num_subkeys = r_o.num_subkeys ;
+ *max_subkeylen = r_o.max_subkeylen ;
+ *num_values = r_o.num_values ;
+ *max_valnamelen = r_o.max_valnamelen;
+ *max_valbufsize = r_o.max_valbufsize;
+ *sec_desc = r_o.sec_desc ;
+ *mod_time = r_o.mod_time ;
+ /* Maybe: *max_classlen = r_o.reserved; */
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Unknown 1A
+****************************************************************************/
+WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, uint32 *unk)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_GETVERSION q_o;
+ REG_R_GETVERSION r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_getversion(&q_o, hnd);
+
+ if (!reg_io_q_getversion("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_GETVERSION, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_getversion("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result))
+ if (unk != NULL)
+ *unk = r_o.unknown;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Query Info
+****************************************************************************/
+WERROR cli_reg_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, const char *val_name,
+ uint32 *type, REGVAL_BUFFER *buffer)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_INFO q_o;
+ REG_R_INFO r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_info(&q_o, hnd, val_name, buffer);
+
+ if (!reg_io_q_info("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_INFO, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_info("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result)) {
+ *type = *r_o.type;
+ *buffer = *r_o.value;
+ }
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Set Key Security
+****************************************************************************/
+WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, uint32 sec_info,
+ size_t secdesc_size, SEC_DESC *sec_desc)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_SET_KEY_SEC q_o;
+ REG_R_SET_KEY_SEC r_o;
+ SEC_DESC_BUF *sec_desc_buf;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ /*
+ * Flatten the security descriptor.
+ */
+ sec_desc_buf = make_sec_desc_buf(mem_ctx, secdesc_size, sec_desc);
+ if (sec_desc_buf == NULL)
+ goto done;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_desc_buf);
+
+ if (!reg_io_q_set_key_sec("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_KEY_SEC, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (reg_io_r_set_key_sec("", &r_o, &rbuf, 0))
+ result = r_o.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+
+/****************************************************************************
+do a REG Query Key Security
+****************************************************************************/
+WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, uint32 sec_info,
+ uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_GET_KEY_SEC q_o;
+ REG_R_GET_KEY_SEC r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf);
+
+ if (!reg_io_q_get_key_sec("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_GET_KEY_SEC, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ r_o.data = sec_buf;
+
+ if (*sec_buf_size != 0)
+ {
+ sec_buf->sec = (SEC_DESC*)talloc(mem_ctx, *sec_buf_size);
+ }
+
+ if (!reg_io_r_get_key_sec("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result))
+ (*sec_buf_size) = r_o.data->len;
+ else if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER))
+ {
+ /*
+ * get the maximum buffer size: it was too small
+ */
+ (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+ }
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Delete Value
+****************************************************************************/
+WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *val_name)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_DELETE_VALUE q_o;
+ REG_R_DELETE_VALUE r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_delete_val(&q_o, hnd, val_name);
+
+ if (!reg_io_q_delete_val("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_VALUE, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (reg_io_r_delete_val("", &r_o, &rbuf, 0))
+ result = r_o.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Delete Key
+****************************************************************************/
+WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *key_name)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_DELETE_KEY q_o;
+ REG_R_DELETE_KEY r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_delete_key(&q_o, hnd, key_name);
+
+ if (!reg_io_q_delete_key("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_KEY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (reg_io_r_delete_key("", &r_o, &rbuf, 0))
+ result = r_o.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Create Key
+****************************************************************************/
+WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *key_name, char *key_class,
+ uint32 access_desired, POLICY_HND *key)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_CREATE_KEY q_o;
+ REG_R_CREATE_KEY r_o;
+ SEC_DESC *sec;
+ SEC_DESC_BUF *sec_buf;
+ size_t sec_len;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ ZERO_STRUCT(q_o);
+
+ if ((sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE,
+ NULL, NULL, NULL, NULL, &sec_len)) == NULL)
+ goto done;
+
+ if ((sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) == NULL)
+ goto done;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_create_key(&q_o, hnd, key_name, key_class, access_desired, sec_buf);
+
+ if (!reg_io_q_create_key("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_CREATE_KEY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_create_key("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result))
+ *key = r_o.key_pol;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Enum Key
+****************************************************************************/
+WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, int key_index, fstring key_name,
+ uint32 *unk_1, uint32 *unk_2, time_t *mod_time)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_ENUM_KEY q_o;
+ REG_R_ENUM_KEY r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_enum_key(&q_o, hnd, key_index);
+
+ if (!reg_io_q_enum_key("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_KEY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_enum_key("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result)) {
+ (*unk_1) = r_o.unknown_1;
+ (*unk_2) = r_o.unknown_2;
+ unistr3_to_ascii(key_name, &r_o.key_name,
+ sizeof(fstring)-1);
+ (*mod_time) = nt_time_to_unix(&r_o.time);
+ }
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Create Value
+****************************************************************************/
+WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *val_name, uint32 type,
+ RPC_DATA_BLOB *data)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_SET_VALUE q_o;
+ REG_R_SET_VALUE r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_set_val(&q_o, hnd, val_name, type, data);
+
+ if (!reg_io_q_set_val("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_VALUE, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshal response */
+
+ if (reg_io_r_set_val("", &r_o, &rbuf, 0))
+ result = r_o.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Enum Value
+****************************************************************************/
+WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, int val_index, int max_valnamelen,
+ int max_valbufsize, fstring val_name,
+ uint32 *val_type, REGVAL_BUFFER *value)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_ENUM_VALUE q_o;
+ REG_R_ENUM_VALUE r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_enum_val(&q_o, hnd, val_index, val_name, max_valbufsize);
+
+ if (!reg_io_q_enum_val("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_VALUE, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarshall response */
+
+ if (!reg_io_r_enum_val("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result) ||
+ NT_STATUS_EQUAL(result, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ (*val_type) = *r_o.type;
+ unistr2_to_ascii(val_name, r_o.name.string, sizeof(fstring)-1);
+ *value = *r_o.value;
+ }
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Open Key
+****************************************************************************/
+WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd, char *key_name,
+ uint32 access_desired, POLICY_HND *key_hnd)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_OPEN_ENTRY q_o;
+ REG_R_OPEN_ENTRY r_o;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_open_entry(&q_o, hnd, key_name, access_desired);
+
+ /* turn parameters into data stream */
+ if (!reg_io_q_open_entry("", &q_o, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_OPEN_ENTRY, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_o);
+
+ /* Unmarsall response */
+
+ if (!reg_io_r_open_entry("", &r_o, &rbuf, 0))
+ goto done;
+
+ result = r_o.status;
+ if (NT_STATUS_IS_OK(result))
+ *key_hnd = r_o.pol;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+/****************************************************************************
+do a REG Close
+****************************************************************************/
+WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct qbuf;
+ REG_Q_CLOSE q_c;
+ REG_R_CLOSE r_c;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_reg_q_close(&q_c, hnd);
+
+ if (!reg_io_q_close("", &q_c, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_CLOSE, &qbuf, &rbuf))
+ goto done;
+
+ ZERO_STRUCT(r_c);
+
+ /* Unmarshall response */
+
+ if (reg_io_r_close("", &r_c, &rbuf, 0))
+ result = r_c.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return result;
+}
+
+
diff --git a/source/rpc_client/cli_shutdown.c b/source/rpc_client/cli_shutdown.c
index 9ad0510d1db..c342f255a9f 100644
--- a/source/rpc_client/cli_shutdown.c
+++ b/source/rpc_client/cli_shutdown.c
@@ -36,9 +36,10 @@ NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
prs_struct rbuf;
SHUTDOWN_Q_INIT q_s;
SHUTDOWN_R_INIT r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ WERROR result = WERR_GENERAL_FAILURE;
- if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
+ if (msg == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
ZERO_STRUCT (q_s);
ZERO_STRUCT (r_s);
@@ -63,7 +64,48 @@ done:
prs_mem_free(&rbuf);
prs_mem_free(&qbuf);
- return result;
+ return werror_to_ntstatus(result);
+}
+
+/* Shutdown a server */
+
+NTSTATUS cli_shutdown_init_ex(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+ const char *msg, uint32 timeout, BOOL do_reboot,
+ BOOL force, uint32 reason)
+{
+ prs_struct qbuf;
+ prs_struct rbuf;
+ SHUTDOWN_Q_INIT_EX q_s;
+ SHUTDOWN_R_INIT_EX r_s;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ if (msg == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ ZERO_STRUCT (q_s);
+ ZERO_STRUCT (r_s);
+
+ prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_shutdown_q_init_ex(&q_s, msg, timeout, do_reboot, force, reason);
+
+ if (!shutdown_io_q_init_ex("", &q_s, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_INIT_EX, &qbuf, &rbuf))
+ goto done;
+
+ /* Unmarshall response */
+
+ if(shutdown_io_r_init_ex("", &r_s, &rbuf, 0))
+ result = r_s.status;
+
+done:
+ prs_mem_free(&rbuf);
+ prs_mem_free(&qbuf);
+
+ return werror_to_ntstatus(result);
}
@@ -75,7 +117,7 @@ NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
prs_struct qbuf;
SHUTDOWN_Q_ABORT q_s;
SHUTDOWN_R_ABORT r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ WERROR result = WERR_GENERAL_FAILURE;
ZERO_STRUCT (q_s);
ZERO_STRUCT (r_s);
@@ -100,5 +142,5 @@ done:
prs_mem_free(&rbuf);
prs_mem_free(&qbuf );
- return result;
+ return werror_to_ntstatus(result);
}
diff --git a/source/rpc_client/cli_spoolss.c b/source/rpc_client/cli_spoolss.c
index 6ce74fed665..518c20ff9b0 100644
--- a/source/rpc_client/cli_spoolss.c
+++ b/source/rpc_client/cli_spoolss.c
@@ -31,25 +31,13 @@
* @{
**/
-/**********************************************************************
- Initialize a new spoolss buff for use by a client rpc
-**********************************************************************/
-static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
-{
- buffer->ptr = (size != 0);
- buffer->size = size;
- buffer->string_at_end = size;
- prs_init(&buffer->prs, size, ctx, MARSHALL);
- buffer->struct_start = prs_offset(&buffer->prs);
-}
-
/*********************************************************************
Decode various spoolss rpc's and info levels
********************************************************************/
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PRINTER_INFO_0 **info)
{
uint32 i;
@@ -69,7 +57,7 @@ static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PRINTER_INFO_1 **info)
{
uint32 i;
@@ -89,7 +77,7 @@ static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PRINTER_INFO_2 **info)
{
uint32 i;
@@ -111,7 +99,7 @@ static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PRINTER_INFO_3 **info)
{
uint32 i;
@@ -132,7 +120,7 @@ static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PRINTER_INFO_7 **info)
{
uint32 i;
@@ -153,7 +141,7 @@ static void decode_printer_info_7(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PORT_INFO_1 **info)
{
uint32 i;
@@ -173,7 +161,7 @@ static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, PORT_INFO_2 **info)
{
uint32 i;
@@ -193,7 +181,7 @@ static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, DRIVER_INFO_1 **info)
{
uint32 i;
@@ -213,7 +201,7 @@ static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, DRIVER_INFO_2 **info)
{
uint32 i;
@@ -233,7 +221,7 @@ static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, DRIVER_INFO_3 **info)
{
uint32 i;
@@ -253,7 +241,7 @@ static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 returned, DRIVER_DIRECTORY_1 **info
)
{
@@ -430,7 +418,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_struct qbuf, rbuf;
SPOOL_Q_ENUMPRINTERS q;
SPOOL_R_ENUMPRINTERS r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
@@ -438,7 +426,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -525,7 +513,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_struct qbuf, rbuf;
SPOOL_Q_ENUMPORTS q;
SPOOL_R_ENUMPORTS r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
fstring server;
@@ -537,7 +525,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -600,7 +588,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTER q;
SPOOL_R_GETPRINTER r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
ZERO_STRUCT(q);
@@ -608,7 +596,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -749,7 +737,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTERDRIVER2 q;
SPOOL_R_GETPRINTERDRIVER2 r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
fstring server;
@@ -761,7 +749,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -830,7 +818,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
prs_struct qbuf, rbuf;
SPOOL_Q_ENUMPRINTERDRIVERS q;
SPOOL_R_ENUMPRINTERDRIVERS r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
fstring server;
@@ -842,7 +830,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -916,7 +904,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTERDRIVERDIR q;
SPOOL_R_GETPRINTERDRIVERDIR r;
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
WERROR result = W_ERROR(ERRgeneral);
fstring server;
@@ -928,7 +916,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1204,7 +1192,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
SPOOL_R_GETPRINTPROCESSORDIRECTORY r;
int level = 1;
WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1216,7 +1204,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
/* Initialise input parameters */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getprintprocessordirectory(
&q, name, environment, level, &buffer, offered);
@@ -1388,14 +1376,14 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SPOOL_Q_GETFORM q;
SPOOL_R_GETFORM r;
WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1494,7 +1482,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 num_forms, FORM_1 **forms)
{
int i;
@@ -1530,14 +1518,14 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SPOOL_Q_ENUMFORMS q;
SPOOL_R_ENUMFORMS r;
WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1576,7 +1564,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 num_jobs, JOB_INFO_1 **jobs)
{
uint32 i;
@@ -1588,7 +1576,7 @@ static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
smb_io_job_info_1("", buffer, &((*jobs)[i]), 0);
}
-static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer,
+static void decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
uint32 num_jobs, JOB_INFO_2 **jobs)
{
uint32 i;
@@ -1611,14 +1599,14 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SPOOL_Q_ENUMJOBS q;
SPOOL_R_ENUMJOBS r;
WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
@@ -1728,14 +1716,14 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SPOOL_Q_GETJOB q;
SPOOL_R_GETJOB r;
WERROR result = W_ERROR(ERRgeneral);
- NEW_BUFFER buffer;
+ RPC_BUFFER buffer;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
- init_buffer(&buffer, offered, mem_ctx);
+ rpcbuf_init(&buffer, offered, mem_ctx);
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
diff --git a/source/rpc_client/cli_svcctl.c b/source/rpc_client/cli_svcctl.c
new file mode 100644
index 00000000000..9f80bb79a39
--- /dev/null
+++ b/source/rpc_client/cli_svcctl.c
@@ -0,0 +1,415 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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 "includes.h"
+#include "rpc_client.h"
+
+struct svc_state_msg {
+ uint32 flag;
+ const char *message;
+};
+
+static struct svc_state_msg state_msg_table[] = {
+ { SVCCTL_STOPPED, "stopped" },
+ { SVCCTL_START_PENDING, "start pending" },
+ { SVCCTL_STOP_PENDING, "stop pending" },
+ { SVCCTL_RUNNING, "running" },
+ { SVCCTL_CONTINUE_PENDING, "resume pending" },
+ { SVCCTL_PAUSE_PENDING, "pause pending" },
+ { SVCCTL_PAUSED, "paused" },
+ { 0, NULL }
+};
+
+
+/********************************************************************
+********************************************************************/
+const char* svc_status_string( uint32 state )
+{
+ static fstring msg;
+ int i;
+
+ fstr_sprintf( msg, "Unknown State [%d]", state );
+
+ for ( i=0; state_msg_table[i].message; i++ ) {
+ if ( state_msg_table[i].flag == state ) {
+ fstrcpy( msg, state_msg_table[i].message );
+ break;
+ }
+ }
+
+ return msg;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, uint32 access_desired )
+{
+ SVCCTL_Q_OPEN_SCMANAGER in;
+ SVCCTL_R_OPEN_SCMANAGER out;
+ prs_struct qbuf, rbuf;
+ fstring server;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ /* leave the database name NULL to get the default service db */
+
+ in.database = NULL;
+
+ /* set the server name */
+
+ if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) )
+ return WERR_NOMEM;
+ fstr_sprintf( server, "\\\\%s", cli->desthost );
+ init_unistr2( in.servername, server, UNI_STR_TERMINATE );
+
+ in.access = access_desired;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_open_scmanager,
+ svcctl_io_r_open_scmanager,
+ WERR_GENERAL_FAILURE );
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( hSCM, &out.handle, sizeof(POLICY_HND) );
+
+ return out.status;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, POLICY_HND *hService,
+ const char *servicename, uint32 access_desired )
+{
+ SVCCTL_Q_OPEN_SERVICE in;
+ SVCCTL_R_OPEN_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
+ init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE );
+ in.access = access_desired;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_open_service,
+ svcctl_io_r_open_service,
+ WERR_GENERAL_FAILURE );
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( hService, &out.handle, sizeof(POLICY_HND) );
+
+ return out.status;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
+{
+ SVCCTL_Q_CLOSE_SERVICE in;
+ SVCCTL_R_CLOSE_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CLOSE_SERVICE,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_close_service,
+ svcctl_io_r_close_service,
+ WERR_GENERAL_FAILURE );
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, uint32 type, uint32 state,
+ uint32 *returned, ENUM_SERVICES_STATUS **service_array )
+{
+ SVCCTL_Q_ENUM_SERVICES_STATUS in;
+ SVCCTL_R_ENUM_SERVICES_STATUS out;
+ prs_struct qbuf, rbuf;
+ uint32 resume = 0;
+ ENUM_SERVICES_STATUS *services;
+ int i;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ /* setup the request */
+
+ memcpy( &in.handle, hSCM, sizeof(POLICY_HND) );
+
+ in.type = type;
+ in.state = state;
+ in.resume = &resume;
+
+ /* first time is to get the buffer size */
+ in.buffer_size = 0;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_enum_services_status,
+ svcctl_io_r_enum_services_status,
+ WERR_GENERAL_FAILURE );
+
+ /* second time with correct buffer size...should be ok */
+
+ if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
+ in.buffer_size = out.needed;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_enum_services_status,
+ svcctl_io_r_enum_services_status,
+ WERR_GENERAL_FAILURE );
+ }
+
+ if ( !W_ERROR_IS_OK(out.status) )
+ return out.status;
+
+ /* pull out the data */
+ if ( !(services = TALLOC_ARRAY( mem_ctx, ENUM_SERVICES_STATUS, out.returned )) )
+ return WERR_NOMEM;
+
+ for ( i=0; i<out.returned; i++ ) {
+ svcctl_io_enum_services_status( "", &services[i], &out.buffer, 0 );
+ }
+
+ *service_array = services;
+ *returned = out.returned;
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService, SERVICE_STATUS *status )
+{
+ SVCCTL_Q_QUERY_STATUS in;
+ SVCCTL_R_QUERY_STATUS out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_query_status,
+ svcctl_io_r_query_status,
+ WERR_GENERAL_FAILURE );
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService, SERVICE_CONFIG *config )
+{
+ SVCCTL_Q_QUERY_SERVICE_CONFIG in;
+ SVCCTL_R_QUERY_SERVICE_CONFIG out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+ in.buffer_size = 0;
+
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_query_service_config,
+ svcctl_io_r_query_service_config,
+ WERR_GENERAL_FAILURE );
+
+ if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
+ in.buffer_size = out.needed;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_query_service_config,
+ svcctl_io_r_query_service_config,
+ WERR_GENERAL_FAILURE );
+ }
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( config, &out.config, sizeof(SERVICE_CONFIG) );
+
+ config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+
+ copy_unistr2( config->executablepath, out.config.executablepath );
+ copy_unistr2( config->loadordergroup, out.config.loadordergroup );
+ copy_unistr2( config->dependencies, out.config.dependencies );
+ copy_unistr2( config->startname, out.config.startname );
+ copy_unistr2( config->displayname, out.config.displayname );
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService,
+ const char **parm_array, uint32 parmcount )
+{
+ SVCCTL_Q_START_SERVICE in;
+ SVCCTL_R_START_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+
+ in.parmcount = 0;
+ in.parameters = NULL;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_start_service,
+ svcctl_io_r_start_service,
+ WERR_GENERAL_FAILURE );
+
+ return out.status;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService, uint32 control,
+ SERVICE_STATUS *status )
+{
+ SVCCTL_Q_CONTROL_SERVICE in;
+ SVCCTL_R_CONTROL_SERVICE out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+ in.control = control;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_control_service,
+ svcctl_io_r_control_service,
+ WERR_GENERAL_FAILURE );
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
+
+ return out.status;
+}
+
+
+/*******************************************************************
+*******************************************************************/
+
+WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hService, fstring displayname )
+{
+ SVCCTL_Q_GET_DISPLAY_NAME in;
+ SVCCTL_R_GET_DISPLAY_NAME out;
+ prs_struct qbuf, rbuf;
+
+ ZERO_STRUCT(in);
+ ZERO_STRUCT(out);
+
+ memcpy( &in.handle, hService, sizeof(POLICY_HND) );
+ in.display_name_len = 0;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_get_display_name,
+ svcctl_io_r_get_display_name,
+ WERR_GENERAL_FAILURE );
+
+ /* second time with correct buffer size...should be ok */
+
+ if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
+ in.display_name_len = out.display_name_len;
+
+ CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
+ in, out,
+ qbuf, rbuf,
+ svcctl_io_q_get_display_name,
+ svcctl_io_r_get_display_name,
+ WERR_GENERAL_FAILURE );
+ }
+
+ if ( !W_ERROR_IS_OK( out.status ) )
+ return out.status;
+
+ rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
+
+ return out.status;
+}
+
diff --git a/source/rpc_parse/parse_buffer.c b/source/rpc_parse/parse_buffer.c
new file mode 100644
index 00000000000..a48d5cfa982
--- /dev/null
+++ b/source/rpc_parse/parse_buffer.c
@@ -0,0 +1,491 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * 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-2005,
+ * Copyright (C) Tim Potter 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
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/**********************************************************************
+ Initialize a new spoolss buff for use by a client rpc
+**********************************************************************/
+void rpcbuf_init(RPC_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
+{
+ buffer->size = size;
+ buffer->string_at_end = size;
+ prs_init(&buffer->prs, size, ctx, MARSHALL);
+ buffer->struct_start = prs_offset(&buffer->prs);
+}
+
+/*******************************************************************
+ Read/write a RPC_BUFFER struct.
+********************************************************************/
+
+BOOL prs_rpcbuffer(const char *desc, prs_struct *ps, int depth, RPC_BUFFER *buffer)
+{
+ prs_debug(ps, depth, desc, "prs_rpcbuffer");
+ depth++;
+
+ /* reading */
+ if (UNMARSHALLING(ps)) {
+ buffer->size=0;
+ buffer->string_at_end=0;
+
+ if (!prs_uint32("size", ps, depth, &buffer->size))
+ return False;
+
+ /*
+ * JRA. I'm not sure if the data in here is in big-endian format if
+ * the client is big-endian. Leave as default (little endian) for now.
+ */
+
+ if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
+ return False;
+
+ if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
+ return False;
+
+ if (!prs_set_offset(&buffer->prs, 0))
+ return False;
+
+ if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
+ return False;
+
+ buffer->string_at_end=buffer->size;
+
+ return True;
+ }
+ else {
+ BOOL ret = False;
+
+ if (!prs_uint32("size", ps, depth, &buffer->size))
+ goto out;
+
+ if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
+ goto out;
+
+ ret = True;
+ out:
+
+ /* We have finished with the data in buffer->prs - free it. */
+ prs_mem_free(&buffer->prs);
+
+ return ret;
+ }
+}
+
+/*******************************************************************
+ Read/write an RPC_BUFFER* struct.(allocate memory if unmarshalling)
+********************************************************************/
+
+BOOL prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **buffer)
+{
+ uint32 data_p;
+
+ /* caputure the pointer value to stream */
+
+ data_p = (uint32) *buffer;
+
+ if ( !prs_uint32("ptr", ps, depth, &data_p ))
+ return False;
+
+ /* we're done if there is no data */
+
+ if ( !data_p )
+ return True;
+
+ if ( UNMARSHALLING(ps) ) {
+ if ( !(*buffer = PRS_ALLOC_MEM(ps, RPC_BUFFER, 1)) )
+ return False;
+ }
+
+ return prs_rpcbuffer( desc, ps, depth, *buffer);
+}
+
+/****************************************************************************
+ Allocate more memory for a RPC_BUFFER.
+****************************************************************************/
+
+BOOL rpcbuf_alloc_size(RPC_BUFFER *buffer, uint32 buffer_size)
+{
+ prs_struct *ps;
+ uint32 extra_space;
+ uint32 old_offset;
+
+ /* if we don't need anything. don't do anything */
+
+ if ( buffer_size == 0x0 )
+ return True;
+
+ ps= &buffer->prs;
+
+ /* damn, I'm doing the reverse operation of prs_grow() :) */
+ if (buffer_size < prs_data_size(ps))
+ extra_space=0;
+ else
+ extra_space = buffer_size - prs_data_size(ps);
+
+ /*
+ * save the offset and move to the end of the buffer
+ * prs_grow() checks the extra_space against the offset
+ */
+ old_offset=prs_offset(ps);
+ prs_set_offset(ps, prs_data_size(ps));
+
+ if (!prs_grow(ps, extra_space))
+ return False;
+
+ prs_set_offset(ps, old_offset);
+
+ buffer->string_at_end=prs_data_size(ps);
+
+ return True;
+}
+
+/*******************************************************************
+ move a BUFFER from the query to the reply.
+ As the data pointers in RPC_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 rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest)
+{
+ SMB_ASSERT( src != NULL );
+
+ prs_switch_type(&src->prs, MARSHALL);
+ if(!prs_set_offset(&src->prs, 0))
+ return;
+ prs_force_dynamic(&src->prs);
+ prs_mem_clear(&src->prs);
+ *dest=src;
+}
+
+/*******************************************************************
+ Get the size of a BUFFER struct.
+********************************************************************/
+
+uint32 rpcbuf_get_size(RPC_BUFFER *buffer)
+{
+ return (buffer->size);
+}
+
+
+/*******************************************************************
+ * write a UNICODE string and its relative pointer.
+ * used by all the RPC structs passing a buffer
+ *
+ * As I'm a nice guy, I'm forcing myself to explain this code.
+ * MS did a good job in the overall spoolss code except in some
+ * functions where they are passing the API buffer directly in the
+ * RPC request/reply. That's to maintain compatiility at the API level.
+ * They could have done it the good way the first time.
+ *
+ * So what happen is: the strings are written at the buffer's end,
+ * in the reverse order of the original structure. Some pointers to
+ * the strings are also in the buffer. Those are relative to the
+ * buffer's start.
+ *
+ * If you don't understand or want to change that function,
+ * first get in touch with me: jfm@samba.org
+ *
+ ********************************************************************/
+
+BOOL smb_io_relstr(const char *desc, RPC_BUFFER *buffer, int depth, UNISTR *string)
+{
+ prs_struct *ps=&buffer->prs;
+
+ if (MARSHALLING(ps)) {
+ uint32 struct_offset = prs_offset(ps);
+ uint32 relative_offset;
+
+ buffer->string_at_end -= (size_of_relative_string(string) - 4);
+ if(!prs_set_offset(ps, buffer->string_at_end))
+ return False;
+#if 0 /* JERRY */
+ /*
+ * Win2k does not align strings in a buffer
+ * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry
+ */
+ if (!prs_align(ps))
+ return False;
+#endif
+ buffer->string_at_end = prs_offset(ps);
+
+ /* write the string */
+ if (!smb_io_unistr(desc, string, ps, depth))
+ return False;
+
+ if(!prs_set_offset(ps, struct_offset))
+ return False;
+
+ relative_offset=buffer->string_at_end - buffer->struct_start;
+ /* write its offset */
+ if (!prs_uint32("offset", ps, depth, &relative_offset))
+ return False;
+ }
+ else {
+ uint32 old_offset;
+
+ /* read the offset */
+ if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
+ return False;
+
+ if (buffer->string_at_end == 0)
+ return True;
+
+ old_offset = prs_offset(ps);
+ if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
+ return False;
+
+ /* read the string */
+ if (!smb_io_unistr(desc, string, ps, depth))
+ return False;
+
+ if(!prs_set_offset(ps, old_offset))
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+ * write a array of UNICODE strings and its relative pointer.
+ * used by 2 RPC structs
+ ********************************************************************/
+
+BOOL smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string)
+{
+ UNISTR chaine;
+
+ prs_struct *ps=&buffer->prs;
+
+ if (MARSHALLING(ps)) {
+ uint32 struct_offset = prs_offset(ps);
+ uint32 relative_offset;
+ uint16 *p;
+ uint16 *q;
+ uint16 zero=0;
+ p=*string;
+ q=*string;
+
+ /* first write the last 0 */
+ buffer->string_at_end -= 2;
+ if(!prs_set_offset(ps, buffer->string_at_end))
+ return False;
+
+ if(!prs_uint16("leading zero", ps, depth, &zero))
+ return False;
+
+ while (p && (*p!=0)) {
+ while (*q!=0)
+ q++;
+
+ /* Yes this should be malloc not talloc. Don't change. */
+
+ chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16));
+ if (chaine.buffer == NULL)
+ return False;
+
+ memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
+
+ buffer->string_at_end -= (q-p+1)*sizeof(uint16);
+
+ if(!prs_set_offset(ps, buffer->string_at_end)) {
+ SAFE_FREE(chaine.buffer);
+ return False;
+ }
+
+ /* write the string */
+ if (!smb_io_unistr(desc, &chaine, ps, depth)) {
+ SAFE_FREE(chaine.buffer);
+ return False;
+ }
+ q++;
+ p=q;
+
+ SAFE_FREE(chaine.buffer);
+ }
+
+ if(!prs_set_offset(ps, struct_offset))
+ return False;
+
+ relative_offset=buffer->string_at_end - buffer->struct_start;
+ /* write its offset */
+ if (!prs_uint32("offset", ps, depth, &relative_offset))
+ return False;
+
+ } else {
+
+ /* UNMARSHALLING */
+
+ uint32 old_offset;
+ uint16 *chaine2=NULL;
+ int l_chaine=0;
+ int l_chaine2=0;
+ size_t realloc_size = 0;
+
+ *string=NULL;
+
+ /* read the offset */
+ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
+ return False;
+
+ old_offset = prs_offset(ps);
+ if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
+ return False;
+
+ do {
+ if (!smb_io_unistr(desc, &chaine, ps, depth))
+ return False;
+
+ l_chaine=str_len_uni(&chaine);
+
+ /* we're going to add two more bytes here in case this
+ is the last string in the array and we need to add
+ an extra NULL for termination */
+ 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 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
+ SAFE_FREE(chaine2);
+ return False;
+ }
+ else chaine2 = tc2;
+ memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
+ l_chaine2+=l_chaine+1;
+ }
+
+ } while(l_chaine!=0);
+
+ /* the end should be bould NULL terminated so add
+ the second one here */
+ if (chaine2)
+ {
+ chaine2[l_chaine2] = '\0';
+ *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
+ SAFE_FREE(chaine2);
+ }
+
+ if(!prs_set_offset(ps, old_offset))
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+ Parse a DEVMODE structure and its relative pointer.
+********************************************************************/
+
+BOOL smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc)
+{
+ prs_struct *ps= &buffer->prs;
+
+ prs_debug(ps, depth, desc, "smb_io_relsecdesc");
+ depth++;
+
+ if (MARSHALLING(ps)) {
+ uint32 struct_offset = prs_offset(ps);
+ uint32 relative_offset;
+
+ if (! *secdesc) {
+ relative_offset = 0;
+ if (!prs_uint32("offset", ps, depth, &relative_offset))
+ return False;
+ return True;
+ }
+
+ if (*secdesc != NULL) {
+ buffer->string_at_end -= sec_desc_size(*secdesc);
+
+ if(!prs_set_offset(ps, buffer->string_at_end))
+ return False;
+ /* write the secdesc */
+ if (!sec_io_desc(desc, secdesc, ps, depth))
+ return False;
+
+ if(!prs_set_offset(ps, struct_offset))
+ return False;
+ }
+
+ relative_offset=buffer->string_at_end - buffer->struct_start;
+ /* write its offset */
+
+ if (!prs_uint32("offset", ps, depth, &relative_offset))
+ return False;
+ } else {
+ uint32 old_offset;
+
+ /* read the offset */
+ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
+ return False;
+
+ old_offset = prs_offset(ps);
+ if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
+ return False;
+
+ /* read the sd */
+ if (!sec_io_desc(desc, secdesc, ps, depth))
+ return False;
+
+ if(!prs_set_offset(ps, old_offset))
+ return False;
+ }
+ return True;
+}
+
+
+
+/*******************************************************************
+ * return the length of a UNICODE string in number of char, includes:
+ * - the leading zero
+ * - the relative pointer size
+ ********************************************************************/
+
+uint32 size_of_relative_string(UNISTR *string)
+{
+ uint32 size=0;
+
+ size=str_len_uni(string); /* the string length */
+ size=size+1; /* add the trailing zero */
+ size=size*2; /* convert in char */
+ size=size+4; /* add the size of the ptr */
+
+#if 0 /* JERRY */
+ /*
+ * Do not include alignment as Win2k does not align relative
+ * strings within a buffer --jerry
+ */
+ /* Ensure size is 4 byte multiple (prs_align is being called...). */
+ /* size += ((4 - (size & 3)) & 3); */
+#endif
+
+ return size;
+}
+
diff --git a/source/rpc_parse/parse_eventlog.c b/source/rpc_parse/parse_eventlog.c
new file mode 100644
index 00000000000..9bb0a131697
--- /dev/null
+++ b/source/rpc_parse/parse_eventlog.c
@@ -0,0 +1,457 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/*
+ * called from eventlog_q_open_eventlog (srv_eventlog.c)
+ */
+
+BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ /* Data format seems to be:
+ UNKNOWN structure
+ uint32 unknown
+ uint16 unknown
+ uint16 unknown
+ Eventlog name
+ uint16 eventlog name length
+ uint16 eventlog name size
+ Character Array
+ uint32 unknown
+ uint32 max count
+ uint32 offset
+ uint32 actual count
+ UNISTR2 log file name
+ Server Name
+ uint16 server name length
+ uint16 server name size
+ Character Array
+ UNISTR2 server name
+ */
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_open_eventlog");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ /* Munch unknown bits */
+
+ if(!prs_uint32("", ps, depth, &q_u->unknown1))
+ return False;
+ if(!prs_uint16("", ps, depth, &q_u->unknown2))
+ return False;
+ if(!prs_uint16("", ps, depth, &q_u->unknown3))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ /* Get name of log source */
+
+ if(!prs_uint16("sourcename_length", ps, depth, &q_u->sourcename_length))
+ return False;
+ if(!prs_uint16("sourcename_size", ps, depth, &q_u->sourcename_size))
+ return False;
+ if(!prs_uint32("sourcename_ptr", ps, depth, &q_u->sourcename_ptr))
+ return False;
+ if(!smb_io_unistr2("", &q_u->sourcename, q_u->sourcename_ptr, ps, depth))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ /* Get server name */
+
+ if(!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
+ return False;
+ if(!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_r_open_eventlog(const char *desc, EVENTLOG_R_OPEN_EVENTLOG *r_u,
+ prs_struct *ps, int depth)
+{
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_open_eventlog");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth)))
+ return False;
+
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_q_get_num_records(const char *desc, EVENTLOG_Q_GET_NUM_RECORDS *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_get_num_records");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_r_get_num_records(const char *desc, EVENTLOG_R_GET_NUM_RECORDS *r_u,
+ prs_struct *ps, int depth)
+{
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_get_num_records");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(prs_uint32("num records", ps, depth, &(r_u->num_records))))
+ return False;
+
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_q_get_oldest_entry(const char *desc, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_get_oldest_entry");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_r_get_oldest_entry(const char *desc, EVENTLOG_R_GET_OLDEST_ENTRY *r_u,
+ prs_struct *ps, int depth)
+{
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_get_oldest_entry");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(prs_uint32("oldest entry", ps, depth, &(r_u->oldest_entry))))
+ return False;
+
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_q_close_eventlog(const char *desc, EVENTLOG_Q_CLOSE_EVENTLOG *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_close_eventlog");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_r_close_eventlog(const char *desc, EVENTLOG_R_CLOSE_EVENTLOG *r_u,
+ prs_struct *ps, int depth)
+{
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_close_eventlog");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(r_u->handle), ps, depth)))
+ return False;
+
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
+
+BOOL eventlog_io_q_read_eventlog(const char *desc, EVENTLOG_Q_READ_EVENTLOG *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_read_eventlog");
+ depth++;
+
+ if(!(prs_align(ps)))
+ return False;
+
+ if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+ return False;
+
+ if(!(prs_uint32("read flags", ps, depth, &(q_u->flags))))
+ return False;
+
+ if(!(prs_uint32("read offset", ps, depth, &(q_u->offset))))
+ return False;
+
+ if(!(prs_uint32("read buf size", ps, depth, &(q_u->max_read_size))))
+ return False;
+
+ return True;
+}
+/* Structure of response seems to be:
+ DWORD num_bytes_in_resp -- MUST be the same as q_u->max_read_size
+ for i=0..n
+ EVENTLOGRECORD record
+ DWORD sent_size -- sum of EVENTLOGRECORD lengths if records returned, 0 otherwise
+ DWORD real_size -- 0 if records returned, otherwise length of next record to be returned
+ WERROR status */
+BOOL eventlog_io_r_read_eventlog(const char *desc,
+ EVENTLOG_Q_READ_EVENTLOG *q_u,
+ EVENTLOG_R_READ_EVENTLOG *r_u,
+ prs_struct *ps,
+ int depth)
+{
+ Eventlog_entry *entry;
+ uint32 record_written = 0;
+ uint32 record_total = 0;
+
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_read_eventlog");
+ depth++;
+
+ /* First, see if we've read more logs than we can output */
+
+ if(r_u->num_bytes_in_resp > q_u->max_read_size) {
+ entry = r_u->entry;
+
+ /* remove the size of the last entry from the list */
+
+ while(entry->next != NULL)
+ entry = entry->next;
+
+ r_u->num_bytes_in_resp -= entry->record.length;
+
+ /* do not output the last log entry */
+
+ r_u->num_records--;
+ }
+
+ entry = r_u->entry;
+ record_total = r_u->num_records;
+
+ if(r_u->num_bytes_in_resp != 0)
+ r_u->sent_size = r_u->num_bytes_in_resp;
+ else
+ r_u->real_size = entry->record.length;
+
+ if(!(prs_align(ps)))
+ return False;
+ if(!(prs_uint32("bytes in resp", ps, depth, &(q_u->max_read_size))))
+ return False;
+
+ while(entry != NULL && record_written < record_total)
+ {
+ DEBUG(10, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total));
+
+ /* Encode the actual eventlog record record */
+
+ if(!(prs_uint32("length", ps, depth, &(entry->record.length))))
+ return False;
+ if(!(prs_uint32("reserved", ps, depth, &(entry->record.reserved1))))
+ return False;
+ if(!(prs_uint32("record number", ps, depth, &(entry->record.record_number))))
+ return False;
+ if(!(prs_uint32("time generated", ps, depth, &(entry->record.time_generated))))
+ return False;
+ if(!(prs_uint32("time written", ps, depth, &(entry->record.time_written))))
+ return False;
+ if(!(prs_uint32("event id", ps, depth, &(entry->record.event_id))))
+ return False;
+ if(!(prs_uint16("event type", ps, depth, &(entry->record.event_type))))
+ return False;
+ if(!(prs_uint16("num strings", ps, depth, &(entry->record.num_strings))))
+ return False;
+ if(!(prs_uint16("event category", ps, depth, &(entry->record.event_category))))
+ return False;
+ if(!(prs_uint16("reserved2", ps, depth, &(entry->record.reserved2))))
+ return False;
+ if(!(prs_uint32("closing record", ps, depth, &(entry->record.closing_record_number))))
+ return False;
+ if(!(prs_uint32("string offset", ps, depth, &(entry->record.string_offset))))
+ return False;
+ if(!(prs_uint32("user sid length", ps, depth, &(entry->record.user_sid_length))))
+ return False;
+ if(!(prs_uint32("user sid offset", ps, depth, &(entry->record.user_sid_offset))))
+ return False;
+ if(!(prs_uint32("data length", ps, depth, &(entry->record.data_length))))
+ return False;
+ if(!(prs_uint32("data offset", ps, depth, &(entry->record.data_offset))))
+ return False;
+ if(!(prs_align(ps)))
+ return False;
+
+ /* Now encoding data */
+
+ if(!(prs_uint8s(False, "buffer", ps, depth, entry->data,
+ entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length))))
+ {
+ return False;
+ }
+
+ if(!(prs_align(ps)))
+ return False;
+ if(!(prs_uint32("length 2", ps, depth, &(entry->record.length))))
+ return False;
+
+ entry = entry->next;
+ record_written++;
+
+ } /* end of encoding EVENTLOGRECORD */
+
+ /* Now pad with whitespace until the end of the response buffer */
+
+ r_u->end_of_entries_padding = (uint8 *)calloc(q_u->max_read_size - r_u->num_bytes_in_resp, sizeof(uint8));
+
+ if(!(prs_uint8s(False, "end of entries padding", ps,
+ depth, r_u->end_of_entries_padding,
+ (q_u->max_read_size - r_u->num_bytes_in_resp))))
+ {
+ return False;
+ }
+
+ free(r_u->end_of_entries_padding);
+
+ /* We had better be DWORD aligned here */
+
+ if(!(prs_uint32("sent size", ps, depth, &(r_u->sent_size))))
+ return False;
+ if(!(prs_uint32("real size", ps, depth, &(r_u->real_size))))
+ return False;
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
+
+/* The windows client seems to be doing something funny with the file name
+ A call like
+ ClearEventLog(handle, "backup_file")
+ on the client side will result in the backup file name looking like this on the
+ server side:
+ \??\${CWD of client}\backup_file
+ If an absolute path gets specified, such as
+ ClearEventLog(handle, "C:\\temp\\backup_file")
+ then it is still mangled by the client into this:
+ \??\C:\temp\backup_file
+ when it is on the wire.
+ I'm not sure where the \?? is coming from, or why the ${CWD} of the client process
+ would be added in given that the backup file gets written on the server side. */
+
+BOOL eventlog_io_q_clear_eventlog(const char *desc, EVENTLOG_Q_CLEAR_EVENTLOG *q_u,
+ prs_struct *ps, int depth)
+{
+ if(q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_q_clear_eventlog");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!(smb_io_pol_hnd("log handle", &(q_u->handle), ps, depth)))
+ return False;
+ if(!prs_align(ps))
+ return False;
+ if(!(prs_uint32("unknown1", ps, depth, &q_u->unknown1)))
+ return False;
+ if(!(prs_uint16("backup_file_length", ps, depth, &q_u->backup_file_length)))
+ return False;
+ if(!(prs_uint16("backup_file_size", ps, depth, &q_u->backup_file_size)))
+ return False;
+ if(!prs_uint32("backup_file_ptr", ps, depth, &q_u->backup_file_ptr))
+ return False;
+ if(!smb_io_unistr2("backup file", &q_u->backup_file, q_u->backup_file_ptr, ps, depth))
+ return False;
+
+ return True;
+
+}
+
+BOOL eventlog_io_r_clear_eventlog(const char *desc, EVENTLOG_R_CLEAR_EVENTLOG *r_u,
+ prs_struct *ps, int depth)
+{
+ if(r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "eventlog_io_r_clear_eventlog");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ if(!(prs_werror("status code", ps, depth, &(r_u->status))))
+ return False;
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index bbff258722a..ab3d3fcfe81 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -6,6 +6,7 @@
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Andrew Bartlett 2002,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002.
+ * Copyright (C) Gerald )Jerry) Carter 2005
*
* 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
@@ -516,100 +517,99 @@ void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 en
DEBUG(5, ("init_r_enum_trust_dom\n"));
- r_e->enum_context = enum_context;
- r_e->num_domains = num_domains;
- r_e->ptr_enum_domains = 0;
- r_e->num_domains2 = num_domains;
-
- if (num_domains != 0) {
+ r_e->enum_context = enum_context;
+ r_e->count = num_domains;
+
+ if ( num_domains != 0 ) {
- /*
- * allocating empty arrays of unicode headers, strings
- * and sids of enumerated trusted domains
- */
- if (!(r_e->hdr_domain_name = TALLOC_ARRAY(ctx,UNIHDR2,num_domains))) {
- r_e->status = NT_STATUS_NO_MEMORY;
- return;
- }
+ /* allocate container memory */
- if (!(r_e->uni_domain_name = TALLOC_ARRAY(ctx,UNISTR2,num_domains))) {
- r_e->status = NT_STATUS_NO_MEMORY;
- return;
- }
-
- if (!(r_e->domain_sid = TALLOC_ARRAY(ctx,DOM_SID2,num_domains))) {
+ r_e->domlist = TALLOC_P( ctx, DOMAIN_LIST );
+ r_e->domlist->domains = TALLOC_ARRAY( ctx, DOMAIN_INFO, r_e->count );
+
+ if ( !r_e->domlist || !r_e->domlist->domains ) {
r_e->status = NT_STATUS_NO_MEMORY;
return;
}
+
+ r_e->domlist->count = r_e->count;
+
+ /* initialize the list of domains and their sid */
+
+ for (i = 0; i < num_domains; i++) {
+ if ( !(r_e->domlist->domains[i].sid = TALLOC_P(ctx, DOM_SID2)) ) {
+ r_e->status = NT_STATUS_NO_MEMORY;
+ return;
+ }
- for (i = 0; i < num_domains; i++) {
-
- /* don't know what actually is this for */
- r_e->ptr_enum_domains = 1;
-
- init_dom_sid2(&r_e->domain_sid[i], &(td[i])->sid);
-
- init_unistr2_w(ctx, &r_e->uni_domain_name[i], (td[i])->name);
- init_uni_hdr2(&r_e->hdr_domain_name[i], &r_e->uni_domain_name[i]);
-
- };
+ init_dom_sid2(r_e->domlist->domains[i].sid, &(td[i])->sid);
+ init_unistr4_w(ctx, &r_e->domlist->domains[i].name, (td[i])->name);
+ }
}
}
/*******************************************************************
- Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
********************************************************************/
-BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
- prs_struct *ps, int depth)
+BOOL lsa_io_domain_list( const char *desc, prs_struct *ps, int depth, DOMAIN_LIST *domlist )
{
- prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
+ int i;
+
+ prs_debug(ps, depth, desc, "lsa_io_domain_list");
depth++;
- if(!prs_uint32("enum_context ", ps, depth, &r_e->enum_context))
- return False;
- if(!prs_uint32("num_domains ", ps, depth, &r_e->num_domains))
- return False;
- if(!prs_uint32("ptr_enum_domains", ps, depth, &r_e->ptr_enum_domains))
+ if(!prs_uint32("count", ps, depth, &domlist->count))
return False;
- if (r_e->ptr_enum_domains) {
- int i, num_domains;
+ if ( domlist->count == 0 )
+ return True;
+
+ if ( UNMARSHALLING(ps) ) {
+ if ( !(domlist->domains = PRS_ALLOC_MEM( ps, DOMAIN_INFO, domlist->count )) )
+ return False;
+ }
+
+ /* headers */
+
+ for ( i=0; i<domlist->count; i++ ) {
+ if ( !prs_unistr4_hdr("name_header", ps, depth, &domlist->domains[i].name) )
+ return False;
+ if ( !smb_io_dom_sid2_p("sid_header", ps, depth, &domlist->domains[i].sid) )
+ return False;
+ }
- if(!prs_uint32("num_domains2", ps, depth, &r_e->num_domains2))
+ /* data */
+
+ for ( i=0; i<domlist->count; i++ ) {
+ if ( !prs_unistr4_str("name", ps, depth, &domlist->domains[i].name) )
return False;
+ if( !smb_io_dom_sid2("sid", domlist->domains[i].sid, ps, depth) )
+ return False;
+ }
+
+ return True;
+}
- num_domains = r_e->num_domains2;
+/*******************************************************************
+ Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
- if (UNMARSHALLING(ps)) {
- if (!(r_e->hdr_domain_name = PRS_ALLOC_MEM(ps,UNIHDR2,num_domains)))
- return False;
+BOOL lsa_io_r_enum_trust_dom(const char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
+ prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
+ depth++;
- if (!(r_e->uni_domain_name = PRS_ALLOC_MEM(ps,UNISTR2,num_domains)))
- return False;
+ if(!prs_uint32("enum_context", ps, depth, &r_e->enum_context))
+ return False;
- if (!(r_e->domain_sid = PRS_ALLOC_MEM(ps,DOM_SID2,num_domains)))
- return False;
- }
+ if(!prs_uint32("count", ps, depth, &r_e->count))
+ return False;
- for (i = 0; i < num_domains; i++) {
- if(!smb_io_unihdr2 ("", &r_e->hdr_domain_name[i], ps,
- depth))
- return False;
- }
+ if ( !prs_pointer("trusted_domains", ps, depth, (void**)&r_e->domlist, sizeof(DOMAIN_LIST), (PRS_POINTER_CAST)lsa_io_domain_list))
+ return False;
- for (i = 0; i < num_domains; i++) {
- if(!smb_io_unistr2 ("", &r_e->uni_domain_name[i],
- r_e->hdr_domain_name[i].buffer,
- ps, depth))
- return False;
- if(!smb_io_dom_sid2("", &r_e->domain_sid[i], ps,
- depth))
- return False;
- }
- }
-
if(!prs_ntstatus("status", ps, depth, &r_e->status))
return False;
@@ -906,7 +906,7 @@ void init_q_lookup_sids(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_SIDS *q_l,
memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
init_lsa_sid_enum(mem_ctx, &q_l->sids, num_sids, sids);
- q_l->level.value = level;
+ q_l->level = level;
}
/*******************************************************************
@@ -928,7 +928,10 @@ BOOL lsa_io_q_lookup_sids(const char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *
return False;
if(!lsa_io_trans_names("names ", &q_s->names, ps, depth)) /* translated names */
return False;
- if(!smb_io_lookup_level("switch ", &q_s->level, ps, depth)) /* lookup level */
+
+ if(!prs_uint16("level", ps, depth, &q_s->level)) /* lookup level */
+ return False;
+ if(!prs_align(ps))
return False;
if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count))
@@ -2319,7 +2322,9 @@ NTSTATUS init_r_enum_acct_rights( LSA_R_ENUM_ACCT_RIGHTS *r_u, PRIVILEGE_SET *pr
}
if ( num_priv ) {
- if ( !init_unistr2_array( &r_u->rights, num_priv, privname_array ) )
+ r_u->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+
+ if ( !init_unistr4_array( r_u->rights, num_priv, privname_array ) )
return NT_STATUS_NO_MEMORY;
r_u->count = num_priv;
@@ -2361,7 +2366,7 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr
if(!prs_uint32("count ", ps, depth, &r_c->count))
return False;
- if(!smb_io_unistr2_array("rights", &r_c->rights, ps, depth))
+ if ( !prs_pointer("rights", ps, depth, (void**)&r_c->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
return False;
if(!prs_align(ps))
@@ -2377,17 +2382,17 @@ BOOL lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *r_c, pr
/*******************************************************************
Inits an LSA_Q_ADD_ACCT_RIGHTS structure.
********************************************************************/
-void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q,
- POLICY_HND *hnd,
- DOM_SID *sid,
- uint32 count,
- const char **rights)
+void init_q_add_acct_rights( LSA_Q_ADD_ACCT_RIGHTS *q_q, POLICY_HND *hnd,
+ DOM_SID *sid, uint32 count, const char **rights )
{
DEBUG(5, ("init_q_add_acct_rights\n"));
q_q->pol = *hnd;
init_dom_sid2(&q_q->sid, sid);
- init_unistr2_array(&q_q->rights, count, rights);
+
+ q_q->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+ init_unistr4_array( q_q->rights, count, rights );
+
q_q->count = count;
}
@@ -2409,7 +2414,7 @@ BOOL lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *q_q, prs_
if(!prs_uint32("count", ps, depth, &q_q->count))
return False;
- if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
+ if ( !prs_pointer("rights", ps, depth, (void**)&q_q->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
return False;
return True;
@@ -2443,10 +2448,14 @@ void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q,
DEBUG(5, ("init_q_remove_acct_rights\n"));
q_q->pol = *hnd;
+
init_dom_sid2(&q_q->sid, sid);
+
q_q->removeall = removeall;
- init_unistr2_array(&q_q->rights, count, rights);
q_q->count = count;
+
+ q_q->rights = TALLOC_P( get_talloc_ctx(), UNISTR4_ARRAY );
+ init_unistr4_array( q_q->rights, count, rights );
}
@@ -2470,7 +2479,7 @@ BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q
if(!prs_uint32("count", ps, depth, &q_q->count))
return False;
- if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
+ if ( !prs_pointer("rights", ps, depth, (void**)&q_q->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
return False;
return True;
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index bca40a64c82..faa00d18624 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -4,6 +4,7 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Gerald (Jerry) Carter 2005
*
* 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
@@ -132,28 +133,6 @@ BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
}
/*******************************************************************
- Reads or writes a LOOKUP_LEVEL structure.
-********************************************************************/
-
-BOOL smb_io_lookup_level(const char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
-{
- if (level == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_lookup_level");
- depth++;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint16("value", ps, depth, &level->value))
- return False;
- if(!prs_align(ps))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Gets an enumeration handle from an ENUM_HND structure.
********************************************************************/
@@ -302,6 +281,33 @@ void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
Reads or writes a DOM_SID2 structure.
********************************************************************/
+BOOL smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2)
+{
+ uint32 data_p;
+
+ /* caputure the pointer value to stream */
+
+ data_p = (uint32) *sid2;
+
+ if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
+ return False;
+
+ /* we're done if there is no data */
+
+ if ( !data_p )
+ return True;
+
+ if (UNMARSHALLING(ps)) {
+ if ( !(*sid2 = PRS_ALLOC_MEM(ps, DOM_SID2, 1)) )
+ return False;
+ }
+
+ return True;
+}
+/*******************************************************************
+ Reads or writes a DOM_SID2 structure.
+********************************************************************/
+
BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
{
if (sid == NULL)
@@ -507,39 +513,6 @@ BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
-creates a UNIHDR2 structure.
-********************************************************************/
-
-void init_uni_hdr2(UNIHDR2 *hdr, UNISTR2 *str2)
-{
- init_uni_hdr(&hdr->unihdr, str2);
- hdr->buffer = (str2->uni_str_len > 0) ? 1 : 0;
-}
-
-/*******************************************************************
- Reads or writes a UNIHDR2 structure.
-********************************************************************/
-
-BOOL smb_io_unihdr2(const char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
-{
- if (hdr2 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_unihdr2");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
- return False;
- if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Inits a UNISTR structure.
********************************************************************/
@@ -581,105 +554,69 @@ BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
}
/*******************************************************************
- Allocate the BUFFER3 memory.
+ Allocate the RPC_DATA_BLOB memory.
********************************************************************/
-static size_t create_buffer3(BUFFER3 *str, size_t len)
+static size_t create_rpc_blob(RPC_DATA_BLOB *str, size_t len)
{
str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
if (str->buffer == NULL)
- smb_panic("create_buffer3: talloc fail\n");
+ smb_panic("create_rpc_blob: talloc fail\n");
return len;
}
/*******************************************************************
- Inits a BUFFER3 structure from a uint32
+ Inits a RPC_DATA_BLOB structure from a uint32
********************************************************************/
-void init_buffer3_uint32(BUFFER3 *str, uint32 val)
+void init_rpc_blob_uint32(RPC_DATA_BLOB *str, uint32 val)
{
ZERO_STRUCTP(str);
/* set up string lengths. */
- str->buf_max_len = str->buf_len = create_buffer3(str, sizeof(uint32));
+ str->buf_len = create_rpc_blob(str, sizeof(uint32));
SIVAL(str->buffer, 0, val);
}
/*******************************************************************
- Inits a BUFFER3 structure.
+ Inits a RPC_DATA_BLOB structure.
********************************************************************/
-void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
+void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len)
{
ZERO_STRUCTP(str);
/* set up string lengths. */
- str->buf_max_len = str->buf_len = create_buffer3(str, len*2);
- rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
+ str->buf_len = create_rpc_blob(str, len*2);
+ rpcstr_push(str->buffer, buf, str->buf_len, STR_TERMINATE);
}
/*******************************************************************
- Inits a BUFFER3 structure from a hex string.
+ Inits a RPC_DATA_BLOB structure from a hex string.
********************************************************************/
-void init_buffer3_hex(BUFFER3 *str, const char *buf)
+void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf)
{
ZERO_STRUCTP(str);
- str->buf_max_len = str->buf_len = create_buffer3(str, strlen(buf));
- str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
+ str->buf_len = create_rpc_blob(str, strlen(buf));
+ str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
}
/*******************************************************************
- Inits a BUFFER3 structure.
+ Inits a RPC_DATA_BLOB structure.
********************************************************************/
-void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, size_t len)
+void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len)
{
ZERO_STRUCTP(str);
/* max buffer size (allocated size) */
if (buf != NULL) {
- len = create_buffer3(str, len);
+ len = create_rpc_blob(str, len);
memcpy(str->buffer, buf, len);
}
- str->buf_max_len = len;
- str->buf_len = buf != NULL ? len : 0;
-}
-
-/*******************************************************************
- Reads or writes a BUFFER3 structure.
- the uni_max_len member tells you how large the buffer is.
- the uni_str_len member tells you how much of the buffer is really used.
-********************************************************************/
-
-BOOL smb_io_buffer3(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
-{
- if (buf3 == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_buffer3");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
- return False;
-
- if (UNMARSHALLING(ps)) {
- buf3->buffer = PRS_ALLOC_MEM(ps, unsigned char, buf3->buf_max_len);
- if (buf3->buffer == NULL)
- return False;
- }
-
- if(!prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len))
- return False;
-
- if(!prs_uint32("buf_len ", ps, depth, &buf3->buf_len))
- return False;
-
- return True;
+ str->buf_len = len;
}
/*******************************************************************
@@ -707,10 +644,10 @@ BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
}
/*******************************************************************
- Inits a BUFFER2 structure.
+ Inits a REGVAL_BUFFER structure.
********************************************************************/
-void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
+void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len)
{
ZERO_STRUCTP(str);
@@ -723,50 +660,39 @@ void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
SMB_ASSERT(str->buf_max_len >= str->buf_len);
str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->buf_max_len);
if (str->buffer == NULL)
- smb_panic("init_buffer2: talloc fail\n");
+ smb_panic("init_regval_buffer: talloc fail\n");
memcpy(str->buffer, buf, str->buf_len);
}
}
/*******************************************************************
- Reads or writes a BUFFER2 structure.
+ Reads or writes a REGVAL_BUFFER structure.
the uni_max_len member tells you how large the buffer is.
the uni_str_len member tells you how much of the buffer is really used.
********************************************************************/
-BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2)
{
- if (buf2 == NULL)
- return False;
- if (buffer) {
-
- prs_debug(ps, depth, desc, "smb_io_buffer2");
- depth++;
+ prs_debug(ps, depth, desc, "smb_io_regval_buffer");
+ depth++;
- if(!prs_align(ps))
- return False;
+ if(!prs_align(ps))
+ return False;
- if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
- return False;
- if(!prs_uint32("offset ", ps, depth, &buf2->offset))
- return False;
- if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
- return False;
-
- /* buffer advanced by indicated length of string
- NOT by searching for null-termination */
-
- if(!prs_buffer2(True, "buffer ", ps, depth, buf2))
- return False;
+ if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
+ return False;
+ if(!prs_uint32("offset ", ps, depth, &buf2->offset))
+ return False;
+ if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
+ return False;
- } else {
+ /* buffer advanced by indicated length of string
+ NOT by searching for null-termination */
- prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
- depth++;
- memset((char *)buf2, '\0', sizeof(*buf2));
+ if(!prs_regval_buffer(True, "buffer ", ps, depth, buf2))
+ return False;
- }
return True;
}
@@ -933,6 +859,28 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
str->uni_max_len++;
}
+/*******************************************************************
+ Inits a UNISTR4 structure.
+********************************************************************/
+
+void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
+{
+ uni4->string = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+ init_unistr2( uni4->string, buf, flags );
+
+ uni4->length = 2 * (uni4->string->uni_str_len);
+ uni4->size = 2 * (uni4->string->uni_max_len);
+}
+
+void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
+{
+ uni4->string = TALLOC_P( ctx, UNISTR2 );
+ init_unistr2_w( ctx, uni4->string, buf );
+
+ uni4->length = 2 * (uni4->string->uni_str_len);
+ uni4->size = 2 * (uni4->string->uni_max_len);
+}
+
/**
* Inits a UNISTR2 structure.
* @param ctx talloc context to allocate string on
@@ -1034,6 +982,57 @@ void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob)
}
/*******************************************************************
+ UNISTR2* are a little different in that the pointer and the UNISTR2
+ are not necessarily read/written back to back. So we break it up
+ into 2 separate functions.
+ See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
+********************************************************************/
+
+BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
+{
+ uint32 data_p;
+
+ /* caputure the pointer value to stream */
+
+ data_p = (uint32) *uni2;
+
+ if ( !prs_uint32("ptr", ps, depth, &data_p ))
+ return False;
+
+ /* we're done if there is no data */
+
+ if ( !data_p )
+ return True;
+
+ if (UNMARSHALLING(ps)) {
+ if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ now read/write the actual UNISTR2. Memory for the UNISTR2 (but
+ not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
+********************************************************************/
+
+BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
+{
+ /* just return true if there is no pointer to deal with.
+ the memory must have been previously allocated on unmarshalling
+ by prs_unistr2_p() */
+
+ if ( !uni2 )
+ return True;
+
+ /* just pass off to smb_io_unstr2() passing the uni2 address as
+ the pointer (like you would expect) */
+
+ return smb_io_unistr2( desc, uni2, (uint32)uni2, ps, depth );
+}
+
+/*******************************************************************
Reads or writes a UNISTR2 structure.
XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
the uni_str_len member tells you how long the string is;
@@ -1076,32 +1075,114 @@ BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *
return True;
}
+/*******************************************************************
+ now read/write UNISTR4
+********************************************************************/
+
+BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+ if ( !prs_uint16("length", ps, depth, &uni4->length ))
+ return False;
+ if ( !prs_uint16("size", ps, depth, &uni4->size ))
+ return False;
+
+ if ( !prs_pointer( desc, ps, depth, (void**)&uni4->string, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ now read/write UNISTR4 header
+********************************************************************/
+
+BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+ prs_debug(ps, depth, desc, "prs_unistr4_hdr");
+ depth++;
+
+ if ( !prs_uint16("length", ps, depth, &uni4->length) )
+ return False;
+ if ( !prs_uint16("size", ps, depth, &uni4->size) )
+ return False;
+ if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ now read/write UNISTR4 string
+********************************************************************/
+
+BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
+{
+ prs_debug(ps, depth, desc, "prs_unistr4_str");
+ depth++;
+
+ if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes a UNISTR2_ARRAY structure.
+********************************************************************/
-/*
+BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
+{
+ unsigned int i;
+
+ prs_debug(ps, depth, desc, "prs_unistr4_array");
+ depth++;
+
+ if(!prs_uint32("count", ps, depth, &array->count))
+ return False;
+
+ if ( array->count == 0 )
+ return True;
+
+ if (UNMARSHALLING(ps)) {
+ if ( !(array->strings = TALLOC_ZERO_ARRAY( get_talloc_ctx(), UNISTR4, array->count)) )
+ return False;
+ }
+
+ /* write the headers and then the actual string buffer */
+
+ for ( i=0; i<array->count; i++ ) {
+ if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
+ return False;
+ }
+
+ for (i=0;i<array->count;i++) {
+ if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) )
+ return False;
+ }
+
+ return True;
+}
+
+/********************************************************************
initialise a UNISTR_ARRAY from a char**
-*/
-BOOL init_unistr2_array(UNISTR2_ARRAY *array,
- uint32 count, const char **strings)
+********************************************************************/
+
+BOOL init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
{
unsigned int i;
array->count = count;
- array->ref_id = count?1:0;
- if (array->count == 0) {
+
+ if ( array->count == 0 )
return True;
- }
- array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR2_ARRAY_EL, count );
- if (!array->strings) {
+ /* allocate memory for the array of UNISTR4 objects */
+
+ if ( !(array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR4, count )) )
return False;
- }
- for (i=0;i<count;i++) {
- init_unistr2(&array->strings[i].string, strings[i], UNI_FLAGS_NONE);
- array->strings[i].size = array->strings[i].string.uni_max_len*2;
- array->strings[i].length = array->strings[i].size;
- array->strings[i].ref_id = 1;
- }
+ for ( i=0; i<count; i++ )
+ init_unistr4( &array->strings[i], strings[i], STR_TERMINATE );
return True;
}
@@ -1154,55 +1235,6 @@ BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockou
}
/*******************************************************************
- Reads or writes a UNISTR2_ARRAY structure.
-********************************************************************/
-BOOL smb_io_unistr2_array(const char *desc, UNISTR2_ARRAY *array, prs_struct *ps, int depth)
-{
- unsigned int i;
-
- prs_debug(ps, depth, desc, "smb_io_unistr2_array");
- depth++;
-
- if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
- return False;
-
- if (! array->ref_id) {
- return True;
- }
-
- if(!prs_uint32("count", ps, depth, &array->count))
- return False;
-
- if (array->count == 0) {
- return True;
- }
-
- if (UNMARSHALLING(ps)) {
- array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR2_ARRAY_EL, array->count );
- }
- if (! array->strings) {
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if(!prs_uint16("length", ps, depth, &array->strings[i].length))
- return False;
- if(!prs_uint16("size", ps, depth, &array->strings[i].size))
- return False;
- if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
- return False;
- }
-
- for (i=0;i<array->count;i++) {
- if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth))
- return False;
- }
-
- return True;
-}
-
-
-/*******************************************************************
Inits a DOM_RID2 structure.
********************************************************************/
@@ -1748,23 +1780,30 @@ BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
-reads or writes a BUFFER4 structure.
+reads or writes a RPC_DATA_BLOB structure.
********************************************************************/
-BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_rpc_blob(const char *desc, RPC_DATA_BLOB *blob, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "smb_io_buffer4");
+ prs_debug(ps, depth, desc, "smb_io_rpc_blob");
depth++;
prs_align(ps);
- prs_uint32("buf_len", ps, depth, &buf4->buf_len);
+ if ( !prs_uint32("buf_len", ps, depth, &blob->buf_len) )
+ return False;
+
+ if ( blob->buf_len == 0 )
+ return True;
+
if (UNMARSHALLING(ps)) {
- buf4->buffer = PRS_ALLOC_MEM(ps, uint8, buf4->buf_len);
- if (!buf4->buffer) {
+ blob->buffer = PRS_ALLOC_MEM(ps, uint8, blob->buf_len);
+ if (!blob->buffer) {
return False;
}
}
- prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
+
+ if ( !prs_uint8s(True, "buffer", ps, depth, blob->buffer, blob->buf_len) )
+ return False;
return True;
}
@@ -1797,3 +1836,22 @@ BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
return True;
}
+
+/*******************************************************************
+return the length of a UNISTR string.
+********************************************************************/
+
+uint32 str_len_uni(UNISTR *source)
+{
+ uint32 i=0;
+
+ if (!source->buffer)
+ return 0;
+
+ while (source->buffer[i])
+ i++;
+
+ return i;
+}
+
+
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index d7bdca4df99..ed95656fdae 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1972,8 +1972,7 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * 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))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout,
@@ -2021,8 +2020,7 @@ static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
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))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
return True;
@@ -2274,8 +2272,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
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))
+ if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
return False;
prs_align(ps);
if (!smb_io_unistr2("uni_comment", &info->uni_comment,
@@ -2316,8 +2313,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
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))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
prs_align(ps);
if (!smb_io_unistr2("uni_profile", &info->uni_profile,
@@ -2436,8 +2432,7 @@ static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
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))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
@@ -2596,8 +2591,7 @@ static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
return False;
- if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
- info->hdr_sec_desc.buffer, ps, depth))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
@@ -2831,8 +2825,7 @@ static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
return False;
- if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
- info->hdr_sec_desc.buffer, ps, depth))
+ if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
return False;
return True;
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 4b78d373bab..1b9ac51c613 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -589,6 +589,37 @@ BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
}
/*******************************************************************
+ Stream a uint16* (allocate memory if unmarshalling)
+ ********************************************************************/
+
+BOOL prs_pointer( const char *name, prs_struct *ps, int depth,
+ void **data, size_t data_size,
+ BOOL(*prs_fn)(const char*, prs_struct*, int, void*) )
+{
+ uint32 data_p;
+
+ /* caputure the pointer value to stream */
+
+ data_p = (uint32) *data;
+
+ if ( !prs_uint32("ptr", ps, depth, &data_p ))
+ return False;
+
+ /* we're done if there is no data */
+
+ if ( !data_p )
+ return True;
+
+ if (UNMARSHALLING(ps)) {
+ if ( !(*data = PRS_ALLOC_MEM_VOID(ps, data_size)) )
+ return False;
+ }
+
+ return prs_fn(name, ps, depth, *data);
+}
+
+
+/*******************************************************************
Stream a uint16.
********************************************************************/
@@ -598,12 +629,12 @@ BOOL prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)
if (q == NULL)
return False;
- if (UNMARSHALLING(ps)) {
+ if (UNMARSHALLING(ps)) {
if (ps->bigendian_data)
*data16 = RSVAL(q,0);
else
*data16 = SVAL(q,0);
- } else {
+ } else {
if (ps->bigendian_data)
RSSVAL(q,0,*data16);
else
@@ -916,28 +947,28 @@ BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
in byte chars. String is in little-endian format.
********************************************************************/
-BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER2 *str)
+BOOL prs_regval_buffer(BOOL charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf)
{
char *p;
- char *q = prs_mem_get(ps, str->buf_len);
+ char *q = prs_mem_get(ps, buf->buf_len);
if (q == NULL)
return False;
if (UNMARSHALLING(ps)) {
- if (str->buf_len > str->buf_max_len) {
+ if (buf->buf_len > buf->buf_max_len) {
return False;
}
- if ( str->buf_max_len ) {
- str->buffer = PRS_ALLOC_MEM(ps, uint16, str->buf_max_len);
- if ( str->buffer == NULL )
+ if ( buf->buf_max_len ) {
+ buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len);
+ if ( buf->buffer == NULL )
return False;
}
}
- p = (char *)str->buffer;
+ p = (char *)buf->buffer;
- dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len/2);
- ps->data_offset += str->buf_len;
+ dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2);
+ ps->data_offset += buf->buf_len;
return True;
}
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index a67a3973b95..a51b4269e3a 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -6,7 +6,8 @@
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Marc Jacobsen 1999.
* Copyright (C) Simo Sorce 2000.
- * Copyright (C) Gerald Carter 2002.
+ * Copyright (C) Jeremy Cooper 2004
+ * Copyright (C) Gerald Carter 2002-2005.
*
* 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,10 +30,10 @@
#define DBGC_CLASS DBGC_RPC_PARSE
/*******************************************************************
- Fill in a BUFFER2 for the data given a REGISTRY_VALUE
+ Fill in a REGVAL_BUFFER for the data given a REGISTRY_VALUE
*******************************************************************/
-static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
+static uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val )
{
uint32 real_size = 0;
@@ -40,151 +41,72 @@ static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
return 0;
real_size = regval_size(val);
- init_buffer2( buf2, (unsigned char*)regval_data_p(val), real_size );
+ init_regval_buffer( buf2, (unsigned char*)regval_data_p(val), real_size );
return real_size;
}
/*******************************************************************
- Inits a structure.
+ Inits a hive connect request structure
********************************************************************/
-void init_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
- uint16 unknown_0, uint32 level)
+void init_reg_q_open_hive( REG_Q_OPEN_HIVE *q_o, uint32 access_desired )
{
- q_o->ptr = 1;
- q_o->unknown_0 = unknown_0;
- q_o->unknown_1 = 0x0; /* random - changes */
- q_o->level = level;
+
+ q_o->server = TALLOC_P( get_talloc_ctx(), uint16);
+ *q_o->server = 0x1;
+
+ q_o->access = access_desired;
}
/*******************************************************************
-reads or writes a structure.
+Marshalls a hive connect request
********************************************************************/
-BOOL reg_io_q_open_hkcr(const char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_hive(const char *desc, REG_Q_OPEN_HIVE *q_u,
+ prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
+ prs_debug(ps, depth, desc, "reg_io_q_open_hive");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
+ if(!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
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("level ", ps, depth, &r_q->level))
- return False;
- }
+ if(!prs_uint32("access", ps, depth, &q_u->access))
+ return False;
return True;
}
/*******************************************************************
-reads or writes a structure.
+Unmarshalls a hive connect response
********************************************************************/
-BOOL reg_io_r_open_hkcr(const char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_hive(const char *desc, REG_R_OPEN_HIVE *r_u,
+ prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
+ prs_debug(ps, depth, desc, "reg_io_r_open_hive");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
- return False;
-
- if(!prs_werror("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(const 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(const 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))
+ if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
return False;
- if (!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
-
-
-
/*******************************************************************
Inits a structure.
********************************************************************/
@@ -198,9 +120,9 @@ void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_flush_key(const char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_flush_key(const char *desc, REG_Q_FLUSH_KEY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_flush_key");
@@ -209,19 +131,20 @@ BOOL reg_io_q_flush_key(const char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
return True;
}
/*******************************************************************
-reads or writes a structure.
+Unmarshalls a registry key flush response
********************************************************************/
-BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_u,
+ prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_flush_key");
@@ -230,7 +153,7 @@ BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -240,12 +163,14 @@ BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps,
reads or writes SEC_DESC_BUF and SEC_DATA structures.
********************************************************************/
-static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DESC_BUF *data, prs_struct *ps, int depth)
+static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
+ SEC_DESC_BUF *data, prs_struct *ps, int depth)
{
if (ptr != 0) {
uint32 hdr_offset;
uint32 old_offset;
- if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset))
+ if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth,
+ &hdr_offset))
return False;
old_offset = prs_offset(ps);
@@ -256,14 +181,16 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DES
}
if (ptr3 == NULL || *ptr3 != 0) {
- if(!sec_io_desc_buf("data ", &data, ps, depth)) /* JRA - this line is probably wrong... */
+ /* JRA - this next line is probably wrong... */
+ if(!sec_io_desc_buf("data ", &data, ps, depth))
return False;
}
- if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
- data->max_len, data->len))
+ if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth,
+ hdr_offset, data->max_len, data->len))
return False;
- if(!prs_set_offset(ps, old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
+ if(!prs_set_offset(ps, old_offset + data->len +
+ sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
return False;
if(!prs_align(ps))
@@ -274,28 +201,25 @@ static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DES
}
/*******************************************************************
- Inits a structure.
+ Inits a registry key create request
********************************************************************/
void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *name, char *class, SEC_ACCESS *sam_access,
- SEC_DESC_BUF *sec_buf)
+ char *name, char *class, uint32 access_desired,
+ SEC_DESC_BUF *sec_buf)
{
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
- init_unistr2(&q_c->uni_class, class, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_class, &q_c->uni_class);
+ init_unistr4( &q_c->name, name, UNI_STR_TERMINATE );
+ init_unistr4( &q_c->class, class, UNI_STR_TERMINATE );
- q_c->reserved = 0x00000000;
- memcpy(&q_c->sam_access, sam_access, sizeof(q_c->sam_access));
+ q_c->access = access_desired;
- q_c->ptr1 = 1;
- q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
+ q_c->sec_info = TALLOC_P( get_talloc_ctx(), uint32 );
+ *q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
q_c->data = sec_buf;
q_c->ptr2 = 1;
@@ -305,12 +229,13 @@ void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
}
/*******************************************************************
-reads or writes a structure.
+Marshalls a registry key create request
********************************************************************/
-BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *q_u,
+ prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_create_key");
@@ -319,54 +244,49 @@ BOOL reg_io_q_create_key(const char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *p
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
return False;
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4 ("name", ps, depth, &q_u->name))
return False;
if(!prs_align(ps))
return False;
- if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+ if(!prs_unistr4 ("class", ps, depth, &q_u->class))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("reserved", ps, depth, &r_q->reserved))
+ if(!prs_uint32("reserved", ps, depth, &q_u->reserved))
return False;
- if(!sec_io_access("sam_access", &r_q->sam_access, ps, depth))
+ if(!prs_uint32("access", ps, depth, &q_u->access))
return False;
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+ if(!prs_pointer("sec_info", ps, depth, (void**)&q_u->sec_info, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
- return False;
- }
-
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+ if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
return False;
- if(!reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth))
+ if(!reg_io_hdrbuf_sec(q_u->ptr2, &q_u->ptr3, &q_u->hdr_sec, q_u->data,
+ ps, depth))
return False;
- if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+#if 0
+ if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
return False;
+#endif
return True;
}
/*******************************************************************
-reads or writes a structure.
+Unmarshalls a registry key create response
********************************************************************/
-BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_u,
+ prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_create_key");
@@ -375,12 +295,12 @@ BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *p
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_r->key_pol, ps, depth))
+ if(!smb_io_pol_hnd("", &r_u->key_pol, ps, depth))
return False;
- if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+ if(!prs_uint32("unknown", ps, depth, &r_u->unknown))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -392,23 +312,22 @@ BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *p
********************************************************************/
void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
- char *name)
+ char *name)
{
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
-
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+ init_unistr4(&q_c->name, name, UNI_STR_TERMINATE);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *q_u,
+ prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_val");
@@ -417,12 +336,10 @@ BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
return False;
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &q_u->name))
return False;
if(!prs_align(ps))
return False;
@@ -435,9 +352,10 @@ BOOL reg_io_q_delete_val(const char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_u,
+ prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_val");
@@ -446,7 +364,7 @@ BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -457,23 +375,23 @@ BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct
********************************************************************/
void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
- char *name)
+ char *name)
{
ZERO_STRUCTP(q_c);
memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
- init_unistr2(&q_c->uni_name, name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_c->hdr_name, &q_c->uni_name);
+ init_unistr4(&q_c->name, name, UNI_STR_TERMINATE);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_delete_key(const char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_delete_key(const char *desc, REG_Q_DELETE_KEY *q_u,
+ prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_key");
@@ -482,12 +400,10 @@ BOOL reg_io_q_delete_key(const char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *p
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pnt_pol, ps, depth))
return False;
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("", ps, depth, &q_u->name))
return False;
if(!prs_align(ps))
return False;
@@ -499,9 +415,9 @@ BOOL reg_io_q_delete_key(const char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *p
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_key");
@@ -510,7 +426,7 @@ BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *p
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -520,21 +436,21 @@ BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *p
Inits a structure.
********************************************************************/
-void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, UNISTR2 *uni2)
+void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, const char *class)
{
ZERO_STRUCTP(q_o);
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
- init_uni_hdr(&q_o->hdr_class, uni2);
+ init_unistr4(&q_o->class, class, UNI_STR_TERMINATE);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_query_key");
@@ -543,11 +459,9 @@ BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
+ if(!prs_unistr4("class", ps, depth, &q_u->class))
return False;
if(!prs_align(ps))
@@ -561,9 +475,9 @@ BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps,
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_query_key");
@@ -572,32 +486,30 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!smb_io_unihdr ("", &r_r->hdr_class, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_r->uni_class, r_r->hdr_class.buffer, ps, depth))
+ if(!prs_unistr4("class", ps, depth, &r_u->class))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("num_subkeys ", ps, depth, &r_r->num_subkeys))
+ if(!prs_uint32("num_subkeys ", ps, depth, &r_u->num_subkeys))
return False;
- if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen))
+ if(!prs_uint32("max_subkeylen ", ps, depth, &r_u->max_subkeylen))
return False;
- if(!prs_uint32("reserved ", ps, depth, &r_r->reserved))
+ if(!prs_uint32("reserved ", ps, depth, &r_u->reserved))
return False;
- if(!prs_uint32("num_values ", ps, depth, &r_r->num_values))
+ if(!prs_uint32("num_values ", ps, depth, &r_u->num_values))
return False;
- if(!prs_uint32("max_valnamelen", ps, depth, &r_r->max_valnamelen))
+ if(!prs_uint32("max_valnamelen", ps, depth, &r_u->max_valnamelen))
return False;
- if(!prs_uint32("max_valbufsize", ps, depth, &r_r->max_valbufsize))
+ if(!prs_uint32("max_valbufsize", ps, depth, &r_u->max_valbufsize))
return False;
- if(!prs_uint32("sec_desc ", ps, depth, &r_r->sec_desc))
+ if(!prs_uint32("sec_desc ", ps, depth, &r_u->sec_desc))
return False;
- if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
+ if(!smb_io_time("mod_time ", &r_u->mod_time, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -607,7 +519,7 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
Inits a structure.
********************************************************************/
-void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
+void init_reg_q_getversion(REG_Q_GETVERSION *q_o, POLICY_HND *hnd)
{
memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
}
@@ -617,18 +529,18 @@ void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_unknown_1a(const char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_getversion(const char *desc, REG_Q_GETVERSION *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_q_unknown_1a");
+ prs_debug(ps, depth, desc, "reg_io_q_getversion");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
return True;
@@ -638,20 +550,20 @@ BOOL reg_io_q_unknown_1a(const char *desc, REG_Q_UNKNOWN_1A *r_q, prs_struct *p
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_unknown_1a(const char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_getversion(const char *desc, REG_R_GETVERSION *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_r_unknown_1a");
+ prs_debug(ps, depth, desc, "reg_io_r_getversion");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
+ if(!prs_uint32("unknown", ps, depth, &r_u->unknown))
return False;
- if(!prs_werror("status" , ps, depth, &r_r->status))
+ if(!prs_werror("status" , ps, depth, &r_u->status))
return False;
return True;
@@ -662,26 +574,24 @@ BOOL reg_io_r_unknown_1a(const char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *p
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_save_key(const char *desc, REG_Q_SAVE_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_restore_key(const char *desc, REG_Q_RESTORE_KEY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_q_save_key");
+ prs_debug(ps, depth, desc, "reg_io_q_restore_key");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!smb_io_unihdr ("hdr_file", &r_q->hdr_file, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_file", &r_q->uni_file, r_q->hdr_file.buffer, ps, depth))
+ if(!prs_unistr4("filename", ps, depth, &q_u->filename))
return False;
- if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
+ if(!prs_uint32("flags", ps, depth, &q_u->flags))
return False;
return True;
@@ -691,61 +601,48 @@ BOOL reg_io_q_save_key(const char *desc, REG_Q_SAVE_KEY *r_q, prs_struct *ps, i
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_save_key(const char *desc, REG_R_SAVE_KEY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_restore_key(const char *desc, REG_R_RESTORE_KEY *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_r_save_key");
+ prs_debug(ps, depth, desc, "reg_io_r_restore_key");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_werror("status" , ps, depth, &r_r->status))
+ if(!prs_werror("status" , ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-void init_reg_q_open_hku(REG_Q_OPEN_HKU *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_hku(const char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_save_key(const char *desc, REG_Q_SAVE_KEY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_q_open_hku");
+ prs_debug(ps, depth, desc, "reg_io_q_save_key");
depth++;
if(!prs_align(ps))
return False;
-
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
+
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
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;
- }
+
+ if(!prs_unistr4("filename", ps, depth, &q_u->filename))
+ return False;
+
+#if 0 /* reg_io_sec_attr() */
+ if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
+ return False;
+#endif
return True;
}
@@ -754,21 +651,18 @@ BOOL reg_io_q_open_hku(const char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, i
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_hku(const char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_save_key(const char *desc, REG_R_SAVE_KEY *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_r_open_hku");
+ prs_debug(ps, depth, desc, "reg_io_r_save_key");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
- return False;
-
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status" , ps, depth, &r_u->status))
return False;
return True;
@@ -814,7 +708,7 @@ reads or writes a structure.
BOOL reg_io_r_close(const char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_close");
@@ -838,24 +732,25 @@ BOOL reg_io_r_close(const char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int dep
makes a structure.
********************************************************************/
-void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf)
+void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_u, POLICY_HND *pol,
+ uint32 sec_info, SEC_DESC_BUF *sec_desc_buf)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- q_i->sec_info = DACL_SECURITY_INFORMATION;
+ q_u->sec_info = sec_info;
- q_i->ptr = 1;
- init_buf_hdr(&q_i->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
- q_i->data = sec_desc_buf;
+ q_u->ptr = 1;
+ init_buf_hdr(&q_u->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
+ q_u->data = sec_desc_buf;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_set_key_sec(const char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_key_sec(const char *desc, REG_Q_SET_KEY_SEC *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
@@ -864,15 +759,15 @@ BOOL reg_io_q_set_key_sec(const char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+ if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
+ if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
return False;
- if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+ if(!reg_io_hdrbuf_sec(q_u->ptr, NULL, &q_u->hdr_sec, q_u->data, ps, depth))
return False;
return True;
@@ -882,9 +777,9 @@ BOOL reg_io_q_set_key_sec(const char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
@@ -893,7 +788,7 @@ BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &q_u->status))
return False;
return True;
@@ -904,28 +799,27 @@ BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *
makes a structure.
********************************************************************/
-void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_buf_size, SEC_DESC_BUF *psdb)
+void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_u, POLICY_HND *pol,
+ uint32 sec_info, uint32 sec_buf_size,
+ SEC_DESC_BUF *psdb)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- q_i->sec_info = OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION;
+ q_u->sec_info = sec_info;
- q_i->ptr = psdb != NULL ? 1 : 0;
- q_i->data = psdb;
+ q_u->ptr = psdb != NULL ? 1 : 0;
+ q_u->data = psdb;
- init_buf_hdr(&q_i->hdr_sec, sec_buf_size, 0);
+ init_buf_hdr(&q_u->hdr_sec, sec_buf_size, 0);
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_get_key_sec(const char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_get_key_sec(const char *desc, REG_Q_GET_KEY_SEC *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_get_key_sec");
@@ -934,15 +828,15 @@ BOOL reg_io_q_get_key_sec(const char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
+ if(!prs_uint32("sec_info", ps, depth, &q_u->sec_info))
return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
+ if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
return False;
- if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
+ if(!reg_io_hdrbuf_sec(q_u->ptr, NULL, &q_u->hdr_sec, q_u->data, ps, depth))
return False;
return True;
@@ -968,9 +862,9 @@ makes a structure.
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_get_key_sec");
@@ -979,19 +873,19 @@ BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
+ if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
return False;
- if (r_q->ptr != 0) {
- if(!smb_io_hdrbuf("", &r_q->hdr_sec, ps, depth))
+ if (q_u->ptr != 0) {
+ if(!smb_io_hdrbuf("", &q_u->hdr_sec, ps, depth))
return False;
- if(!sec_io_desc_buf("", &r_q->data, ps, depth))
+ if(!sec_io_desc_buf("", &q_u->data, ps, depth))
return False;
if(!prs_align(ps))
return False;
}
- if(!prs_werror("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &q_u->status))
return False;
return True;
@@ -1001,29 +895,29 @@ BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct
makes a structure.
********************************************************************/
-BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name)
+BOOL init_reg_q_info(REG_Q_INFO *q_u, POLICY_HND *pol, const char *val_name,
+ REGVAL_BUFFER *value_output)
{
- if (q_i == NULL)
+ if (q_u == NULL)
return False;
- q_i->pol = *pol;
+ q_u->pol = *pol;
- init_unistr2(&q_i->uni_type, val_name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_i->hdr_type, &q_i->uni_type);
+ init_unistr4(&q_u->name, val_name, UNI_STR_TERMINATE);
- q_i->ptr_reserved = 1;
- q_i->ptr_buf = 1;
+ q_u->ptr_reserved = 1;
+ q_u->ptr_buf = 1;
- q_i->ptr_bufsize = 1;
- q_i->bufsize = 0;
- q_i->buf_unk = 0;
+ q_u->ptr_bufsize = 1;
+ q_u->bufsize = value_output->buf_max_len;
+ q_u->buf_unk = 0;
- q_i->unk1 = 0;
- q_i->ptr_buflen = 1;
- q_i->buflen = 0;
+ q_u->unk1 = 0;
+ q_u->ptr_buflen = 1;
+ q_u->buflen = value_output->buf_max_len;
- q_i->ptr_buflen2 = 1;
- q_i->buflen2 = 0;
+ q_u->ptr_buflen2 = 1;
+ q_u->buflen2 = 0;
return True;
}
@@ -1032,9 +926,9 @@ BOOL init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char* val_name)
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_info(const char *desc, REG_Q_INFO *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_info");
@@ -1043,43 +937,41 @@ BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_type, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!smb_io_unistr2("", &r_q->uni_type, r_q->hdr_type.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &q_u->name))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_reserved", ps, depth, &(r_q->ptr_reserved)))
+ if(!prs_uint32("ptr_reserved", ps, depth, &(q_u->ptr_reserved)))
return False;
- if(!prs_uint32("ptr_buf", ps, depth, &(r_q->ptr_buf)))
+ if(!prs_uint32("ptr_buf", ps, depth, &(q_u->ptr_buf)))
return False;
- if(r_q->ptr_buf) {
- if(!prs_uint32("ptr_bufsize", ps, depth, &(r_q->ptr_bufsize)))
+ if(q_u->ptr_buf) {
+ if(!prs_uint32("ptr_bufsize", ps, depth, &(q_u->ptr_bufsize)))
return False;
- if(!prs_uint32("bufsize", ps, depth, &(r_q->bufsize)))
+ if(!prs_uint32("bufsize", ps, depth, &(q_u->bufsize)))
return False;
- if(!prs_uint32("buf_unk", ps, depth, &(r_q->buf_unk)))
+ if(!prs_uint32("buf_unk", ps, depth, &(q_u->buf_unk)))
return False;
}
- if(!prs_uint32("unk1", ps, depth, &(r_q->unk1)))
+ if(!prs_uint32("unk1", ps, depth, &(q_u->unk1)))
return False;
- if(!prs_uint32("ptr_buflen", ps, depth, &(r_q->ptr_buflen)))
+ if(!prs_uint32("ptr_buflen", ps, depth, &(q_u->ptr_buflen)))
return False;
- if (r_q->ptr_buflen) {
- if(!prs_uint32("buflen", ps, depth, &(r_q->buflen)))
+ if (q_u->ptr_buflen) {
+ if(!prs_uint32("buflen", ps, depth, &(q_u->buflen)))
return False;
- if(!prs_uint32("ptr_buflen2", ps, depth, &(r_q->ptr_buflen2)))
+ if(!prs_uint32("ptr_buflen2", ps, depth, &(q_u->ptr_buflen2)))
return False;
- if(!prs_uint32("buflen2", ps, depth, &(r_q->buflen2)))
+ if(!prs_uint32("buflen2", ps, depth, &(q_u->buflen2)))
return False;
}
@@ -1091,72 +983,36 @@ BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth
New version to replace older init_reg_r_info()
********************************************************************/
-BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
+BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_u,
REGISTRY_VALUE *val, WERROR status)
{
- uint32 buf_len = 0;
- BUFFER2 buf2;
+ uint32 buf_len = 0;
+ REGVAL_BUFFER buf2;
- if(r_r == NULL)
+ if( !r_u || !val )
return False;
- if ( !val )
- return False;
-
- r_r->ptr_type = 1;
- r_r->type = val->type;
+ r_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->type = val->type;
- /* if include_keyval is not set, don't send the key value, just
- the buflen data. probably used by NT5 to allocate buffer space - SK */
-
- if ( include_keyval ) {
- r_r->ptr_uni_val = 1;
- buf_len = reg_init_buffer2( &r_r->uni_val, val );
+ buf_len = reg_init_regval_buffer( &buf2, val );
- }
- else {
- /* dummy buffer used so we can get the size */
- r_r->ptr_uni_val = 0;
- buf_len = reg_init_buffer2( &buf2, val );
- }
-
- r_r->ptr_max_len = 1;
- r_r->buf_max_len = buf_len;
-
- r_r->ptr_len = 1;
- r_r->buf_len = buf_len;
-
- r_r->status = status;
-
- return True;
-}
-
-/*******************************************************************
- Inits a structure.
-********************************************************************/
-
-BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- BUFFER2* buf, uint32 type, WERROR status)
-{
- if(r_r == NULL)
- return False;
-
- r_r->ptr_type = 1;
- r_r->type = type;
+ r_u->buf_max_len = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->buf_max_len = buf_len;
+ r_u->buf_len = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->buf_len = buf_len;
+
/* if include_keyval is not set, don't send the key value, just
the buflen data. probably used by NT5 to allocate buffer space - SK */
- r_r->ptr_uni_val = include_keyval ? 1:0;
- r_r->uni_val = *buf;
-
- r_r->ptr_max_len = 1;
- r_r->buf_max_len = r_r->uni_val.buf_max_len;
-
- r_r->ptr_len = 1;
- r_r->buf_len = r_r->uni_val.buf_len;
+ if ( include_keyval ) {
+ r_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+ /* steal the memory */
+ *r_u->value = buf2;
+ }
- r_r->status = status;
+ r_u->status = status;
return True;
}
@@ -1165,9 +1021,9 @@ BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_info");
@@ -1176,41 +1032,20 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type)))
+ if ( !prs_pointer("type", ps, depth, (void**)&r_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (r_r->ptr_type != 0) {
- if(!prs_uint32("type", ps, depth, &r_r->type))
- return False;
- }
-
- if(!prs_uint32("ptr_uni_val", ps, depth, &(r_r->ptr_uni_val)))
+ if ( !prs_pointer("value", ps, depth, (void**)&r_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
return False;
-
- if(r_r->ptr_uni_val != 0) {
- if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
- return False;
- }
-
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len)))
+ if ( !prs_pointer("buf_max_len", ps, depth, (void**)&r_u->buf_max_len, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
-
- if (r_r->ptr_max_len != 0) {
- if(!prs_uint32("buf_max_len", ps, depth, &(r_r->buf_max_len)))
+ if ( !prs_pointer("buf_len", ps, depth, (void**)&r_u->buf_len, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- }
- if(!prs_uint32("ptr_len", ps, depth, &(r_r->ptr_len)))
- return False;
- if (r_r->ptr_len != 0) {
- if(!prs_uint32("buf_len", ps, depth, &(r_r->buf_len)))
- return False;
- }
-
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1220,28 +1055,29 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
makes a structure.
********************************************************************/
-void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
- uint32 val_idx, UNISTR2 *uni2,
+void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_u, POLICY_HND *pol,
+ uint32 val_idx, char *name,
uint32 max_buf_len)
{
- ZERO_STRUCTP(q_i);
+ ZERO_STRUCTP(q_u);
+
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ q_u->val_index = val_idx;
- q_i->val_index = val_idx;
- init_uni_hdr(&q_i->hdr_name, uni2);
+ init_unistr4( &q_u->name, name, UNI_STR_TERMINATE );
- q_i->ptr_type = 1;
- q_i->type = 0x0;
+ q_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+ *q_u->type = 0x0;
- q_i->ptr_value = 1;
- q_i->buf_value.buf_max_len = max_buf_len;
+ q_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+ q_u->value->buf_max_len = max_buf_len;
- q_i->ptr1 = 1;
- q_i->len_value1 = max_buf_len;
+ q_u->len_value1 = TALLOC_P( get_talloc_ctx(), uint32 );
+ *q_u->len_value1 = max_buf_len;
- q_i->ptr2 = 1;
- q_i->len_value2 = 0;
+ q_u->len_value2 = TALLOC_P( get_talloc_ctx(), uint32 );
+ *q_u->len_value2 = max_buf_len;
}
/*******************************************************************
@@ -1260,26 +1096,25 @@ void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
- init_unistr2( &r_u->uni_name, val->valuename, UNI_STR_TERMINATE);
- init_uni_hdr( &r_u->hdr_name, &r_u->uni_name);
+ init_unistr4( &r_u->name, val->valuename, UNI_STR_TERMINATE);
/* type */
- r_u->ptr_type = 1;
- r_u->type = val->type;
+ r_u->type = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->type = val->type;
/* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
- r_u->ptr_value = 1;
- real_size = reg_init_buffer2( &r_u->buf_value, val );
+ r_u->value = TALLOC_P( get_talloc_ctx(), REGVAL_BUFFER );
+ real_size = reg_init_regval_buffer( r_u->value, val );
/* lengths */
- r_u->ptr1 = 1;
- r_u->len_value1 = real_size;
+ r_u->len_value1 = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->len_value1 = real_size;
- r_u->ptr2 = 1;
- r_u->len_value2 = real_size;
+ r_u->len_value2 = TALLOC_P( get_talloc_ctx(), uint32 );
+ *r_u->len_value2 = real_size;
DEBUG(8,("init_reg_r_enum_val: Exit\n"));
}
@@ -1288,9 +1123,9 @@ void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_enum_val(const char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_val(const char *desc, REG_Q_ENUM_VALUE *q_u, prs_struct *ps, int depth)
{
- if (q_q == NULL)
+ if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_val");
@@ -1299,46 +1134,29 @@ BOOL reg_io_q_enum_val(const char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
+ if(!prs_uint32("val_index", ps, depth, &q_u->val_index))
return False;
- if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &q_u->name ))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_type", ps, depth, &q_q->ptr_type))
+ if(!prs_pointer("type", ps, depth, (void**)&q_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (q_q->ptr_type != 0) {
- if(!prs_uint32("type", ps, depth, &q_q->type))
- return False;
- }
-
- if(!prs_uint32("ptr_value", ps, depth, &q_q->ptr_value))
- return False;
- if(!smb_io_buffer2("buf_value", &q_q->buf_value, q_q->ptr_value, ps, depth))
+ if ( !prs_pointer("value", ps, depth, (void**)&q_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+ if(!prs_pointer("len_value1", ps, depth, (void**)&q_u->len_value1, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (q_q->ptr1 != 0) {
- if(!prs_uint32("len_value1", ps, depth, &q_q->len_value1))
- return False;
- }
- if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+ if(!prs_pointer("len_value2", ps, depth, (void**)&q_u->len_value2, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (q_q->ptr2 != 0) {
- if(!prs_uint32("len_value2", ps, depth, &q_q->len_value2))
- return False;
- }
return True;
}
@@ -1347,9 +1165,9 @@ BOOL reg_io_q_enum_val(const char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps,
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_val");
@@ -1358,43 +1176,26 @@ BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!smb_io_unihdr ("hdr_name", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &r_u->name ))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr_type", ps, depth, &r_q->ptr_type))
+ if(!prs_pointer("type", ps, depth, (void**)&r_u->type, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (r_q->ptr_type != 0) {
- if(!prs_uint32("type", ps, depth, &r_q->type))
- return False;
- }
-
- if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
- return False;
- if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
+ if ( !prs_pointer("value", ps, depth, (void**)&r_u->value, sizeof(REGVAL_BUFFER), (PRS_POINTER_CAST)smb_io_regval_buffer))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+ if(!prs_pointer("len_value1", ps, depth, (void**)&r_u->len_value1, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("len_value1", ps, depth, &r_q->len_value1))
- return False;
- }
-
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+ if(!prs_pointer("len_value2", ps, depth, (void**)&r_u->len_value2, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
return False;
- if (r_q->ptr2 != 0) {
- if(!prs_uint32("len_value2", ps, depth, &r_q->len_value2))
- return False;
- }
- if(!prs_werror("status", ps, depth, &r_q->status))
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1404,53 +1205,55 @@ BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps,
makes a structure.
********************************************************************/
-void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
+void init_reg_q_set_val(REG_Q_SET_VALUE *q_u, POLICY_HND *pol,
char *val_name, uint32 type,
- BUFFER3 *val)
+ RPC_DATA_BLOB *val)
{
- ZERO_STRUCTP(q_i);
+ ZERO_STRUCTP(q_u);
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- init_unistr2(&q_i->uni_name, val_name, UNI_STR_TERMINATE);
- init_uni_hdr(&q_i->hdr_name, &q_i->uni_name);
+ init_unistr4(&q_u->name, val_name, UNI_STR_TERMINATE);
- q_i->type = type;
- q_i->buf_value = val;
+ q_u->type = type;
+ q_u->value = *val;
+ q_u->size = val->buf_len;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_create_val(const char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_set_val(const char *desc, REG_Q_SET_VALUE *q_u, prs_struct *ps, int depth)
{
- if (q_q == NULL)
+ if (q_u == NULL)
return False;
- prs_debug(ps, depth, desc, "reg_io_q_create_val");
+ prs_debug(ps, depth, desc, "reg_io_q_set_val");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &q_u->name ))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("type", ps, depth, &q_q->type))
+ if(!prs_uint32("type", ps, depth, &q_u->type))
return False;
- if(!smb_io_buffer3("buf_value", q_q->buf_value, ps, depth))
+
+ if(!smb_io_rpc_blob("value", &q_u->value, ps, depth ))
return False;
if(!prs_align(ps))
return False;
+ if(!prs_uint32("size", ps, depth, &q_u->size))
+ return False;
+
return True;
}
@@ -1458,18 +1261,18 @@ BOOL reg_io_q_create_val(const char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_create_val(const char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_set_val(const char *desc, REG_R_SET_VALUE *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_r_create_val");
+ prs_debug(ps, depth, desc, "reg_io_r_set_val");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &q_u->status))
return False;
return True;
@@ -1479,23 +1282,23 @@ BOOL reg_io_r_create_val(const char *desc, REG_R_CREATE_VALUE *r_q, prs_struct
makes a structure.
********************************************************************/
-void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_u, POLICY_HND *pol, uint32 key_idx)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- q_i->key_index = key_idx;
- q_i->key_name_len = 0;
- q_i->unknown_1 = 0x0414;
+ q_u->key_index = key_idx;
+ q_u->key_name_len = 0;
+ q_u->unknown_1 = 0x0414;
- q_i->ptr1 = 1;
- q_i->unknown_2 = 0x0000020A;
- memset(q_i->pad1, 0, sizeof(q_i->pad1));
+ q_u->ptr1 = 1;
+ q_u->unknown_2 = 0x0000020A;
+ memset(q_u->pad1, 0, sizeof(q_u->pad1));
- q_i->ptr2 = 1;
- memset(q_i->pad2, 0, sizeof(q_i->pad2));
+ q_u->ptr2 = 1;
+ memset(q_u->pad2, 0, sizeof(q_u->pad2));
- q_i->ptr3 = 1;
- unix_to_nt_time(&q_i->time, 0); /* current time? */
+ q_u->ptr3 = 1;
+ unix_to_nt_time(&q_u->time, 0); /* current time? */
}
/*******************************************************************
@@ -1525,9 +1328,9 @@ void init_reg_r_enum_key(REG_R_ENUM_KEY *r_u, char *subkey, uint32 unknown_1,
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_enum_key(const char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth)
+BOOL reg_io_q_enum_key(const char *desc, REG_Q_ENUM_KEY *q_u, prs_struct *ps, int depth)
{
- if (q_q == NULL)
+ if (q_u == NULL)
return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_key");
@@ -1536,39 +1339,39 @@ BOOL reg_io_q_enum_key(const char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, i
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!prs_uint32("key_index", ps, depth, &q_q->key_index))
+ if(!prs_uint32("key_index", ps, depth, &q_u->key_index))
return False;
- if(!prs_uint16("key_name_len", ps, depth, &q_q->key_name_len))
+ if(!prs_uint16("key_name_len", ps, depth, &q_u->key_name_len))
return False;
- if(!prs_uint16("unknown_1", ps, depth, &q_q->unknown_1))
+ if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
return False;
- if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
+ if(!prs_uint32("ptr1", ps, depth, &q_u->ptr1))
return False;
- if (q_q->ptr1 != 0) {
- if(!prs_uint32("unknown_2", ps, depth, &q_q->unknown_2))
+ if (q_u->ptr1 != 0) {
+ if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
return False;
- if(!prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1)))
+ if(!prs_uint8s(False, "pad1", ps, depth, q_u->pad1, sizeof(q_u->pad1)))
return False;
}
- if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
+ if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
return False;
- if (q_q->ptr2 != 0) {
- if(!prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2)))
+ if (q_u->ptr2 != 0) {
+ if(!prs_uint8s(False, "pad2", ps, depth, q_u->pad2, sizeof(q_u->pad2)))
return False;
}
- if(!prs_uint32("ptr3", ps, depth, &q_q->ptr3))
+ if(!prs_uint32("ptr3", ps, depth, &q_u->ptr3))
return False;
- if (q_q->ptr3 != 0) {
- if(!smb_io_time("", &q_q->time, ps, depth))
+ if (q_u->ptr3 != 0) {
+ if(!smb_io_time("", &q_u->time, ps, depth))
return False;
}
@@ -1579,9 +1382,9 @@ BOOL reg_io_q_enum_key(const char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, i
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_key");
@@ -1590,42 +1393,42 @@ BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, i
if(!prs_align(ps))
return False;
- if(!prs_uint16("key_name_len", ps, depth, &r_q->key_name_len))
+ if(!prs_uint16("key_name_len", ps, depth, &q_u->key_name_len))
return False;
- if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
+ if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
return False;
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
+ if(!prs_uint32("ptr1", ps, depth, &q_u->ptr1))
return False;
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
+ if (q_u->ptr1 != 0) {
+ if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
return False;
- if(!prs_uint32("unknown_3", ps, depth, &r_q->unknown_3))
+ if(!prs_uint32("unknown_3", ps, depth, &q_u->unknown_3))
return False;
- if(!smb_io_unistr3("key_name", &r_q->key_name, ps, depth))
+ if(!smb_io_unistr3("key_name", &q_u->key_name, ps, depth))
return False;
if(!prs_align(ps))
return False;
}
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
+ if(!prs_uint32("ptr2", ps, depth, &q_u->ptr2))
return False;
- if (r_q->ptr2 != 0) {
- if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
+ if (q_u->ptr2 != 0) {
+ if(!prs_uint8s(False, "pad2", ps, depth, q_u->pad2, sizeof(q_u->pad2)))
return False;
}
- if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
+ if(!prs_uint32("ptr3", ps, depth, &q_u->ptr3))
return False;
- if (r_q->ptr3 != 0) {
- if(!smb_io_time("", &r_q->time, ps, depth))
+ if (q_u->ptr3 != 0) {
+ if(!smb_io_time("", &q_u->time, ps, depth))
return False;
}
- if(!prs_werror("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &q_u->status))
return False;
return True;
@@ -1635,46 +1438,43 @@ BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, i
makes a structure.
********************************************************************/
-void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *q_u, POLICY_HND *pol,
char *key_name, uint32 access_desired)
{
- memcpy(&r_q->pol, pol, sizeof(r_q->pol));
+ memcpy(&q_u->pol, pol, sizeof(q_u->pol));
- init_unistr2(&r_q->uni_name, key_name, UNI_STR_TERMINATE);
- init_uni_hdr(&r_q->hdr_name, &r_q->uni_name);
+ init_unistr4(&q_u->name, key_name, UNI_STR_TERMINATE);
- r_q->unknown_0 = 0x00000000;
- r_q->access_desired = access_desired;
+ q_u->unknown_0 = 0x00000000;
+ q_u->access = access_desired;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
+BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *q_u, prs_struct *ps, int depth)
{
- if (r_q == NULL)
+ if ( !q_u )
return False;
- prs_debug(ps, depth, desc, "reg_io_q_entry");
+ prs_debug(ps, depth, desc, "reg_io_q_open_entry");
depth++;
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
+ if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
+ if(!prs_unistr4("name", ps, depth, &q_u->name))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("unknown_0 ", ps, depth, &r_q->unknown_0))
+ if(!prs_uint32("unknown_0 ", ps, depth, &q_u->unknown_0))
return False;
- if(!prs_uint32("access_desired ", ps, depth, &r_q->access_desired))
+ if(!prs_uint32("access", ps, depth, &q_u->access))
return False;
return True;
@@ -1684,24 +1484,24 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *p
Inits a structure.
********************************************************************/
-void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_u,
POLICY_HND *pol, WERROR werr)
{
if (W_ERROR_IS_OK(werr)) {
- memcpy(&r_r->pol, pol, sizeof(r_r->pol));
+ memcpy(&r_u->pol, pol, sizeof(r_u->pol));
} else {
- ZERO_STRUCT(r_r->pol);
+ ZERO_STRUCT(r_u->pol);
}
- r_r->status = werr;
+ r_u->status = werr;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
+BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_u, prs_struct *ps, int depth)
{
- if (r_r == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_open_entry");
@@ -1710,10 +1510,10 @@ BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *p
if(!prs_align(ps))
return False;
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
+ if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
return False;
- if(!prs_werror("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -1723,30 +1523,53 @@ BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *p
Inits a structure.
********************************************************************/
-void init_reg_q_shutdown(REG_Q_SHUTDOWN * q_s, const char *msg,
+void init_reg_q_shutdown(REG_Q_SHUTDOWN *q_u, const char *msg,
uint32 timeout, BOOL do_reboot, BOOL force)
{
- q_s->ptr_0 = 1;
- q_s->ptr_1 = 1;
- q_s->ptr_2 = 1;
+ q_u->server = TALLOC_P( get_talloc_ctx(), uint16 );
+ *q_u->server = 0x1;
+
+ q_u->message = TALLOC_P( get_talloc_ctx(), UNISTR4 );
+ init_unistr4( q_u->message, msg, UNI_FLAGS_NONE );
- init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
- init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+ q_u->timeout = timeout;
+
+ q_u->reboot = do_reboot ? 1 : 0;
+ q_u->force = force ? 1 : 0;
+}
- q_s->timeout = timeout;
+/*******************************************************************
+Inits a REG_Q_SHUTDOWN_EX structure.
+********************************************************************/
- q_s->reboot = do_reboot ? 1 : 0;
- q_s->force = force ? 1 : 0;
+void init_reg_q_shutdown_ex(REG_Q_SHUTDOWN_EX * q_u_ex, const char *msg,
+ uint32 timeout, BOOL do_reboot, BOOL force, uint32 reason)
+{
+ REG_Q_SHUTDOWN q_u;
+
+ ZERO_STRUCT( q_u );
+
+ init_reg_q_shutdown( &q_u, msg, timeout, do_reboot, force );
+
+ /* steal memory */
+
+ q_u_ex->server = q_u.server;
+ q_u_ex->message = q_u.message;
+
+ q_u_ex->reboot = q_u.reboot;
+ q_u_ex->force = q_u.force;
+
+ q_u_ex->reason = reason;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
+BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN *q_u, prs_struct *ps,
int depth)
{
- if (q_s == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_shutdown");
@@ -1755,37 +1578,34 @@ BOOL reg_io_q_shutdown(const char *desc, REG_Q_SHUTDOWN * q_s, prs_struct *ps,
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)))
+ if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
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))
+ if (!prs_pointer("message", ps, depth, (void**)&q_u->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
return False;
+
if (!prs_align(ps))
return False;
- if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
+ if (!prs_uint32("timeout", ps, depth, &(q_u->timeout)))
return False;
- if (!prs_uint8("force ", ps, depth, &(q_s->force)))
+
+ if (!prs_uint8("force ", ps, depth, &(q_u->force)))
return False;
- if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
+ if (!prs_uint8("reboot ", ps, depth, &(q_u->reboot)))
return False;
+
return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
+BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN *r_u, prs_struct *ps,
int depth)
{
- if (r_s == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_shutdown");
@@ -1794,29 +1614,93 @@ BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!prs_werror("status", ps, depth, &r_s->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
}
/*******************************************************************
-Inits a structure.
+reads or writes a REG_Q_SHUTDOWN_EX structure.
********************************************************************/
-void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN * q_s)
+
+BOOL reg_io_q_shutdown_ex(const char *desc, REG_Q_SHUTDOWN_EX *q_u, prs_struct *ps,
+ int depth)
{
+ if ( !q_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_shutdown_ex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
+ return False;
+
+ if (!prs_pointer("message", ps, depth, (void**)&q_u->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
+ return False;
- q_s->ptr_server = 0;
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("timeout", ps, depth, &(q_u->timeout)))
+ return False;
+
+ if (!prs_uint8("force ", ps, depth, &(q_u->force)))
+ return False;
+ if (!prs_uint8("reboot ", ps, depth, &(q_u->reboot)))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("reason", ps, depth, &(q_u->reason)))
+ return False;
+
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a REG_R_SHUTDOWN_EX structure.
+********************************************************************/
+BOOL reg_io_r_shutdown_ex(const char *desc, REG_R_SHUTDOWN_EX *r_u, prs_struct *ps,
+ int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "reg_io_r_shutdown_ex");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+
+/*******************************************************************
+Inits a structure.
+********************************************************************/
+void init_reg_q_abort_shutdown(REG_Q_ABORT_SHUTDOWN *q_u)
+{
+ q_u->server = TALLOC_P( get_talloc_ctx(), uint16 );
+ *q_u->server = 0x1;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
+BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN *q_u,
prs_struct *ps, int depth)
{
- if (q_s == NULL)
+ if ( !q_u )
return False;
prs_debug(ps, depth, desc, "reg_io_q_abort_shutdown");
@@ -1825,11 +1709,8 @@ BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
if (!prs_align(ps))
return False;
- if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+ if (!prs_pointer("server", ps, depth, (void**)&q_u->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
return False;
- if (q_s->ptr_server != 0)
- if (!prs_uint16("server", ps, depth, &(q_s->server)))
- return False;
return True;
}
@@ -1837,10 +1718,10 @@ BOOL reg_io_q_abort_shutdown(const char *desc, REG_Q_ABORT_SHUTDOWN * q_s,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
+BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN *r_u,
prs_struct *ps, int depth)
{
- if (r_s == NULL)
+ if ( !r_u )
return False;
prs_debug(ps, depth, desc, "reg_io_r_abort_shutdown");
@@ -1849,7 +1730,7 @@ BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
if (!prs_align(ps))
return False;
- if (!prs_werror("status", ps, depth, &r_s->status))
+ if (!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index aa296eb70a1..6bdab2e437c 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -36,7 +36,7 @@ interface/version dce/rpc pipe identification
0x8a885d04, 0x1ceb, 0x11c9, \
{ 0x9f, 0xe8 }, \
{ 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
+ 0x2b, 0x10, 0x48, 0x60 } \
}, 0x02 \
}
@@ -46,7 +46,7 @@ interface/version dce/rpc pipe identification
0x8a885d04, 0x1ceb, 0x11c9, \
{ 0x9f, 0xe8 }, \
{ 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
+ 0x2b, 0x10, 0x48, 0x60 } \
}, 0x02 \
}
@@ -56,7 +56,7 @@ interface/version dce/rpc pipe identification
0x6bffd098, 0xa112, 0x3610, \
{ 0x98, 0x33 }, \
{ 0x46, 0xc3, \
- 0xf8, 0x7e, 0x34, 0x5a } \
+ 0xf8, 0x7e, 0x34, 0x5a } \
}, 0x01 \
}
@@ -66,7 +66,7 @@ interface/version dce/rpc pipe identification
0x4b324fc8, 0x1670, 0x01d3, \
{ 0x12, 0x78 }, \
{ 0x5a, 0x47, \
- 0xbf, 0x6e, 0xe1, 0x88 } \
+ 0xbf, 0x6e, 0xe1, 0x88 } \
}, 0x03 \
}
@@ -76,7 +76,7 @@ interface/version dce/rpc pipe identification
0x12345778, 0x1234, 0xabcd, \
{ 0xef, 0x00 }, \
{ 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
+ 0x45, 0x67, 0x89, 0xab } \
}, 0x00 \
}
@@ -86,7 +86,7 @@ interface/version dce/rpc pipe identification
0x3919286a, 0xb10c, 0x11d0, \
{ 0x9b, 0xa8 }, \
{ 0x00, 0xc0, \
- 0x4f, 0xd9, 0x2e, 0xf5 } \
+ 0x4f, 0xd9, 0x2e, 0xf5 } \
}, 0x00 \
}
@@ -96,7 +96,7 @@ interface/version dce/rpc pipe identification
0x12345778, 0x1234, 0xabcd, \
{ 0xef, 0x00 }, \
{ 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xac } \
+ 0x45, 0x67, 0x89, 0xac } \
}, 0x01 \
}
@@ -106,7 +106,7 @@ interface/version dce/rpc pipe identification
0x12345678, 0x1234, 0xabcd, \
{ 0xef, 0x00 }, \
{ 0x01, 0x23, \
- 0x45, 0x67, 0xcf, 0xfb } \
+ 0x45, 0x67, 0xcf, 0xfb } \
}, 0x01 \
}
@@ -116,7 +116,7 @@ interface/version dce/rpc pipe identification
0x338cd001, 0x2244, 0x31f1, \
{ 0xaa, 0xaa }, \
{ 0x90, 0x00, \
- 0x38, 0x00, 0x10, 0x03 } \
+ 0x38, 0x00, 0x10, 0x03 } \
}, 0x01 \
}
@@ -126,7 +126,7 @@ interface/version dce/rpc pipe identification
0x12345678, 0x1234, 0xabcd, \
{ 0xef, 0x00 }, \
{ 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
+ 0x45, 0x67, 0x89, 0xab } \
}, 0x01 \
}
@@ -136,7 +136,7 @@ interface/version dce/rpc pipe identification
0x0, 0x0, 0x0, \
{ 0x00, 0x00 }, \
{ 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00 } \
+ 0x00, 0x00, 0x00, 0x00 } \
}, 0x00 \
}
@@ -170,6 +170,27 @@ interface/version dce/rpc pipe identification
}, 0x01 \
}
+#define SYNT_SVCCTL_V2 \
+{ \
+ { \
+ 0x367abb81, 0x9844, 0x35f1, \
+ { 0xad, 0x32 }, \
+ { 0x98, 0xf0, \
+ 0x38, 0x00, 0x10, 0x03 } \
+ }, 0x02 \
+}
+
+
+#define SYNT_EVENTLOG_V0 \
+{ \
+ { \
+ 0x82273fdc, 0xe32a, 0x18c3, \
+ { 0x3f, 0x78 }, \
+ { 0x82, 0x79, \
+ 0x29, 0xdc, 0x23, 0xea } \
+ }, 0x00 \
+}
+
/*
* IMPORTANT!! If you update this structure, make sure to
* update the index #defines in smb.h.
@@ -189,6 +210,8 @@ const struct pipe_id_info pipe_names [] =
{ PIPE_NETDFS , SYNT_NETDFS_V3 , PIPE_NETDFS , TRANS_SYNT_V2 },
{ PIPE_ECHO , SYNT_ECHO_V1 , PIPE_ECHO , TRANS_SYNT_V2 },
{ PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1 , PIPE_SHUTDOWN , TRANS_SYNT_V2 },
+ { PIPE_SVCCTL , SYNT_SVCCTL_V2 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_EVENTLOG, SYNT_EVENTLOG_V0 , PIPE_EVENTLOG , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index f6fdf102928..6a752688a0b 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -133,7 +133,7 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
* Note that the size is always a multiple of 4 bytes due to the
* nature of the data structure. Therefore the prs_align() calls
* have been removed as they through us off when doing two-layer
- * marshalling such as in the printing code (NEW_BUFFER). --jerry
+ * marshalling such as in the printing code (RPC_BUFFER). --jerry
*/
if (ppsa == NULL)
diff --git a/source/rpc_parse/parse_shutdown.c b/source/rpc_parse/parse_shutdown.c
index ad2d6e1a028..00daeaaaee7 100644
--- a/source/rpc_parse/parse_shutdown.c
+++ b/source/rpc_parse/parse_shutdown.c
@@ -2,6 +2,7 @@
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ * Copyright (C) Gerald (Jerry) Carter 2002-2005.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,12 +31,11 @@ Inits a structure.
void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
uint32 timeout, BOOL do_reboot, BOOL force)
{
- q_s->ptr_server = 1;
- q_s->server = 1;
- q_s->ptr_msg = 1;
+ q_s->server = TALLOC_P( get_talloc_ctx(), uint16 );
+ *q_s->server = 0x1;
- init_unistr2(&q_s->uni_msg, msg, UNI_FLAGS_NONE);
- init_uni_hdr(&q_s->hdr_msg, &q_s->uni_msg);
+ q_s->message = TALLOC_P( get_talloc_ctx(), UNISTR4 );
+ init_unistr4( q_s->message, msg, UNI_FLAGS_NONE );
q_s->timeout = timeout;
@@ -44,6 +44,29 @@ void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
}
/*******************************************************************
+********************************************************************/
+
+void init_shutdown_q_init_ex(SHUTDOWN_Q_INIT_EX * q_u_ex, const char *msg,
+ uint32 timeout, BOOL do_reboot, BOOL force, uint32 reason)
+{
+ SHUTDOWN_Q_INIT q_u;
+
+ ZERO_STRUCT( q_u );
+
+ init_shutdown_q_init( &q_u, msg, timeout, do_reboot, force );
+
+ /* steal memory */
+
+ q_u_ex->server = q_u.server;
+ q_u_ex->message = q_u.message;
+
+ q_u_ex->reboot = q_u.reboot;
+ q_u_ex->force = q_u.force;
+
+ q_u_ex->reason = reason;
+}
+
+/*******************************************************************
reads or writes a structure.
********************************************************************/
@@ -59,62 +82,119 @@ BOOL shutdown_io_q_init(const char *desc, SHUTDOWN_Q_INIT *q_s, prs_struct *ps,
if (!prs_align(ps))
return False;
- if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+ if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
return False;
- if (!prs_uint16("server", ps, depth, &(q_s->server)))
+
+ if (!prs_pointer("message", ps, depth, (void**)&q_s->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
return False;
if (!prs_align(ps))
return False;
- if (!prs_uint32("ptr_msg", ps, depth, &(q_s->ptr_msg)))
+
+ if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
return False;
- if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
+ if (!prs_uint8("force ", ps, depth, &(q_s->force)))
return False;
- if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
+ if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
return False;
+
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
+ int depth)
+{
+ if (r_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "shutdown_io_r_init");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_s->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a REG_Q_SHUTDOWN_EX structure.
+********************************************************************/
+
+BOOL shutdown_io_q_init_ex(const char *desc, SHUTDOWN_Q_INIT_EX * q_s, prs_struct *ps,
+ int depth)
+{
+ if (q_s == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "shutdown_io_q_init_ex");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
+ return False;
+
+ if (!prs_pointer("message", ps, depth, (void**)&q_s->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
+ return False;
+
if (!prs_align(ps))
return False;
if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
return False;
+
if (!prs_uint8("force ", ps, depth, &(q_s->force)))
return False;
if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
return False;
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("reason", ps, depth, &(q_s->reason)))
+ return False;
+
+
return True;
}
/*******************************************************************
-reads or writes a structure.
+reads or writes a REG_R_SHUTDOWN_EX structure.
********************************************************************/
-BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
- int depth)
+BOOL shutdown_io_r_init_ex(const char *desc, SHUTDOWN_R_INIT_EX * r_s, prs_struct *ps,
+ int depth)
{
if (r_s == NULL)
return False;
- prs_debug(ps, depth, desc, "shutdown_io_r_init");
+ prs_debug(ps, depth, desc, "shutdown_io_r_init_ex");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_s->status))
+ if(!prs_werror("status", ps, depth, &r_s->status))
return False;
return True;
}
+
/*******************************************************************
Inits a structure.
********************************************************************/
void init_shutdown_q_abort(SHUTDOWN_Q_ABORT *q_s)
{
-
- q_s->ptr_server = 0;
-
+ q_s->server = TALLOC_P( get_talloc_ctx(), uint16 );
+ *q_s->server = 0x1;
}
/*******************************************************************
@@ -132,11 +212,8 @@ BOOL shutdown_io_q_abort(const char *desc, SHUTDOWN_Q_ABORT *q_s,
if (!prs_align(ps))
return False;
- if (!prs_uint32("ptr_server", ps, depth, &(q_s->ptr_server)))
+ if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
return False;
- if (q_s->ptr_server != 0)
- if (!prs_uint16("server", ps, depth, &(q_s->server)))
- return False;
return True;
}
@@ -156,7 +233,7 @@ BOOL shutdown_io_r_abort(const char *desc, SHUTDOWN_R_ABORT *r_s,
if (!prs_align(ps))
return False;
- if (!prs_ntstatus("status", ps, depth, &r_s->status))
+ if (!prs_werror("status", ps, depth, &r_s->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index dc419a73b5f..78602dd806a 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -27,22 +27,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
-/*******************************************************************
-return the length of a UNISTR string.
-********************************************************************/
-
-static uint32 str_len_uni(UNISTR *source)
-{
- uint32 i=0;
-
- if (!source->buffer)
- return 0;
-
- while (source->buffer[i])
- i++;
-
- return i;
-}
/*******************************************************************
This should be moved in a more generic lib.
@@ -566,23 +550,22 @@ static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_st
/*******************************************************************
********************************************************************/
-static BOOL spool_io_user_level_1(const char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
+BOOL spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
{
prs_debug(ps, depth, desc, "");
depth++;
- /* reading */
- if (UNMARSHALLING(ps))
- ZERO_STRUCTP(q_u);
-
if (!prs_align(ps))
return False;
+
if (!prs_uint32("size", ps, depth, &q_u->size))
return False;
- if (!prs_uint32("client_name_ptr", ps, depth, &q_u->client_name_ptr))
+
+ if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
return False;
- if (!prs_uint32("user_name_ptr", ps, depth, &q_u->user_name_ptr))
+ if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
return False;
+
if (!prs_uint32("build", ps, depth, &q_u->build))
return False;
if (!prs_uint32("major", ps, depth, &q_u->major))
@@ -592,11 +575,12 @@ static BOOL spool_io_user_level_1(const char *desc, SPOOL_USER_1 *q_u, prs_struc
if (!prs_uint32("processor", ps, depth, &q_u->processor))
return False;
- if (!smb_io_unistr2("", &q_u->client_name, q_u->client_name_ptr, ps, depth))
+ if (!prs_io_unistr2("", ps, depth, q_u->client_name))
return False;
if (!prs_align(ps))
return False;
- if (!smb_io_unistr2("", &q_u->user_name, q_u->user_name_ptr, ps, depth))
+
+ if (!prs_io_unistr2("", ps, depth, q_u->user_name))
return False;
return True;
@@ -616,21 +600,20 @@ static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struc
if (!prs_align(ps))
return False;
- /* From looking at many captures in ethereal, it looks like
- the level and ptr fields should be transposed. -tpot */
-
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
- return False;
- switch (q_u->level) {
- case 1:
- if (!spool_io_user_level_1("", &q_u->user1, ps, depth))
- return False;
- break;
- default:
- return False;
+ switch ( q_u->level )
+ {
+ case 1:
+ if ( !prs_pointer( "" , ps, depth, (void**)&q_u->user.user1,
+ sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 ))
+ {
+ return False;
+ }
+ break;
+ default:
+ return False;
}
return True;
@@ -915,30 +898,31 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
const fstring user_name)
{
DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
- q_u->printername_ptr = (printername!=NULL)?1:0;
- init_unistr2(&q_u->printername, printername, UNI_STR_TERMINATE);
+
+ q_u->printername = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+ init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
q_u->printer_default.datatype_ptr = 0;
-/*
- q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
- init_unistr2(&q_u->printer_default.datatype, datatype, UNI_FLAGS_NONE);
-*/
+
q_u->printer_default.devmode_cont.size=0;
q_u->printer_default.devmode_cont.devmode_ptr=0;
q_u->printer_default.devmode_cont.devmode=NULL;
q_u->printer_default.access_required=access_required;
- q_u->user_switch=1;
- q_u->user_ctr.level=1;
- q_u->user_ctr.ptr=1;
- q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+10;
- q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
- q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
- q_u->user_ctr.user1.build=1381;
- q_u->user_ctr.user1.major=2;
- q_u->user_ctr.user1.minor=0;
- q_u->user_ctr.user1.processor=0;
- init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
- init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
+
+ q_u->user_switch = 1;
+
+ q_u->user_ctr.level = 1;
+ q_u->user_ctr.user.user1->size = strlen(clientname) + strlen(user_name) + 10;
+ q_u->user_ctr.user.user1->build = 1381;
+ q_u->user_ctr.user.user1->major = 2;
+ q_u->user_ctr.user.user1->minor = 0;
+ q_u->user_ctr.user.user1->processor = 0;
+
+ q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+ q_u->user_ctr.user.user1->user_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
+
+ init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
+ init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
return True;
}
@@ -947,23 +931,19 @@ 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,
- const char *srv_name,
- const char* clientname,
- const char* user_name,
- uint32 level,
- PRINTER_INFO_CTR *ctr)
+BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u,
+ const char *srv_name, const char* clientname, const char* user_name,
+ uint32 level, PRINTER_INFO_CTR *ctr)
{
DEBUG(5,("make_spoolss_q_addprinterex\n"));
- if (!ctr) return False;
+ 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, UNI_FLAGS_NONE);
+ q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
+ init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
q_u->level = level;
@@ -983,18 +963,20 @@ BOOL make_spoolss_q_addprinterex(
q_u->user_switch=1;
- q_u->user_ctr.level=1;
- q_u->user_ctr.ptr=1;
- q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
- q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
- q_u->user_ctr.user1.build=1381;
- q_u->user_ctr.user1.major=2;
- q_u->user_ctr.user1.minor=0;
- q_u->user_ctr.user1.processor=0;
- init_unistr2(&q_u->user_ctr.user1.client_name, clientname, UNI_STR_TERMINATE);
- init_unistr2(&q_u->user_ctr.user1.user_name, user_name, UNI_STR_TERMINATE);
- q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
- q_u->user_ctr.user1.client_name.uni_str_len + 2;
+ q_u->user_ctr.level = 1;
+ q_u->user_ctr.user.user1->build = 1381;
+ q_u->user_ctr.user.user1->major = 2;
+ q_u->user_ctr.user.user1->minor = 0;
+ q_u->user_ctr.user.user1->processor = 0;
+
+ q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
+ q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 );
+
+ init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
+ init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
+
+ q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
+ q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
return True;
}
@@ -1118,9 +1100,9 @@ BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_
if (!prs_align(ps))
return False;
- if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
+ if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
return False;
- if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
+ if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
return False;
if (!prs_align(ps))
@@ -1174,9 +1156,9 @@ BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u
if (!prs_align(ps))
return False;
- if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
+ if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
return False;
- if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
+ if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
return False;
if (!prs_align(ps))
@@ -2068,33 +2050,6 @@ static uint32 size_of_nttime(NTTIME *value)
}
/*******************************************************************
- * return the length of a UNICODE string in number of char, includes:
- * - the leading zero
- * - the relative pointer size
- ********************************************************************/
-
-static uint32 size_of_relative_string(UNISTR *string)
-{
- uint32 size=0;
-
- size=str_len_uni(string); /* the string length */
- size=size+1; /* add the trailing zero */
- size=size*2; /* convert in char */
- size=size+4; /* add the size of the ptr */
-
-#if 0 /* JERRY */
- /*
- * Do not include alignment as Win2k does not align relative
- * strings within a buffer --jerry
- */
- /* Ensure size is 4 byte multiple (prs_align is being called...). */
- /* size += ((4 - (size & 3)) & 3); */
-#endif
-
- return size;
-}
-
-/*******************************************************************
* return the length of a uint32 (obvious, but the code is clean)
********************************************************************/
@@ -2119,277 +2074,10 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime)
}
/*******************************************************************
- * write a UNICODE string and its relative pointer.
- * used by all the RPC structs passing a buffer
- *
- * As I'm a nice guy, I'm forcing myself to explain this code.
- * MS did a good job in the overall spoolss code except in some
- * functions where they are passing the API buffer directly in the
- * RPC request/reply. That's to maintain compatiility at the API level.
- * They could have done it the good way the first time.
- *
- * So what happen is: the strings are written at the buffer's end,
- * in the reverse order of the original structure. Some pointers to
- * the strings are also in the buffer. Those are relative to the
- * buffer's start.
- *
- * If you don't understand or want to change that function,
- * first get in touch with me: jfm@samba.org
- *
- ********************************************************************/
-
-static BOOL smb_io_relstr(const char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
-{
- prs_struct *ps=&buffer->prs;
-
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
-
- buffer->string_at_end -= (size_of_relative_string(string) - 4);
- if(!prs_set_offset(ps, buffer->string_at_end))
- return False;
-#if 0 /* JERRY */
- /*
- * Win2k does not align strings in a buffer
- * Tested against WinNT 4.0 SP 6a & 2k SP2 --jerry
- */
- if (!prs_align(ps))
- return False;
-#endif
- buffer->string_at_end = prs_offset(ps);
-
- /* write the string */
- if (!smb_io_unistr(desc, string, ps, depth))
- return False;
-
- if(!prs_set_offset(ps, struct_offset))
- return False;
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- }
- else {
- uint32 old_offset;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
- return False;
-
- if (buffer->string_at_end == 0)
- return True;
-
- old_offset = prs_offset(ps);
- if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
- return False;
-
- /* read the string */
- if (!smb_io_unistr(desc, string, ps, depth))
- return False;
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- }
- return True;
-}
-
-/*******************************************************************
- * write a array of UNICODE strings and its relative pointer.
- * used by 2 RPC structs
- ********************************************************************/
-
-static BOOL smb_io_relarraystr(const char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
-{
- UNISTR chaine;
-
- prs_struct *ps=&buffer->prs;
-
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
- uint16 *p;
- uint16 *q;
- uint16 zero=0;
- p=*string;
- q=*string;
-
- /* first write the last 0 */
- buffer->string_at_end -= 2;
- if(!prs_set_offset(ps, buffer->string_at_end))
- return False;
-
- if(!prs_uint16("leading zero", ps, depth, &zero))
- return False;
-
- while (p && (*p!=0)) {
- while (*q!=0)
- q++;
-
- /* Yes this should be malloc not talloc. Don't change. */
-
- chaine.buffer = SMB_MALLOC((q-p+1)*sizeof(uint16));
- if (chaine.buffer == NULL)
- return False;
-
- memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
-
- buffer->string_at_end -= (q-p+1)*sizeof(uint16);
-
- if(!prs_set_offset(ps, buffer->string_at_end)) {
- SAFE_FREE(chaine.buffer);
- return False;
- }
-
- /* write the string */
- if (!smb_io_unistr(desc, &chaine, ps, depth)) {
- SAFE_FREE(chaine.buffer);
- return False;
- }
- q++;
- p=q;
-
- SAFE_FREE(chaine.buffer);
- }
-
- if(!prs_set_offset(ps, struct_offset))
- return False;
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
-
- } else {
-
- /* UNMARSHALLING */
-
- uint32 old_offset;
- uint16 *chaine2=NULL;
- int l_chaine=0;
- int l_chaine2=0;
- size_t realloc_size = 0;
-
- *string=NULL;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
- return False;
-
- old_offset = prs_offset(ps);
- if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
- return False;
-
- do {
- if (!smb_io_unistr(desc, &chaine, ps, depth))
- return False;
-
- l_chaine=str_len_uni(&chaine);
-
- /* we're going to add two more bytes here in case this
- is the last string in the array and we need to add
- an extra NULL for termination */
- 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 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) {
- SAFE_FREE(chaine2);
- return False;
- }
- else chaine2 = tc2;
- memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
- l_chaine2+=l_chaine+1;
- }
-
- } while(l_chaine!=0);
-
- /* the end should be bould NULL terminated so add
- the second one here */
- if (chaine2)
- {
- chaine2[l_chaine2] = '\0';
- *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size);
- SAFE_FREE(chaine2);
- }
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- }
- return True;
-}
-
-/*******************************************************************
Parse a DEVMODE structure and its relative pointer.
********************************************************************/
-static BOOL smb_io_relsecdesc(const char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
-{
- prs_struct *ps= &buffer->prs;
-
- prs_debug(ps, depth, desc, "smb_io_relsecdesc");
- depth++;
-
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
-
- if (! *secdesc) {
- relative_offset = 0;
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- return True;
- }
-
- if (*secdesc != NULL) {
- buffer->string_at_end -= sec_desc_size(*secdesc);
-
- if(!prs_set_offset(ps, buffer->string_at_end))
- return False;
- /* write the secdesc */
- if (!sec_io_desc(desc, secdesc, ps, depth))
- return False;
-
- if(!prs_set_offset(ps, struct_offset))
- return False;
- }
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
-
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- } else {
- uint32 old_offset;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
- return False;
-
- old_offset = prs_offset(ps);
- if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
- return False;
-
- /* read the sd */
- if (!sec_io_desc(desc, secdesc, ps, depth))
- return False;
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- }
- return True;
-}
-
-/*******************************************************************
- Parse a DEVMODE structure and its relative pointer.
-********************************************************************/
-
-static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
+static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
{
prs_struct *ps=&buffer->prs;
@@ -2457,7 +2145,7 @@ static BOOL smb_io_reldevmode(const char *desc, NEW_BUFFER *buffer, int depth, D
Parse a PRINTER_INFO_0 structure.
********************************************************************/
-BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
+BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2558,7 +2246,7 @@ BOOL smb_io_printer_info_0(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0
Parse a PRINTER_INFO_1 structure.
********************************************************************/
-BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
+BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2583,7 +2271,7 @@ BOOL smb_io_printer_info_1(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1
Parse a PRINTER_INFO_2 structure.
********************************************************************/
-BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
+BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
uint32 dm_offset, sd_offset, current_offset;
@@ -2674,7 +2362,7 @@ BOOL smb_io_printer_info_2(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2
Parse a PRINTER_INFO_3 structure.
********************************************************************/
-BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
+BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2695,7 +2383,7 @@ BOOL smb_io_printer_info_3(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3
Parse a PRINTER_INFO_4 structure.
********************************************************************/
-BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
+BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2717,7 +2405,7 @@ BOOL smb_io_printer_info_4(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4
Parse a PRINTER_INFO_5 structure.
********************************************************************/
-BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
+BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2743,7 +2431,7 @@ BOOL smb_io_printer_info_5(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5
Parse a PRINTER_INFO_7 structure.
********************************************************************/
-BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
+BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2763,7 +2451,7 @@ BOOL smb_io_printer_info_7(const char *desc, NEW_BUFFER *buffer, PRINTER_INFO_7
Parse a PORT_INFO_1 structure.
********************************************************************/
-BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
+BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2782,7 +2470,7 @@ BOOL smb_io_port_info_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info,
Parse a PORT_INFO_2 structure.
********************************************************************/
-BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
+BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2809,7 +2497,7 @@ BOOL smb_io_port_info_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info,
Parse a DRIVER_INFO_1 structure.
********************************************************************/
-BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth)
+BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2828,7 +2516,7 @@ BOOL smb_io_printer_driver_info_1(const char *desc, NEW_BUFFER *buffer, DRIVER_I
Parse a DRIVER_INFO_2 structure.
********************************************************************/
-BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth)
+BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2857,7 +2545,7 @@ BOOL smb_io_printer_driver_info_2(const char *desc, NEW_BUFFER *buffer, DRIVER_I
Parse a DRIVER_INFO_3 structure.
********************************************************************/
-BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
+BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2896,7 +2584,7 @@ BOOL smb_io_printer_driver_info_3(const char *desc, NEW_BUFFER *buffer, DRIVER_I
Parse a DRIVER_INFO_6 structure.
********************************************************************/
-BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
+BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -2961,7 +2649,7 @@ BOOL smb_io_printer_driver_info_6(const char *desc, NEW_BUFFER *buffer, DRIVER_I
Parse a JOB_INFO_1 structure.
********************************************************************/
-BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
+BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3004,7 +2692,7 @@ BOOL smb_io_job_info_1(const char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, i
Parse a JOB_INFO_2 structure.
********************************************************************/
-BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
+BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
{
uint32 pipo=0;
prs_struct *ps=&buffer->prs;
@@ -3071,7 +2759,7 @@ BOOL smb_io_job_info_2(const char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, i
/*******************************************************************
********************************************************************/
-BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
+BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3102,123 +2790,13 @@ BOOL smb_io_form_1(const char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth
return True;
}
-/*******************************************************************
- Read/write a BUFFER struct.
-********************************************************************/
-static BOOL spoolss_io_buffer(const char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
-{
- NEW_BUFFER *buffer = *pp_buffer;
-
- prs_debug(ps, depth, desc, "spoolss_io_buffer");
- depth++;
-
- if (UNMARSHALLING(ps))
- buffer = *pp_buffer = PRS_ALLOC_MEM(ps, NEW_BUFFER, 1);
-
- if (buffer == NULL)
- return False;
-
- if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
- return False;
-
- /* reading */
- if (UNMARSHALLING(ps)) {
- buffer->size=0;
- buffer->string_at_end=0;
-
- if (buffer->ptr==0) {
- /*
- * JRA. I'm not sure if the data in here is in big-endian format if
- * the client is big-endian. Leave as default (little endian) for now.
- */
-
- if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
- return False;
- return True;
- }
-
- if (!prs_uint32("size", ps, depth, &buffer->size))
- return False;
-
- /*
- * JRA. I'm not sure if the data in here is in big-endian format if
- * the client is big-endian. Leave as default (little endian) for now.
- */
-
- if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
- return False;
-
- if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
- return False;
-
- if (!prs_set_offset(&buffer->prs, 0))
- return False;
-
- if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
- return False;
-
- buffer->string_at_end=buffer->size;
-
- return True;
- }
- else {
- BOOL ret = False;
-
- /* writing */
- if (buffer->ptr==0) {
- /* We have finished with the data in buffer->prs - free it. */
- prs_mem_free(&buffer->prs);
- return True;
- }
-
- if (!prs_uint32("size", ps, depth, &buffer->size))
- goto out;
-
- if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
- goto out;
-
- ret = True;
- out:
-
- /* We have finished with the data in buffer->prs - free it. */
- prs_mem_free(&buffer->prs);
-
- return ret;
- }
-}
-
-/*******************************************************************
- 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)
-{
- prs_switch_type(&src->prs, MARSHALL);
- if(!prs_set_offset(&src->prs, 0))
- return;
- prs_force_dynamic(&src->prs);
- prs_mem_clear(&src->prs);
- *dest=src;
-}
-
-/*******************************************************************
- Get the size of a BUFFER struct.
-********************************************************************/
-
-uint32 new_get_buffer_size(NEW_BUFFER *buffer)
-{
- return (buffer->size);
-}
/*******************************************************************
Parse a DRIVER_DIRECTORY_1 structure.
********************************************************************/
-BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
+BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3237,7 +2815,7 @@ BOOL smb_io_driverdir_1(const char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1
Parse a PORT_INFO_1 structure.
********************************************************************/
-BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
+BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3256,7 +2834,7 @@ BOOL smb_io_port_1(const char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int
Parse a PORT_INFO_2 structure.
********************************************************************/
-BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
+BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3282,7 +2860,7 @@ BOOL smb_io_port_2(const char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int
/*******************************************************************
********************************************************************/
-BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
+BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3300,7 +2878,7 @@ BOOL smb_io_printprocessor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPRO
/*******************************************************************
********************************************************************/
-BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
+BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3318,7 +2896,7 @@ BOOL smb_io_printprocdatatype_info_1(const char *desc, NEW_BUFFER *buffer, PRINT
/*******************************************************************
********************************************************************/
-BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
+BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3336,7 +2914,7 @@ BOOL smb_io_printmonitor_info_1(const char *desc, NEW_BUFFER *buffer, PRINTMONIT
/*******************************************************************
********************************************************************/
-BOOL smb_io_printmonitor_info_2(const char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
+BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -3859,7 +3437,7 @@ BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u,
const POLICY_HND *hnd,
const fstring architecture,
uint32 level, uint32 clientmajor, uint32 clientminor,
- NEW_BUFFER *buffer, uint32 offered)
+ RPC_BUFFER *buffer, uint32 offered)
{
if (q_u == NULL)
return False;
@@ -3903,7 +3481,7 @@ BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2
if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -3933,7 +3511,7 @@ BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -3959,7 +3537,7 @@ BOOL make_spoolss_q_enumprinters(
uint32 flags,
char *servername,
uint32 level,
- NEW_BUFFER *buffer,
+ RPC_BUFFER *buffer,
uint32 offered
)
{
@@ -3981,7 +3559,7 @@ BOOL make_spoolss_q_enumprinters(
BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u,
fstring servername, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ RPC_BUFFER *buffer, uint32 offered)
{
q_u->name_ptr = (servername != NULL) ? 1 : 0;
init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
@@ -4019,7 +3597,7 @@ BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -4042,7 +3620,7 @@ BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4074,7 +3652,7 @@ BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_stru
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4107,7 +3685,7 @@ BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -4127,7 +3705,7 @@ BOOL make_spoolss_q_getprinter(
SPOOL_Q_GETPRINTER *q_u,
const POLICY_HND *hnd,
uint32 level,
- NEW_BUFFER *buffer,
+ RPC_BUFFER *buffer,
uint32 offered
)
{
@@ -4349,7 +3927,7 @@ BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if(!prs_align(ps))
@@ -4380,7 +3958,7 @@ BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps,
if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -4403,7 +3981,7 @@ BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4428,7 +4006,7 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
uint32 firstjob,
uint32 numofjobs,
uint32 level,
- NEW_BUFFER *buffer,
+ RPC_BUFFER *buffer,
uint32 offered)
{
if (q_u == NULL)
@@ -4465,7 +4043,7 @@ BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -4569,7 +4147,7 @@ BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVER
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4595,7 +4173,7 @@ BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
const char *name,
const char *environment,
uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ RPC_BUFFER *buffer, uint32 offered)
{
init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
@@ -4637,7 +4215,7 @@ BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVER
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -4665,7 +4243,7 @@ BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -4687,7 +4265,7 @@ BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4727,7 +4305,7 @@ BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -4749,7 +4327,7 @@ BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4776,7 +4354,7 @@ BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -4815,7 +4393,7 @@ BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -5065,9 +4643,10 @@ BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_
if(!prs_align(ps))
return False;
- if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
+
+ if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
return False;
- if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
+ if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
return False;
if(!prs_align(ps))
@@ -5815,7 +5394,7 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
fstring servername, fstring env_name, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ RPC_BUFFER *buffer, uint32 offered)
{
init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
@@ -5857,7 +5436,7 @@ BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVER
if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -5881,7 +5460,7 @@ BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVER
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -5907,7 +5486,7 @@ BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESS
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -5955,7 +5534,7 @@ BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESS
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -6029,7 +5608,7 @@ BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROC
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -6077,7 +5656,7 @@ BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROC
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -6112,7 +5691,7 @@ BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS
if (!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if (!prs_align(ps))
@@ -6135,7 +5714,7 @@ BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -6578,7 +6157,7 @@ BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps,
if (!prs_align(ps))
return False;
- if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if (!prs_align(ps))
@@ -6612,7 +6191,7 @@ BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps,
if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -7463,7 +7042,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
[in] unistr2 *name,
[in] unistr2 *environment,
[in] uint32 level,
- [in,out] NEW_BUFFER buffer,
+ [in,out] RPC_BUFFER buffer,
[in] uint32 offered,
[out] uint32 needed,
[out] uint32 returned
@@ -7471,7 +7050,7 @@ BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX
*/
-BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
+BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
{
DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
@@ -7522,7 +7101,7 @@ BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTP
if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
- if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
return False;
if(!prs_align(ps))
@@ -7546,7 +7125,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP
if(!prs_align(ps))
return False;
- if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
+ if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
return False;
if(!prs_align(ps))
@@ -7561,7 +7140,7 @@ BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTP
return True;
}
-BOOL smb_io_printprocessordirectory_1(const char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
+BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
{
prs_struct *ps=&buffer->prs;
@@ -7625,7 +7204,7 @@ BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle,
BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
const char *formname, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+ RPC_BUFFER *buffer, uint32 offered)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
q_u->level = level;
@@ -7641,7 +7220,7 @@ BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle,
********************************************************************/
BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle,
- uint32 level, NEW_BUFFER *buffer,
+ uint32 level, RPC_BUFFER *buffer,
uint32 offered)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
@@ -7676,7 +7255,7 @@ BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle,
********************************************************************/
BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle,
- uint32 jobid, uint32 level, NEW_BUFFER *buffer,
+ uint32 jobid, uint32 level, RPC_BUFFER *buffer,
uint32 offered)
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 84c45b59014..7d15eda630f 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -1996,6 +1996,79 @@ BOOL srv_io_r_net_sess_enum(const char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_stru
}
/*******************************************************************
+ Inits a SRV_Q_NET_SESS_DEL structure.
+********************************************************************/
+
+void init_srv_q_net_sess_del(SRV_Q_NET_SESS_DEL *q_n, const char *srv_name,
+ const char *cli_name, const char *user_name)
+{
+ DEBUG(5,("init_q_net_sess_enum\n"));
+
+ init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+ init_buf_unistr2(&q_n->uni_cli_name, &q_n->ptr_cli_name, cli_name);
+ init_buf_unistr2(&q_n->uni_user_name, &q_n->ptr_user_name, user_name);
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+BOOL srv_io_q_net_sess_del(const char *desc, SRV_Q_NET_SESS_DEL *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_sess_del");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
+ return False;
+ if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_cli_name", ps, depth, &q_n->ptr_cli_name))
+ return False;
+ if(!smb_io_unistr2("", &q_n->uni_cli_name, q_n->ptr_cli_name, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ptr_user_name", ps, depth, &q_n->ptr_user_name))
+ return False;
+ if(!smb_io_unistr2("", &q_n->uni_user_name, q_n->ptr_user_name, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+BOOL srv_io_r_net_sess_del(const char *desc, SRV_R_NET_SESS_DEL *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_sess_del");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_n->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
Inits a CONN_INFO_0 structure
********************************************************************/
diff --git a/source/rpc_parse/parse_svcctl.c b/source/rpc_parse/parse_svcctl.c
new file mode 100644
index 00000000000..1c41a18b99e
--- /dev/null
+++ b/source/rpc_parse/parse_svcctl.c
@@ -0,0 +1,660 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Gerald (Jerry) Carter 2005.
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_PARSE
+
+/*******************************************************************
+********************************************************************/
+
+static BOOL svcctl_io_service_status( const char *desc, SERVICE_STATUS *status, prs_struct *ps, int depth )
+{
+
+ prs_debug(ps, depth, desc, "svcctl_io_service_status");
+ depth++;
+
+ if(!prs_uint32("type", ps, depth, &status->type))
+ return False;
+
+ if(!prs_uint32("state", ps, depth, &status->state))
+ return False;
+
+ if(!prs_uint32("controls_accepted", ps, depth, &status->controls_accepted))
+ return False;
+
+ if(!prs_uint32("win32_exit_code", ps, depth, &status->win32_exit_code))
+ return False;
+
+ if(!prs_uint32("service_exit_code", ps, depth, &status->service_exit_code))
+ return False;
+
+ if(!prs_uint32("check_point", ps, depth, &status->check_point))
+ return False;
+
+ if(!prs_uint32("wait_hint", ps, depth, &status->wait_hint))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config, prs_struct *ps, int depth )
+{
+
+ prs_debug(ps, depth, desc, "svcctl_io_service_config");
+ depth++;
+
+ if(!prs_uint32("service_type", ps, depth, &config->service_type))
+ return False;
+ if(!prs_uint32("start_type", ps, depth, &config->start_type))
+ return False;
+ if(!prs_uint32("error_control", ps, depth, &config->error_control))
+ return False;
+
+ if (!prs_io_unistr2_p("", ps, depth, &config->executablepath))
+ return False;
+ if (!prs_io_unistr2_p("", ps, depth, &config->loadordergroup))
+ return False;
+
+ if(!prs_uint32("tag_id", ps, depth, &config->tag_id))
+ return False;
+
+ if (!prs_io_unistr2_p("", ps, depth, &config->dependencies))
+ return False;
+ if (!prs_io_unistr2_p("", ps, depth, &config->startname))
+ return False;
+ if (!prs_io_unistr2_p("", ps, depth, &config->displayname))
+ return False;
+
+ if (!prs_io_unistr2("", ps, depth, config->executablepath))
+ return False;
+ if (!prs_io_unistr2("", ps, depth, config->loadordergroup))
+ return False;
+ if (!prs_io_unistr2("", ps, depth, config->dependencies))
+ return False;
+ if (!prs_io_unistr2("", ps, depth, config->startname))
+ return False;
+ if (!prs_io_unistr2("", ps, depth, config->displayname))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth )
+{
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "svcctl_io_enum_services_status");
+ depth++;
+
+ if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) )
+ return False;
+ if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) )
+ return False;
+
+ if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status )
+{
+ uint32 size = 0;
+
+ size += size_of_relative_string( &status->servicename );
+ size += size_of_relative_string( &status->displayname );
+ size += sizeof(SERVICE_STATUS);
+
+ return size;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_close_service(const char *desc, SVCCTL_Q_CLOSE_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_close_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_close_service(const char *desc, SVCCTL_R_CLOSE_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_close_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_open_scmanager(const char *desc, SVCCTL_Q_OPEN_SCMANAGER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_open_scmanager");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_pointer("servername", ps, depth, (void**)&q_u->servername, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_pointer("database", ps, depth, (void**)&q_u->database, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2))
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &q_u->access))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_open_scmanager(const char *desc, SVCCTL_R_OPEN_SCMANAGER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_open_scmanager");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_pol", &r_u->handle, ps, depth))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_get_display_name(const char *desc, SVCCTL_Q_GET_DISPLAY_NAME *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_get_display_name");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("display_name_len", ps, depth, &q_u->display_name_len))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL init_svcctl_r_get_display_name( SVCCTL_R_GET_DISPLAY_NAME *r_u, const char *displayname )
+{
+ r_u->display_name_len = strlen(displayname);
+ init_unistr2( &r_u->displayname, displayname, UNI_STR_TERMINATE );
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_get_display_name(const char *desc, SVCCTL_R_GET_DISPLAY_NAME *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_get_display_name");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+
+ if(!smb_io_unistr2("displayname", &r_u->displayname, 1, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("display_name_len", ps, depth, &r_u->display_name_len))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_open_service(const char *desc, SVCCTL_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_open_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &q_u->access))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_open_service(const char *desc, SVCCTL_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_open_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &r_u->handle, ps, depth))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_query_status(const char *desc, SVCCTL_Q_QUERY_STATUS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_query_status");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_query_status(const char *desc, SVCCTL_R_QUERY_STATUS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_query_status");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_enum_services_status(const char *desc, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_enum_services_status");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("type", ps, depth, &q_u->type))
+ return False;
+ if(!prs_uint32("state", ps, depth, &q_u->state))
+ return False;
+ if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+ return False;
+
+ if(!prs_pointer("resume", ps, depth, (void**)&q_u->resume, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_enum_services_status(const char *desc, SVCCTL_R_ENUM_SERVICES_STATUS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_enum_services_status");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!prs_rpcbuffer("", 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_uint32("returned", ps, depth, &r_u->returned))
+ return False;
+
+ if(!prs_pointer("resume", ps, depth, (void**)&r_u->resume, sizeof(uint32), (PRS_POINTER_CAST)prs_uint32))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_start_service(const char *desc, SVCCTL_Q_START_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_start_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("parmcount", ps, depth, &q_u->parmcount))
+ return False;
+
+ if ( !prs_pointer("rights", ps, depth, (void**)&q_u->parameters, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_start_service(const char *desc, SVCCTL_R_START_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_start_service");
+ depth++;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_enum_dependent_services(const char *desc, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_enum_dependent_services");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("state", ps, depth, &q_u->state))
+ return False;
+ if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_enum_dependent_services(const char *desc, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_enum_dependent_services");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if (!prs_rpcbuffer("", 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_uint32("returned", ps, depth, &r_u->returned))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_control_service(const char *desc, SVCCTL_Q_CONTROL_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_control_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("control", ps, depth, &q_u->control))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_control_service(const char *desc, SVCCTL_R_CONTROL_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_control_service");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_q_query_service_config(const char *desc, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_query_service_config");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
+ return False;
+
+ if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_query_service_config(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!svcctl_io_service_config("config", &r_u->config, ps, depth))
+ 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;
+}
+
+
diff --git a/source/rpc_server/srv_eventlog.c b/source/rpc_server/srv_eventlog.c
new file mode 100644
index 00000000000..07aebcd2faa
--- /dev/null
+++ b/source/rpc_server/srv_eventlog.c
@@ -0,0 +1,206 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+static BOOL api_eventlog_open_eventlog(pipes_struct *p)
+{
+ EVENTLOG_Q_OPEN_EVENTLOG q_u;
+ EVENTLOG_R_OPEN_EVENTLOG 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 (!(eventlog_io_q_open_eventlog("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_open_eventlog: unable to unmarshall EVENTLOG_Q_OPEN_EVENTLOG.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_open_eventlog(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_open_eventlog("", &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_r_open_eventlog: unable to marshall EVENTLOG_R_OPEN_EVENTLOG.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL api_eventlog_close_eventlog(pipes_struct *p)
+{
+ EVENTLOG_Q_CLOSE_EVENTLOG q_u;
+ EVENTLOG_R_CLOSE_EVENTLOG 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 (!(eventlog_io_q_close_eventlog("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_close_eventlog: unable to unmarshall EVENTLOG_Q_CLOSE_EVENTLOG.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_close_eventlog(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_close_eventlog("", &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_r_close_eventlog: unable to marshall EVENTLOG_R_CLOSE_EVENTLOG.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL api_eventlog_get_num_records(pipes_struct *p)
+{
+ EVENTLOG_Q_GET_NUM_RECORDS q_u;
+ EVENTLOG_R_GET_NUM_RECORDS 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 (!(eventlog_io_q_get_num_records("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_get_num_records: unable to unmarshall EVENTLOG_Q_GET_NUM_RECORDS.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_get_num_records(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_get_num_records("", &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_r_get_num_records: unable to marshall EVENTLOG_R_GET_NUM_RECORDS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL api_eventlog_get_oldest_entry(pipes_struct *p)
+{
+ EVENTLOG_Q_GET_OLDEST_ENTRY q_u;
+ EVENTLOG_R_GET_OLDEST_ENTRY 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 (!(eventlog_io_q_get_oldest_entry("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_get_oldest_entry: unable to unmarshall EVENTLOG_Q_GET_OLDEST_ENTRY.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_get_oldest_entry(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_get_oldest_entry("", &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_r_get_oldest_entry: unable to marshall EVENTLOG_R_GET_OLDEST_ENTRY.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL api_eventlog_read_eventlog(pipes_struct *p)
+{
+ EVENTLOG_Q_READ_EVENTLOG q_u;
+ EVENTLOG_R_READ_EVENTLOG 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 (!(eventlog_io_q_read_eventlog("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_read_eventlog: unable to unmarshall EVENTLOG_Q_READ_EVENTLOG.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_read_eventlog(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_read_eventlog("", &q_u, &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_r_read_eventlog: unable to marshall EVENTLOG_R_READ_EVENTLOG.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL api_eventlog_clear_eventlog(pipes_struct *p)
+{
+ EVENTLOG_Q_CLEAR_EVENTLOG q_u;
+ EVENTLOG_R_CLEAR_EVENTLOG 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 (!(eventlog_io_q_clear_eventlog("", &q_u, data, 0))) {
+ DEBUG(0, ("eventlog_io_q_clear_eventlog: unable to unmarshall EVENTLOG_Q_CLEAR_EVENTLOG.\n"));
+ return False;
+ }
+
+ r_u.status = _eventlog_clear_eventlog(p, &q_u, &r_u);
+
+ if (!(eventlog_io_r_clear_eventlog("", &r_u, rdata, 0))) {
+ DEBUG(0, ("eventlog_io_q_clear_eventlog: unable to marshall EVENTLOG_Q_CLEAR_EVENTLOG.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/*
+ \pipe\eventlog commands
+*/
+struct api_struct api_eventlog_cmds[] =
+{
+ {"EVENTLOG_OPENEVENTLOG", EVENTLOG_OPENEVENTLOG, api_eventlog_open_eventlog },
+ {"EVENTLOG_CLOSEVENTLOG", EVENTLOG_CLOSEEVENTLOG, api_eventlog_close_eventlog },
+ {"EVENTLOG_GETNUMRECORDS", EVENTLOG_GETNUMRECORDS, api_eventlog_get_num_records },
+ {"EVENTLOG_GETOLDESTENTRY", EVENTLOG_GETOLDESTENTRY, api_eventlog_get_oldest_entry },
+ {"EVENTLOG_READEVENTLOG", EVENTLOG_READEVENTLOG, api_eventlog_read_eventlog },
+ {"EVENTLOG_CLEAREVENTLOG", EVENTLOG_CLEAREVENTLOG, api_eventlog_clear_eventlog }
+};
+
+NTSTATUS rpc_eventlog_init(void)
+{
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
+ "eventlog", "eventlog", api_eventlog_cmds,
+ sizeof(api_eventlog_cmds)/sizeof(struct api_struct));
+}
+
+void eventlog_get_pipe_fns(struct api_struct **fns, int *n_fns)
+{
+ *fns = api_eventlog_cmds;
+ *n_fns = sizeof(api_eventlog_cmds) / sizeof(struct api_struct);
+}
diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c
new file mode 100644
index 00000000000..7501434a134
--- /dev/null
+++ b/source/rpc_server/srv_eventlog_nt.c
@@ -0,0 +1,923 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+typedef struct eventlog_info
+{
+ /* for use by the \PIPE\eventlog policy */
+ fstring source_log_file_name;
+ fstring source_server_name;
+ fstring handle_string;
+ uint32 num_records;
+ uint32 oldest_entry;
+} Eventlog_info;
+
+static void free_eventlog_info(void *ptr)
+{
+ struct eventlog_info *info = (struct eventlog_info *)ptr;
+ memset(info->source_log_file_name, '0', sizeof(*(info->source_log_file_name)));
+ memset(info->source_server_name, '0', sizeof(*(info->source_server_name)));
+ memset(info->handle_string, '0', sizeof(*(info->handle_string)));
+ memset(info, 0, sizeof(*(info)));
+ SAFE_FREE(info);
+}
+
+static Eventlog_info *find_eventlog_info_by_hnd(pipes_struct *p,
+ POLICY_HND *handle)
+{
+ Eventlog_info *info = NULL;
+
+ if(!(find_policy_by_hnd(p,handle,(void **)&info)))
+ {
+ DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
+ }
+
+ return info;
+}
+
+void policy_handle_to_string(POLICY_HND *handle, fstring *dest)
+{
+ memset(dest, 0, sizeof(*dest));
+ snprintf((char *)dest, sizeof(*dest), "%08X-%08X-%04X-%04X-%02X%02X%02X%02X%02X",
+ handle->data1,
+ handle->data2,
+ handle->data3,
+ handle->data4,
+ handle->data5[0],
+ handle->data5[1],
+ handle->data5[2],
+ handle->data5[3],
+ handle->data5[4]);
+}
+
+/**
+ * Callout to open the specified event log
+ *
+ * smbrun calling convention --
+ * INPUT: <open_cmd> <log name> <policy handle>
+ * OUTPUT: the string "SUCCESS" if the command succeeded
+ * no such string if there was a failure.
+ */
+static BOOL _eventlog_open_eventlog_hook(Eventlog_info *info)
+{
+ char *cmd = lp_eventlog_open_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
+ return False;
+ }
+
+ memset(command, 0, sizeof(command));
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+ {
+ DEBUGADD(10, ("Able to open [%s].\n", info->source_log_file_name));
+ file_lines_free(qlines);
+ return True;
+ }
+ }
+
+ file_lines_free(qlines);
+ return False;
+}
+
+WERROR _eventlog_open_eventlog(pipes_struct *p,
+ EVENTLOG_Q_OPEN_EVENTLOG *q_u,
+ EVENTLOG_R_OPEN_EVENTLOG *r_u)
+{
+ Eventlog_info *info = NULL;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ if((info = SMB_MALLOC_P(Eventlog_info)) == NULL)
+ return WERR_NOMEM;
+
+ ZERO_STRUCTP(info);
+
+ if(q_u->servername_ptr != 0)
+ {
+ unistr2_to_ascii(info->source_server_name, &(q_u->servername), sizeof(info->source_server_name));
+ }
+ else
+ {
+ /* if servername == NULL, use the local computer */
+ fstrcpy(info->source_server_name, global_myname());
+ }
+ DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info->source_server_name));
+
+ if(q_u->sourcename_ptr != 0)
+ {
+ unistr2_to_ascii(info->source_log_file_name, &(q_u->sourcename), sizeof(info->source_log_file_name));
+ }
+ else
+ {
+ /* if sourcename == NULL, default to "Application" log */
+ fstrcpy(info->source_log_file_name, "Application");
+ }
+ DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->source_log_file_name));
+
+ if(!create_policy_hnd(p, &(r_u->handle), free_eventlog_info, (void *)info))
+ return WERR_NOMEM;
+
+ policy_handle_to_string(&r_u->handle, &info->handle_string);
+
+ if(!(_eventlog_open_eventlog_hook(info)))
+ return WERR_BADFILE;
+
+ return WERR_OK;
+}
+/**
+ * Callout to get the number of records in the specified event log
+ *
+ * smbrun calling convention --
+ * INPUT: <get_num_records_cmd> <log name> <policy handle>
+ * OUTPUT: A single line with a single integer containing the number of
+ * entries in the log. If there are no entries in the log, return 0.
+ */
+static BOOL _eventlog_get_num_records_hook(Eventlog_info *info)
+{
+ char *cmd = lp_eventlog_num_records_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
+ return False;
+ }
+
+ memset(command, 0, sizeof(command));
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ sscanf(qlines[0], "%d", &(info->num_records));
+ file_lines_free(qlines);
+ return True;
+ }
+
+ file_lines_free(qlines);
+ return False;
+}
+
+WERROR _eventlog_get_num_records(pipes_struct *p,
+ EVENTLOG_Q_GET_NUM_RECORDS *q_u,
+ EVENTLOG_R_GET_NUM_RECORDS *r_u)
+{
+ Eventlog_info *info = NULL;
+ POLICY_HND *handle = NULL;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ handle = &(q_u->handle);
+ info = find_eventlog_info_by_hnd(p, handle);
+
+ if(!(_eventlog_get_num_records_hook(info)))
+ return WERR_BADFILE;
+
+ r_u->num_records = info->num_records;
+
+ return WERR_OK;
+}
+/**
+ * Callout to find the oldest record in the log
+ *
+ * smbrun calling convention --
+ * INPUT: <oldest_entry_cmd> <log name> <policy handle>
+ * OUTPUT: If there are entries in the event log, the index of the
+ * oldest entry. Must be 1 or greater.
+ * If there are no entries in the log, returns a 0
+ */
+static BOOL _eventlog_get_oldest_entry_hook(Eventlog_info *info)
+{
+ char *cmd = lp_eventlog_oldest_record_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
+ return False;
+ }
+
+ memset(command, 0, sizeof(command));
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ sscanf(qlines[0], "%d", &(info->oldest_entry));
+ file_lines_free(qlines);
+ return True;
+ }
+
+ file_lines_free(qlines);
+ return False;
+}
+
+WERROR _eventlog_get_oldest_entry(pipes_struct *p,
+ EVENTLOG_Q_GET_OLDEST_ENTRY *q_u,
+ EVENTLOG_R_GET_OLDEST_ENTRY *r_u)
+{
+ Eventlog_info *info = NULL;
+ POLICY_HND *handle = NULL;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ handle = &(q_u->handle);
+ info = find_eventlog_info_by_hnd(p, handle);
+
+ if(!(_eventlog_get_oldest_entry_hook(info)))
+ return WERR_BADFILE;
+
+ r_u->oldest_entry = info->oldest_entry;
+
+ return WERR_OK;
+}
+
+/**
+ * Callout to close the specified event log
+ *
+ * smbrun calling convention --
+ * INPUT: <close_cmd> <log name> <policy handle>
+ * OUTPUT: the string "SUCCESS" if the command succeeded
+ * no such string if there was a failure.
+ */
+static BOOL _eventlog_close_eventlog_hook(Eventlog_info *info)
+{
+ char *cmd = lp_eventlog_close_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
+ return False;
+ }
+
+ memset(command, 0, sizeof(command));
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+ {
+ DEBUGADD(10, ("Able to close [%s].\n", info->source_log_file_name));
+ file_lines_free(qlines);
+ return True;
+ }
+ }
+
+ file_lines_free(qlines);
+ return False;
+}
+
+WERROR _eventlog_close_eventlog(pipes_struct *p,
+ EVENTLOG_Q_CLOSE_EVENTLOG *q_u,
+ EVENTLOG_R_CLOSE_EVENTLOG *r_u)
+{
+ Eventlog_info *info = NULL;
+ POLICY_HND *handle;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ handle = &(q_u->handle);
+
+ info = find_eventlog_info_by_hnd(p, handle);
+ if(!(_eventlog_close_eventlog_hook(info)))
+ return WERR_BADFILE;
+
+ if(!(close_policy_hnd(p, handle)))
+ {
+ /* WERR_NOMEM is probably not the correct error, but until I figure out a better
+ one it will have to do */
+ return WERR_NOMEM;
+ }
+
+ return WERR_OK;
+}
+
+static BOOL _eventlog_read_parse_line(char *line, Eventlog_entry *entry)
+{
+ char *start = NULL, *stop = NULL;
+ pstring temp;
+ int temp_len = 0, i;
+
+ start = line;
+
+ if(start == NULL || strlen(start) == 0)
+ return False;
+ if(!(stop = strchr(line, ':')))
+ return False;
+
+ DEBUG(6, ("_eventlog_read_parse_line: trying to parse [%s].\n", line));
+
+ if(0 == strncmp(start, "LEN", stop - start))
+ {
+ /* This will get recomputed later anyway -- probably not necessary */
+ entry->record.length = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "RS1", stop - start))
+ {
+ /* For now all these reserved entries seem to have the same value,
+ which can be hardcoded to int(1699505740) for now */
+ entry->record.reserved1 = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "RCN", stop - start))
+ {
+ entry->record.record_number = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "TMG", stop - start))
+ {
+ entry->record.time_generated = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "TMW", stop - start))
+ {
+ entry->record.time_written = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "EID", stop - start))
+ {
+ entry->record.event_id = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "ETP", stop - start))
+ {
+ if(strstr(start, "ERROR"))
+ {
+ entry->record.event_type = EVENTLOG_ERROR_TYPE;
+ }
+ else if(strstr(start, "WARNING"))
+ {
+ entry->record.event_type = EVENTLOG_WARNING_TYPE;
+ }
+ else if(strstr(start, "INFO"))
+ {
+ entry->record.event_type = EVENTLOG_INFORMATION_TYPE;
+ }
+ else if(strstr(start, "AUDIT_SUCCESS"))
+ {
+ entry->record.event_type = EVENTLOG_AUDIT_SUCCESS;
+ }
+ else if(strstr(start, "AUDIT_FAILURE"))
+ {
+ entry->record.event_type = EVENTLOG_AUDIT_FAILURE;
+ }
+ else if(strstr(start, "SUCCESS"))
+ {
+ entry->record.event_type = EVENTLOG_SUCCESS;
+ }
+ else
+ {
+ /* some other eventlog type -- currently not defined in MSDN docs, so error out */
+ return False;
+ }
+ }
+/*
+ else if(0 == strncmp(start, "NST", stop - start))
+ {
+ entry->record.num_strings = atoi(stop + 1);
+ }
+*/
+ else if(0 == strncmp(start, "ECT", stop - start))
+ {
+ entry->record.event_category = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "RS2", stop - start))
+ {
+ entry->record.reserved2 = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "CRN", stop - start))
+ {
+ entry->record.closing_record_number = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "USL", stop - start))
+ {
+ entry->record.user_sid_length = atoi(stop + 1);
+ }
+ else if(0 == strncmp(start, "SRC", stop - start))
+ {
+ memset(temp, 0, sizeof(temp));
+ sscanf(stop+1, "%s", temp);
+ temp_len = strlen(temp);
+ rpcstr_push((void *)(entry->data_record.source_name), temp,
+ sizeof(entry->data_record.source_name), STR_TERMINATE);
+ entry->data_record.source_name_len = (strlen_w(entry->data_record.source_name)* 2) + 2;
+ }
+ else if(0 == strncmp(start, "SRN", stop - start))
+ {
+ memset(temp, 0, sizeof(temp));
+ sscanf(stop+1, "%s", temp);
+ temp_len = strlen(temp);
+ rpcstr_push((void *)(entry->data_record.computer_name), temp,
+ sizeof(entry->data_record.computer_name), STR_TERMINATE);
+ entry->data_record.computer_name_len = (strlen_w(entry->data_record.computer_name)* 2) + 2;
+ }
+ else if(0 == strncmp(start, "SID", stop - start))
+ {
+ memset(temp, 0, sizeof(temp));
+ sscanf(stop+1, "%s", temp);
+ temp_len = strlen(temp);
+ rpcstr_push((void *)(entry->data_record.sid), temp,
+ sizeof(entry->data_record.sid), STR_TERMINATE);
+ entry->record.user_sid_length = (strlen_w(entry->data_record.sid) * 2) + 2;
+ }
+ else if(0 == strncmp(start, "STR", stop - start))
+ {
+ /* skip past initial ":" */
+ stop++;
+ /* now skip any other leading whitespace */
+ while(isspace(stop[0]))
+ stop++;
+ temp_len = strlen(stop);
+ memset(temp, 0, sizeof(temp));
+ strncpy(temp, stop, temp_len);
+ rpcstr_push((void *)(entry->data_record.strings + entry->data_record.strings_len),
+ temp,
+ sizeof(entry->data_record.strings) - entry->data_record.strings_len,
+ STR_TERMINATE);
+ entry->data_record.strings_len += temp_len + 1;
+ fprintf(stderr, "Dumping strings:\n");
+ for(i = 0; i < entry->data_record.strings_len; i++)
+ {
+ fputc((char)entry->data_record.strings[i], stderr);
+ }
+ fprintf(stderr, "\nDone\n");
+ entry->record.num_strings++;
+ }
+ else if(0 == strncmp(start, "DAT", stop - start))
+ {
+ /* Now that we're done processing the STR data, adjust the length to account for
+ unicode, then proceed with the DAT data. */
+ entry->data_record.strings_len *= 2;
+ /* skip past initial ":" */
+ stop++;
+ /* now skip any other leading whitespace */
+ while(isspace(stop[0]))
+ stop++;
+ memset(temp, 0, sizeof(temp));
+ temp_len = strlen(stop);
+ strncpy(temp, stop, temp_len);
+ rpcstr_push((void *)(entry->data_record.user_data), temp,
+ sizeof(entry->data_record.user_data), STR_TERMINATE);
+ entry->data_record.user_data_len = (strlen_w((const smb_ucs2_t *)entry->data_record.user_data) * 2) + 2;
+ }
+ else
+ {
+ /* some other eventlog entry -- not implemented, so dropping on the floor */
+ DEBUG(10, ("Unknown entry [%s]. Ignoring.\n", line));
+ /* For now return true so that we can keep on parsing this mess. Eventually
+ we will return False here. */
+ return True;
+ }
+ return True;
+}
+/**
+ * Callout to read entries from the specified event log
+ *
+ * smbrun calling convention --
+ * INPUT: <read_cmd> <log name> <direction> <starting record> <buffer size> <policy handle>
+ * where direction is either "forward" or "backward", the starting record is somewhere
+ * between the oldest_record and oldest_record+num_records, and the buffer size is the
+ * maximum size of the buffer that the client can accomodate.
+ * OUTPUT: A buffer containing a set of entries, one to a line, of the format:
+ * line type:line data
+ * These are the allowed line types:
+ * RS1:(uint32) - reserved. All M$ entries seem to have int(1699505740) for now
+ * RCN:(uint32) - record number of the record, however it may be calculated by the script
+ * TMG:(uint32) - time generated, seconds since January 1, 1970, 0000 UTC
+ * TMW:(uint32) - time written, seconds since January 1, 1970, 0000 UTC
+ * EID:(uint32) - eventlog source defined event identifier. If there's a stringfile for the event, it is an index into that
+ * ETP:(uint16) - eventlog type - one of ERROR, WARNING, INFO, AUDIT_SUCCESS, AUDIT_FAILURE
+ * ECT:(uint16) - event category - depends on the eventlog generator...
+ * RS2:(uint16) - reserved, make it 0000
+ * CRN:(uint32) - reserved, make it 00000000 for now
+ * USL:(uint32) - user SID length. No sid? Make this 0. Must match SID below
+ * SRC:[(uint8)] - Name of the source, for example ccPwdSvc, in hex bytes. Can not be multiline.
+ * SRN:[(uint8)] - Name of the computer on which this is generated, the short hostname usually.
+ * SID:[(uint8)] - User sid if one exists. Must be present even if there is no SID.
+ * STR:[(uint8)] - String data. One string per line. Multiple strings can be specified using consecutive "STR" lines,
+ * up to a total aggregate string length of 1024 characters.
+ * DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
+ */
+static BOOL _eventlog_read_eventlog_hook(Eventlog_info *info, Eventlog_entry *entry, const char *direction, int starting_record, int buffer_size, BOOL *eof)
+{
+ char *cmd = lp_eventlog_read_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+ int i;
+
+ if(info == NULL)
+ return False;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
+ return False;
+ }
+
+ slprintf(command, sizeof(command)-1, "%s \"%s\" %s %d %d \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ direction,
+ starting_record,
+ buffer_size,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ for(i = 0; i < numlines; i++)
+ {
+ DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
+ _eventlog_read_parse_line(qlines[i], entry);
+ }
+ file_lines_free(qlines);
+ return True;
+ }
+ else
+ *eof = True;
+
+ file_lines_free(qlines);
+ return False;
+}
+
+static BOOL _eventlog_read_prepare_data_buffer(prs_struct *ps,
+ EVENTLOG_Q_READ_EVENTLOG *q_u,
+ EVENTLOG_R_READ_EVENTLOG *r_u,
+ Eventlog_entry *entry)
+{
+ uint8 *offset;
+ Eventlog_entry *new = NULL, *insert_point = NULL;
+
+ new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
+ if(new == NULL)
+ return False;
+
+ entry->data_record.sid_padding = ((4 - ((entry->data_record.source_name_len
+ + entry->data_record.computer_name_len) % 4)) %4);
+ entry->data_record.data_padding = (4 - ((entry->data_record.strings_len
+ + entry->data_record.user_data_len) % 4)) % 4;
+ entry->record.length = sizeof(Eventlog_record);
+ entry->record.length += entry->data_record.source_name_len;
+ entry->record.length += entry->data_record.computer_name_len;
+ if(entry->record.user_sid_length == 0)
+ {
+ /* Should not pad to a DWORD boundary for writing out the sid if there is
+ no SID, so just propagate the padding to pad the data */
+ entry->data_record.data_padding += entry->data_record.sid_padding;
+ entry->data_record.sid_padding = 0;
+ }
+ DEBUG(10, ("sid_padding is [%d].\n", entry->data_record.sid_padding));
+ DEBUG(10, ("data_padding is [%d].\n", entry->data_record.data_padding));
+
+ entry->record.length += entry->data_record.sid_padding;
+ entry->record.length += entry->record.user_sid_length;
+ entry->record.length += entry->data_record.strings_len;
+ entry->record.length += entry->data_record.user_data_len;
+ entry->record.length += entry->data_record.data_padding;
+ /* need another copy of length at the end of the data */
+ entry->record.length += sizeof(entry->record.length);
+ DEBUG(10, ("entry->record.length is [%d].\n", entry->record.length));
+ entry->data = PRS_ALLOC_MEM(ps, uint8, entry->record.length - sizeof(Eventlog_record) - sizeof(entry->record.length));
+ if(entry->data == NULL)
+ return False;
+ offset = entry->data;
+ memcpy(offset, &(entry->data_record.source_name), entry->data_record.source_name_len);
+ offset += entry->data_record.source_name_len;
+ memcpy(offset, &(entry->data_record.computer_name), entry->data_record.computer_name_len);
+ offset += entry->data_record.computer_name_len;
+ /* SID needs to be DWORD-aligned */
+ offset += entry->data_record.sid_padding;
+ entry->record.user_sid_offset = sizeof(Eventlog_record) + (offset - entry->data);
+ memcpy(offset, &(entry->data_record.sid), entry->record.user_sid_length);
+ offset += entry->record.user_sid_length;
+ /* Now do the strings */
+ entry->record.string_offset = sizeof(Eventlog_record) + (offset - entry->data);
+ memcpy(offset, &(entry->data_record.strings), entry->data_record.strings_len);
+ offset += entry->data_record.strings_len;
+ /* Now do the data */
+ entry->record.data_length = entry->data_record.user_data_len;
+ entry->record.data_offset = sizeof(Eventlog_record) + (offset - entry->data);
+ memcpy(offset, &(entry->data_record.user_data), entry->data_record.user_data_len);
+ offset += entry->data_record.user_data_len;
+ /* Now that we've massaged the current entry, copy it into the new entry and add it
+ to end of the list */
+ insert_point=r_u->entry;
+
+ if (NULL == insert_point)
+ {
+ r_u->entry = new;
+ new->next = NULL;
+ }
+ else
+ {
+ while ((NULL != insert_point->next))
+ {
+ insert_point=insert_point->next;
+ }
+ new->next = NULL;
+ insert_point->next = new;
+ }
+
+ memcpy(&(new->record), &entry->record, sizeof(Eventlog_record));
+ memcpy(&(new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
+ new->data = entry->data;
+
+ r_u->num_records++;
+ r_u->num_bytes_in_resp += entry->record.length;
+
+ return True;
+}
+
+WERROR _eventlog_read_eventlog(pipes_struct *p,
+ EVENTLOG_Q_READ_EVENTLOG *q_u,
+ EVENTLOG_R_READ_EVENTLOG *r_u)
+{
+ Eventlog_info *info = NULL;
+ POLICY_HND *handle;
+ Eventlog_entry entry;
+ BOOL eof = False;
+ const char *direction = "";
+ int starting_record;
+ prs_struct *ps;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ handle = &(q_u->handle);
+ info = find_eventlog_info_by_hnd(p, handle);
+ ps = &p->out_data.rdata;
+ /* Rather than checking the EVENTLOG_SEQUENTIAL_READ/EVENTLOG_SEEK_READ flags,
+ we'll just go to the offset specified in the request, or the oldest entry
+ if no offset is specified */
+ if(q_u->offset > 0)
+ starting_record = q_u->offset;
+ else
+ starting_record = info->oldest_entry;
+ if(q_u->flags & EVENTLOG_FORWARDS_READ)
+ direction = "forward";
+ else if(q_u->flags & EVENTLOG_BACKWARDS_READ)
+ direction = "backward";
+
+ do
+ {
+ ZERO_STRUCT(entry);
+ if(!(_eventlog_read_eventlog_hook(info, &entry, direction, starting_record, q_u->max_read_size, &eof)))
+ {
+ if(eof == False)
+ return WERR_NOMEM;
+ }
+ if(eof == False)
+ {
+ /* only if the read hook returned data */
+ if(!(_eventlog_read_prepare_data_buffer(ps, q_u, r_u, &entry)))
+ return WERR_NOMEM;
+ DEBUG(10, ("_eventlog_read_eventlog: read [%d] bytes out of a max of [%d].\n",
+ r_u->num_bytes_in_resp,
+ q_u->max_read_size));
+ }
+ } while((r_u->num_bytes_in_resp <= q_u->max_read_size) && (eof != True));
+
+ return WERR_OK;
+}
+/**
+ * Callout to clear (and optionally backup) a specified event log
+ *
+ * smbrun calling convention --
+ * INPUT: <clear_eventlog_cmd> <log name> <policy handle>
+ * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
+ * Otherwise it is assumed to have failed
+ *
+ * INPUT: <clear_eventlog_cmd> <log name> <backup file> <policy handle>
+ * OUTPUT: A single line with the string "SUCCESS" if the command succeeded.
+ * Otherwise it is assumed to have failed
+ * The given log is copied to that location on the server. See comments for
+ * eventlog_io_q_clear_eventlog for info about odd file name behavior
+ */
+static BOOL _eventlog_clear_eventlog_hook(Eventlog_info *info,
+ pstring backup_file_name)
+{
+ char *cmd = lp_eventlog_clear_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if(cmd == NULL || strlen(cmd) == 0)
+ {
+ DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
+ return False;
+ }
+
+ memset(command, 0, sizeof(command));
+ if(strlen(backup_file_name) > 0)
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ backup_file_name,
+ info->handle_string);
+ else
+ slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
+ cmd,
+ info->source_log_file_name,
+ info->handle_string);
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if(ret != 0)
+ {
+ if(fd != -1)
+ close(fd);
+ return False;
+ }
+
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
+
+ if(numlines)
+ {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ if(0 == strncmp(qlines[0], "SUCCESS", strlen("SUCCESS")))
+ {
+ DEBUGADD(10, ("Able to clear [%s].\n", info->source_log_file_name));
+ file_lines_free(qlines);
+ return True;
+ }
+ }
+
+ file_lines_free(qlines);
+ return False;
+}
+
+WERROR _eventlog_clear_eventlog(pipes_struct *p,
+ EVENTLOG_Q_CLEAR_EVENTLOG *q_u,
+ EVENTLOG_R_CLEAR_EVENTLOG *r_u)
+{
+ Eventlog_info *info = NULL;
+ pstring backup_file_name;
+ POLICY_HND *handle = NULL;
+
+ if(!q_u || !r_u)
+ return WERR_NOMEM;
+
+ handle = &(q_u->handle);
+ info = find_eventlog_info_by_hnd(p, handle);
+ memset(backup_file_name, 0, sizeof(backup_file_name));
+
+ if(q_u->backup_file_ptr != 0)
+ {
+ unistr2_to_ascii(backup_file_name, &(q_u->backup_file), sizeof(backup_file_name));
+ DEBUG(10, ("_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].",
+ backup_file_name,
+ info->source_log_file_name));
+ }
+ else
+ {
+ /* if backup_file == NULL, do not back up the log before clearing it */
+ DEBUG(10, ("_eventlog_clear_eventlog: clearing [%s] log without making a backup.",
+ info->source_log_file_name));
+ }
+
+ if(!(_eventlog_clear_eventlog_hook(info, backup_file_name)))
+ return WERR_BADFILE;
+
+ return WERR_OK;
+}
diff --git a/source/rpc_server/srv_lsa_ds_nt.c b/source/rpc_server/srv_lsa_ds_nt.c
index d0b7a299be3..b410af8dedf 100644
--- a/source/rpc_server/srv_lsa_ds_nt.c
+++ b/source/rpc_server/srv_lsa_ds_nt.c
@@ -46,6 +46,9 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN
return NT_STATUS_NO_MEMORY;
}
+ get_mydnsdomname(dnsdomain);
+ strlower_m(dnsdomain);
+
switch ( lp_server_role() ) {
case ROLE_STANDALONE:
basic->machine_role = DSROLE_STANDALONE_SRV;
@@ -58,16 +61,12 @@ static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN
basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
- get_mydnsdomname(dnsdomain);
- strlower_m(dnsdomain);
break;
case ROLE_DOMAIN_PDC:
basic->machine_role = DSROLE_PDC;
basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
- get_mydnsdomname(dnsdomain);
- strlower_m(dnsdomain);
break;
}
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 7ea35a91faf..5e949f0e63f 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -314,8 +314,6 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
{
- extern DOM_SID global_sid_World;
- extern DOM_SID global_sid_Builtin;
DOM_SID local_adm_sid;
DOM_SID adm_sid;
@@ -523,6 +521,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
}
/* set up the lsa_enum_trust_dom response */
+
init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, max_num_domains, num_domains, trust_doms);
return r_u->status;
@@ -1337,7 +1336,7 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
int i = 0;
DOM_SID sid;
fstring privname;
- UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+ UNISTR4_ARRAY *uni_privnames = q_u->rights;
struct current_user user;
@@ -1368,11 +1367,16 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
}
for ( i=0; i<q_u->count; i++ ) {
- unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
-
+ UNISTR4 *uni4_str = &uni_privnames->strings[i];
+
/* only try to add non-null strings */
+
+ if ( !uni4_str->string )
+ continue;
+
+ rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
- if ( *privname && !grant_privilege_by_name( &sid, privname ) ) {
+ if ( !grant_privilege_by_name( &sid, privname ) ) {
DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
return NT_STATUS_NO_SUCH_PRIVILEGE;
}
@@ -1390,7 +1394,7 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
int i = 0;
DOM_SID sid;
fstring privname;
- UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+ UNISTR4_ARRAY *uni_privnames = q_u->rights;
struct current_user user;
@@ -1425,11 +1429,16 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
}
for ( i=0; i<q_u->count; i++ ) {
- unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
-
+ UNISTR4 *uni4_str = &uni_privnames->strings[i];
+
/* only try to add non-null strings */
+
+ if ( !uni4_str->string )
+ continue;
+
+ rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
- if ( *privname && !revoke_privilege_by_name( &sid, privname ) ) {
+ if ( !revoke_privilege_by_name( &sid, privname ) ) {
DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
return NT_STATUS_NO_SUCH_PRIVILEGE;
}
@@ -1439,6 +1448,9 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
}
+/***************************************************************************
+ ***************************************************************************/
+
NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
{
struct lsa_info *info = NULL;
@@ -1478,6 +1490,9 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA
}
+/***************************************************************************
+ ***************************************************************************/
+
NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
{
struct lsa_info *info = NULL;
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index 705b629732a..a45a7eebf6a 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -299,7 +299,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p)
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"));
+ DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL.\n"));
return False;
}
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index 2bc0cf301e5..c8ffa18c5a7 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -26,6 +26,9 @@
#include "includes.h"
+extern struct dcinfo last_dcinfo;
+extern userdom_struct current_user_info;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -424,7 +427,6 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
init_net_r_auth_2(r_u, &srv_cred, &srv_flgs, status);
if (NT_STATUS_IS_OK(status)) {
- extern struct dcinfo last_dcinfo;
last_dcinfo = p->dc;
}
@@ -575,7 +577,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
fstring nt_username, nt_domain, nt_workstation;
auth_usersupplied_info *user_info = NULL;
auth_serversupplied_info *server_info = NULL;
- extern userdom_struct current_user_info;
SAM_ACCOUNT *sampw;
struct auth_context *auth_context = NULL;
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index 01e91ce6c50..ee6c42bd88f 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -40,6 +40,9 @@
#include "includes.h"
+extern struct pipe_id_info pipe_names[];
+extern struct current_user current_user;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -751,7 +754,6 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
RPC_IFACE* transfer, uint32 context_id)
{
- extern struct pipe_id_info pipe_names[];
char *pipe_name = p->name;
int i=0;
fstring pname;
@@ -765,6 +767,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
for ( i=0; pipe_names[i].client_pipe; i++ )
{
+ DEBUG(10,("checking %s\n", pipe_names[i].client_pipe));
if ( strequal(pipe_names[i].client_pipe, pname)
&& (abstract->version == pipe_names[i].abstr_syntax.version)
&& (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0)
@@ -1426,7 +1429,6 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
if (p->ntlmssp_auth_validated) {
memcpy(user, &p->pipe_user, sizeof(struct current_user));
} else {
- extern struct current_user current_user;
memcpy(user, &current_user, sizeof(struct current_user));
}
@@ -1631,6 +1633,12 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
case PI_NETDFS:
netdfs_get_pipe_fns( &cmds, &n_cmds );
break;
+ case PI_SVCCTL:
+ svcctl_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_EVENTLOG:
+ eventlog_get_pipe_fns( &cmds, &n_cmds );
+ break;
#ifdef DEVELOPER
case PI_ECHO:
echo_get_pipe_fns( &cmds, &n_cmds );
diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c
index b780be0aff3..a90650c536d 100644
--- a/source/rpc_server/srv_reg.c
+++ b/source/rpc_server/srv_reg.c
@@ -63,8 +63,8 @@ static BOOL api_reg_close(pipes_struct *p)
static BOOL api_reg_open_hklm(pipes_struct *p)
{
- REG_Q_OPEN_HKLM q_u;
- REG_R_OPEN_HKLM r_u;
+ REG_Q_OPEN_HIVE q_u;
+ REG_R_OPEN_HIVE r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
@@ -72,12 +72,12 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the reg open */
- if(!reg_io_q_open_hklm("", &q_u, data, 0))
+ if(!reg_io_q_open_hive("", &q_u, data, 0))
return False;
r_u.status = _reg_open_hklm(p, &q_u, &r_u);
- if(!reg_io_r_open_hklm("", &r_u, rdata, 0))
+ if(!reg_io_r_open_hive("", &r_u, rdata, 0))
return False;
return True;
@@ -89,8 +89,8 @@ static BOOL api_reg_open_hklm(pipes_struct *p)
static BOOL api_reg_open_hku(pipes_struct *p)
{
- REG_Q_OPEN_HKU q_u;
- REG_R_OPEN_HKU r_u;
+ REG_Q_OPEN_HIVE q_u;
+ REG_R_OPEN_HIVE r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
@@ -98,12 +98,12 @@ static BOOL api_reg_open_hku(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the reg open */
- if(!reg_io_q_open_hku("", &q_u, data, 0))
+ if(!reg_io_q_open_hive("", &q_u, data, 0))
return False;
r_u.status = _reg_open_hku(p, &q_u, &r_u);
- if(!reg_io_r_open_hku("", &r_u, rdata, 0))
+ if(!reg_io_r_open_hive("", &r_u, rdata, 0))
return False;
return True;
@@ -115,8 +115,8 @@ static BOOL api_reg_open_hku(pipes_struct *p)
static BOOL api_reg_open_hkcr(pipes_struct *p)
{
- REG_Q_OPEN_HKCR q_u;
- REG_R_OPEN_HKCR r_u;
+ REG_Q_OPEN_HIVE q_u;
+ REG_R_OPEN_HIVE r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
@@ -124,12 +124,12 @@ static BOOL api_reg_open_hkcr(pipes_struct *p)
ZERO_STRUCT(r_u);
/* grab the reg open */
- if(!reg_io_q_open_hkcr("", &q_u, data, 0))
+ if(!reg_io_q_open_hive("", &q_u, data, 0))
return False;
r_u.status = _reg_open_hkcr(p, &q_u, &r_u);
- if(!reg_io_r_open_hkcr("", &r_u, rdata, 0))
+ if(!reg_io_r_open_hive("", &r_u, rdata, 0))
return False;
return True;
@@ -216,6 +216,32 @@ static BOOL api_reg_shutdown(pipes_struct *p)
}
/*******************************************************************
+ api_reg_shutdown_ex
+ ********************************************************************/
+
+static BOOL api_reg_shutdown_ex(pipes_struct *p)
+{
+ REG_Q_SHUTDOWN_EX q_u;
+ REG_R_SHUTDOWN_EX 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 ex */
+ if(!reg_io_q_shutdown_ex("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_shutdown_ex(p, &q_u, &r_u);
+
+ if(!reg_io_r_shutdown_ex("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
api_reg_abort_shutdown
********************************************************************/
@@ -268,25 +294,25 @@ static BOOL api_reg_query_key(pipes_struct *p)
}
/*******************************************************************
- api_reg_unknown_1a
+ api_reg_getversion
********************************************************************/
-static BOOL api_reg_unknown_1a(pipes_struct *p)
+static BOOL api_reg_getversion(pipes_struct *p)
{
- REG_Q_UNKNOWN_1A q_u;
- REG_R_UNKNOWN_1A r_u;
+ REG_Q_GETVERSION q_u;
+ REG_R_GETVERSION 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(!reg_io_q_unknown_1a("", &q_u, data, 0))
+ if(!reg_io_q_getversion("", &q_u, data, 0))
return False;
- r_u.status = _reg_unknown_1a(p, &q_u, &r_u);
+ r_u.status = _reg_getversion(p, &q_u, &r_u);
- if(!reg_io_r_unknown_1a("", &r_u, rdata, 0))
+ if(!reg_io_r_getversion("", &r_u, rdata, 0))
return False;
return True;
@@ -343,8 +369,31 @@ static BOOL api_reg_enum_value(pipes_struct *p)
}
/*******************************************************************
- api_reg_save_key
- ********************************************************************/
+ ******************************************************************/
+
+static BOOL api_reg_restore_key(pipes_struct *p)
+{
+ REG_Q_RESTORE_KEY q_u;
+ REG_R_RESTORE_KEY 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(!reg_io_q_restore_key("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_restore_key(p, &q_u, &r_u);
+
+ if(!reg_io_r_restore_key("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ******************************************************************/
static BOOL api_reg_save_key(pipes_struct *p)
{
@@ -383,9 +432,11 @@ static struct api_struct api_reg_cmds[] =
{ "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key },
{ "REG_INFO" , REG_INFO , api_reg_info },
{ "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },
+ { "REG_SHUTDOWN_EX" , REG_SHUTDOWN_EX , api_reg_shutdown_ex },
{ "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown },
- { "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a },
- { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }
+ { "REG_GETVERSION" , REG_GETVERSION , api_reg_getversion },
+ { "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key },
+ { "REG_RESTORE_KEY" , REG_RESTORE_KEY , api_reg_restore_key }
};
void reg_get_pipe_fns( struct api_struct **fns, int *n_fns )
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index c11e0d59a05..f031a3213f2 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 2001.
- * Copyright (C) Gerald Carter 2002.
+ * Copyright (C) Gerald Carter 2002-2005.
*
* 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
@@ -291,7 +291,7 @@ WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
/*******************************************************************
********************************************************************/
-WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
+WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 );
}
@@ -299,7 +299,7 @@ WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_
/*******************************************************************
********************************************************************/
-WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
+WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
}
@@ -307,7 +307,7 @@ WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_
/*******************************************************************
********************************************************************/
-WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
+WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 );
}
@@ -328,7 +328,7 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
if ( !key )
return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
- rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
+ rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
result = open_registry_key( p, &pol, key, name, 0x0 );
@@ -362,7 +362,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
- rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
+ rpcstr_pull(name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0);
DEBUG(5,("reg_info: looking up value: [%s]\n", name));
@@ -439,7 +439,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
out:
- new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
+ init_reg_r_info(q_u->ptr_buf, r_u, val, status);
regval_ctr_destroy( &regvals );
free_registry_value( val );
@@ -485,22 +485,22 @@ WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_
/*****************************************************************************
- Implementation of REG_UNKNOWN_1A
+ Implementation of REG_GETVERSION
****************************************************************************/
-WERROR _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
+WERROR _reg_getversion(pipes_struct *p, REG_Q_GETVERSION *q_u, REG_R_GETVERSION *r_u)
{
WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
- DEBUG(5,("_reg_unknown_1a: Enter\n"));
+ DEBUG(5,("_reg_getversion: Enter\n"));
if ( !regkey )
return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
r_u->unknown = 0x00000005; /* seems to be consistent...no idea what it means */
- DEBUG(5,("_reg_unknown_1a: Exit\n"));
+ DEBUG(5,("_reg_getversion: Exit\n"));
return status;
}
@@ -561,8 +561,7 @@ WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE
DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
- if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
- {
+ if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) ) {
status = WERR_NO_MORE_ITEMS;
goto done;
}
@@ -587,110 +586,190 @@ done:
reg_shutdwon
********************************************************************/
+WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
+{
+ REG_Q_SHUTDOWN_EX q_u_ex;
+ REG_R_SHUTDOWN_EX r_u_ex;
+
+ /* copy fields (including stealing memory) */
+
+ q_u_ex.server = q_u->server;
+ q_u_ex.message = q_u->message;
+ q_u_ex.timeout = q_u->timeout;
+ q_u_ex.force = q_u->force;
+ q_u_ex.reboot = q_u->reboot;
+ q_u_ex.reason = 0x0; /* don't care for now */
+
+ /* thunk down to _reg_shutdown_ex() (just returns a status) */
+
+ return _reg_shutdown_ex( p, &q_u_ex, &r_u_ex );
+}
+
+/*******************************************************************
+ reg_shutdown_ex
+ ********************************************************************/
+
#define SHUTDOWN_R_STRING "-r"
#define SHUTDOWN_F_STRING "-f"
-WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
+WERROR _reg_shutdown_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_EX *r_u)
{
- WERROR status = WERR_OK;
pstring shutdown_script;
- UNISTR2 unimsg = q_u->uni_msg;
pstring message;
pstring chkmsg;
fstring timeout;
+ fstring reason;
fstring r;
fstring f;
+ int ret;
+ BOOL can_shutdown;
+
+ pstrcpy(shutdown_script, lp_shutdown_script());
- /* message */
- rpcstr_pull (message, unimsg.buffer, sizeof(message), unimsg.uni_str_len*2,0);
- /* security check */
+ if ( !*shutdown_script )
+ return WERR_ACCESS_DENIED;
+
+ /* pull the message string and perform necessary sanity checks on it */
+
+ pstrcpy( message, "" );
+ if ( q_u->message ) {
+ UNISTR2 *msg_string = q_u->message->string;
+
+ rpcstr_pull( message, msg_string->buffer, sizeof(message), msg_string->uni_str_len*2, 0 );
+ }
alpha_strcpy (chkmsg, message, NULL, sizeof(message));
- /* timeout */
+
fstr_sprintf(timeout, "%d", q_u->timeout);
- /* reboot */
fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
- /* force */
fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
+ fstr_sprintf( reason, "%d", q_u->reason );
- pstrcpy(shutdown_script, lp_shutdown_script());
+ all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
+ all_string_sub( shutdown_script, "%t", timeout, sizeof(shutdown_script) );
+ all_string_sub( shutdown_script, "%r", r, sizeof(shutdown_script) );
+ all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
+ all_string_sub( shutdown_script, "%x", reason, sizeof(shutdown_script) );
+
+ can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
+
+ /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
+ Take the error return from the script and provide it as the Windows return code. */
+
+ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+
+ if ( can_shutdown )
+ become_root();
- if(*shutdown_script) {
- int shutdown_ret;
- SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
- BOOL can_shutdown;
+ ret = smbrun( shutdown_script, NULL );
- can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+ if ( can_shutdown )
+ unbecome_root();
+
+ /********** END SeRemoteShutdownPrivilege BLOCK **********/
+
+ DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
+ shutdown_script, ret));
- /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
- if ( can_shutdown )
- become_root();
- all_string_sub(shutdown_script, "%m", chkmsg, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%t", timeout, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%r", r, sizeof(shutdown_script));
- all_string_sub(shutdown_script, "%f", f, sizeof(shutdown_script));
- shutdown_ret = smbrun(shutdown_script,NULL);
- DEBUG(3,("_reg_shutdown: Running the command `%s' gave %d\n",shutdown_script,shutdown_ret));
- if ( can_shutdown )
- unbecome_root();
- /********** END SeRemoteShutdownPrivilege BLOCK **********/
- }
- return status;
+ return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
}
+
+
+
/*******************************************************************
reg_abort_shutdwon
********************************************************************/
WERROR _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
{
- WERROR status = WERR_OK;
pstring abort_shutdown_script;
+ int ret;
+ BOOL can_shutdown;
pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
- if(*abort_shutdown_script) {
- int abort_shutdown_ret;
- SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
- BOOL can_shutdown;
+ if ( !*abort_shutdown_script )
+ return WERR_ACCESS_DENIED;
- can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+ can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
- /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
- if ( can_shutdown )
- become_root();
- abort_shutdown_ret = smbrun(abort_shutdown_script,NULL);
- DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",abort_shutdown_script,abort_shutdown_ret));
- if ( can_shutdown )
- unbecome_root();
- /********** END SeRemoteShutdownPrivilege BLOCK **********/
+ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+
+ if ( can_shutdown )
+ become_root();
- }
+ ret = smbrun( abort_shutdown_script, NULL );
+
+ if ( can_shutdown )
+ unbecome_root();
+
+ /********** END SeRemoteShutdownPrivilege BLOCK **********/
- return status;
+ DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
+ abort_shutdown_script, ret));
+
+
+ return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR _reg_restore_key(pipes_struct *p, REG_Q_RESTORE_KEY *q_u, REG_R_RESTORE_KEY *r_u)
+{
+ REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+ pstring filename;
+
+ DEBUG(5,("_reg_restore_key: Enter\n"));
+
+ /*
+ * basically this is a no op function which just verifies
+ * that the client gave us a valid registry key handle
+ */
+
+ if ( !regkey )
+ return WERR_BADFID;
+
+ rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
+
+ DEBUG(8,("_reg_restore_key: verifying restore of key [%s] from \"%s\"\n", regkey->name, filename));
+
+#if 0
+ validate_reg_filemame( filename );
+ return restore_registry_key( regkey, filename );
+#endif
+
+ return WERR_OK;
}
/*******************************************************************
- REG_SAVE_KEY (0x14)
********************************************************************/
WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u)
{
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
+ pstring filename;
DEBUG(5,("_reg_save_key: Enter\n"));
/*
- * basically this is a no op function which just gverifies
+ * basically this is a no op function which just verifies
* that the client gave us a valid registry key handle
*/
if ( !regkey )
- return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
+ return WERR_BADFID;
- DEBUG(8,("_reg_save_key: berifying backup of key [%s]\n", regkey->name));
-
+ rpcstr_pull(filename, q_u->filename.string->buffer, sizeof(filename), q_u->filename.string->uni_str_len*2, STR_TERMINATE);
+
+ DEBUG(8,("_reg_save_key: verifying backup of key [%s] to \"%s\"\n", regkey->name, filename));
+
+#if 0
+ validate_reg_filemame( filename );
+ return backup_registry_key( regkey, filename );
+#endif
return WERR_OK;
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 139960f6613..84c78eab641 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -39,8 +39,6 @@
SA_RIGHT_USER_CHANGE_PASSWORD | \
SA_RIGHT_USER_SET_LOC_COM )
-extern DOM_SID global_sid_Builtin;
-
extern rid_name domain_group_rids[];
extern rid_name domain_alias_rids[];
extern rid_name builtin_alias_rids[];
@@ -80,7 +78,6 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
struct generic_mapping *map,
DOM_SID *sid, uint32 sid_access )
{
- extern DOM_SID global_sid_World;
DOM_SID adm_sid, act_sid, domadmin_sid;
SEC_ACE ace[5]; /* at most 5 entries */
SEC_ACCESS mask;
@@ -867,6 +864,7 @@ static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
int i;
uint32 group_entries = 0;
uint32 num_entries = 0;
+ NTSTATUS result = NT_STATUS_OK;
*p_num_entries = 0;
@@ -884,6 +882,7 @@ static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
if (num_entries>max_entries) {
DEBUG(5,("Limiting to %d entries\n", max_entries));
num_entries=max_entries;
+ result = STATUS_MORE_ENTRIES;
}
*d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
@@ -906,7 +905,7 @@ static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
DEBUG(10,("get_group_domain_entries: returning %d entries\n",
*p_num_entries));
- return NT_STATUS_OK;
+ return result;
}
/*******************************************************************
@@ -973,13 +972,19 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
/* the domain group array is being allocated in the function below */
- if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
+ r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid,
+ q_u->start_idx, &num_entries,
+ MAX_SAM_ENTRIES);
+
+ if (!NT_STATUS_IS_OK(r_u->status) &&
+ !NT_STATUS_EQUAL(r_u->status, STATUS_MORE_ENTRIES))
return r_u->status;
- }
- make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
+ make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
+ num_entries, grp);
- init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
+ init_samr_r_enum_dom_groups(r_u, q_u->start_idx+num_entries,
+ num_entries);
DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
@@ -1464,8 +1469,9 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
makes a SAMR_R_LOOKUP_RIDS structure.
********************************************************************/
-static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
- UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
+static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
+ const char **names, UNIHDR **pp_hdr_name,
+ UNISTR2 **pp_uni_name)
{
uint32 i;
UNIHDR *hdr_name=NULL;
@@ -1485,7 +1491,7 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
}
for (i = 0; i < num_names; i++) {
- DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
+ DEBUG(10, ("names[%d]:%s\n", i, *names[i] ? names[i] : ""));
init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
init_uni_hdr(&hdr_name[i], &uni_name[i]);
}
@@ -1502,16 +1508,13 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
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;
+ const char **names;
+ uint32 *attrs = NULL;
UNIHDR *hdr_name = NULL;
UNISTR2 *uni_name = NULL;
DOM_SID pol_sid;
int num_rids = q_u->num_rids1;
- int i;
uint32 acc_granted;
- BOOL have_mapped = False;
- BOOL have_unmapped = False;
r_u->status = NT_STATUS_OK;
@@ -1527,11 +1530,12 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
return NT_STATUS_UNSUCCESSFUL;
}
- if (num_rids) {
- if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
- return NT_STATUS_NO_MEMORY;
- }
-
+ names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
+ attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
+
+ if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
+ return NT_STATUS_NO_MEMORY;
+
if (!sid_equal(&pol_sid, get_global_sam_sid())) {
/* TODO: Sooner or later we need to look up BUILTIN rids as
* well. -- vl */
@@ -1539,44 +1543,17 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
}
become_root(); /* lookup_sid can require root privs */
-
- for (i = 0; i < num_rids; i++) {
- fstring tmpname;
- fstring domname;
- DOM_SID sid;
- enum SID_NAME_USE type;
-
- group_attrs[i] = SID_NAME_UNKNOWN;
- *group_names[i] = '\0';
-
- sid_copy(&sid, &pol_sid);
- sid_append_rid(&sid, q_u->rid[i]);
-
- if (lookup_sid(&sid, domname, tmpname, &type)) {
- group_attrs[i] = (uint32)type;
- fstrcpy(group_names[i],tmpname);
- DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i],
- group_attrs[i]));
- have_mapped = True;
- } else {
- have_unmapped = True;
- }
- }
-
+ r_u->status = pdb_lookup_rids(p->mem_ctx, &pol_sid, num_rids, q_u->rid,
+ &names, &attrs);
unbecome_root();
done:
- r_u->status = NT_STATUS_NONE_MAPPED;
-
- if (have_mapped)
- r_u->status =
- have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
-
- if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
+ if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
+ &hdr_name, &uni_name))
return NT_STATUS_NO_MEMORY;
- init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
+ init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs);
DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
@@ -1977,7 +1954,7 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S
DOM_GID *gids = NULL;
int num_groups = 0;
gid_t *unix_gids;
- int i, num_gids, num_sids;
+ int i, num_gids;
uint32 acc_granted;
BOOL ret;
NTSTATUS result;
@@ -2027,7 +2004,6 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S
}
sids = NULL;
- num_sids = 0;
become_root();
result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
@@ -2900,7 +2876,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
acct_ctrl = pdb_get_acct_ctrl(pwd);
- if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
+ if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
pdb_free_sam(&pwd);
return False;
}
@@ -2951,7 +2927,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
set_user_info_pw
********************************************************************/
-static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
+static BOOL set_user_info_pw(uint8 *pass, SAM_ACCOUNT *pwd)
{
uint32 len;
pstring plaintext_buf;
@@ -3097,7 +3073,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
dump_data(100, (char *)ctr->info.id24->pass, 516);
- if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
+ if (!set_user_info_pw(ctr->info.id24->pass, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
@@ -3259,8 +3235,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
- int num_groups = 0;
- uint32 *rids=NULL;
+ int num_alias_rids;
+ uint32 *alias_rids;
struct samr_info *info = NULL;
int i;
@@ -3268,8 +3244,6 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
NTSTATUS ntstatus2;
DOM_SID *members;
- DOM_SID *aliases;
- int num_aliases;
BOOL res;
r_u->status = NT_STATUS_OK;
@@ -3302,35 +3276,20 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
for (i=0; i<q_u->num_sids1; i++)
sid_copy(&members[i], &q_u->sid[i].sid);
+ alias_rids = NULL;
+ num_alias_rids = 0;
+
become_root();
- res = pdb_enum_alias_memberships(members,
- q_u->num_sids1, &aliases,
- &num_aliases);
+ res = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
+ q_u->num_sids1,
+ &alias_rids, &num_alias_rids);
unbecome_root();
if (!res)
return NT_STATUS_UNSUCCESSFUL;
- rids = NULL;
- num_groups = 0;
-
- for (i=0; i<num_aliases; i++) {
- uint32 rid;
-
- if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
- continue;
-
- rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
-
- if (rids == NULL)
- return NT_STATUS_NO_MEMORY;
-
- rids[num_groups] = rid;
- num_groups += 1;
- }
- SAFE_FREE(aliases);
-
- init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
+ init_samr_r_query_useraliases(r_u, num_alias_rids, alias_rids,
+ NT_STATUS_OK);
return NT_STATUS_OK;
}
@@ -3821,7 +3780,6 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
DOM_SID user_sid;
SAM_ACCOUNT *sam_pass=NULL;
uint32 acc_granted;
- SE_PRIV se_rights;
BOOL can_add_accounts;
BOOL ret;
@@ -3847,8 +3805,7 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
return NT_STATUS_NO_SUCH_USER;
}
- se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4121,7 +4078,6 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
DOM_SID dom_sid;
DOM_SID info_sid;
fstring name;
- struct group *grp;
struct samr_info *info;
uint32 acc_granted;
gid_t gid;
@@ -4168,7 +4124,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
return NT_STATUS_ACCESS_DENIED;
/* check if the group has been successfully created */
- if ((grp=getgrgid(gid)) == NULL)
+ if ( getgrgid(gid) == NULL )
return NT_STATUS_ACCESS_DENIED;
if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c
index 6797730be97..61160ccaa02 100644
--- a/source/rpc_server/srv_samr_util.c
+++ b/source/rpc_server/srv_samr_util.c
@@ -264,7 +264,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
pdb_sethexhours(old, pdb_get_hours(to));
- pdb_sethexhours(new, (const char *)from->logon_hrs.hours);
+ pdb_sethexhours(new, from->logon_hrs.hours);
if (!strequal(old, new)) {
pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
}
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index f846813a40b..b3a67dd6cfd 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -1244,6 +1244,9 @@ static BOOL api_spoolss_getjob(pipes_struct *p)
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_getjob("", &q_u, data, 0)) {
DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n"));
return False;
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index ffeeb0af9a9..0f33fd7dec8 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -28,6 +28,8 @@
#include "includes.h"
+extern userdom_struct current_user_info;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -644,41 +646,6 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
return True;
}
-/****************************************************************************
- Allocate more memory for a BUFFER.
-****************************************************************************/
-
-static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
-{
- prs_struct *ps;
- uint32 extra_space;
- uint32 old_offset;
-
- ps= &buffer->prs;
-
- /* damn, I'm doing the reverse operation of prs_grow() :) */
- if (buffer_size < prs_data_size(ps))
- extra_space=0;
- else
- extra_space = buffer_size - prs_data_size(ps);
-
- /*
- * save the offset and move to the end of the buffer
- * prs_grow() checks the extra_space against the offset
- */
- old_offset=prs_offset(ps);
- prs_set_offset(ps, prs_data_size(ps));
-
- if (!prs_grow(ps, extra_space))
- return False;
-
- prs_set_offset(ps, old_offset);
-
- buffer->string_at_end=prs_data_size(ps);
-
- return True;
-}
-
/***************************************************************************
check to see if the client motify handle is monitoring the notification
given by (notify_type, notify_field).
@@ -1526,10 +1493,10 @@ static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q
DEBUG(8,("convert_to_openprinterex\n"));
- q_u_ex->printername_ptr = q_u->printername_ptr;
-
- if (q_u->printername_ptr)
- copy_unistr2(&q_u_ex->printername, &q_u->printername);
+ if ( q_u->printername ) {
+ q_u_ex->printername = TALLOC_P( ctx, UNISTR2 );
+ copy_unistr2(q_u_ex->printername, q_u->printername);
+ }
copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
}
@@ -1623,7 +1590,6 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R
WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
{
- UNISTR2 *printername = NULL;
PRINTER_DEFAULT *printer_default = &q_u->printer_default;
POLICY_HND *handle = &r_u->handle;
@@ -1632,15 +1598,13 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
struct current_user user;
Printer_entry *Printer=NULL;
- if (q_u->printername_ptr != 0)
- printername = &q_u->printername;
-
- if (printername == NULL)
+ if ( !q_u->printername )
return WERR_INVALID_PRINTER_NAME;
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
- unistr2_to_ascii(name, printername, sizeof(name)-1);
+
+ unistr2_to_ascii(name, q_u->printername, sizeof(name)-1);
DEBUGADD(3,("checking name: %s\n",name));
@@ -4121,7 +4085,7 @@ static void free_dev_mode(DEVICEMODE *dev)
if (dev == NULL)
return;
- SAFE_FREE(dev->private);
+ SAFE_FREE(dev->private);
SAFE_FREE(dev);
}
@@ -4404,13 +4368,14 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
Spoolss_enumprinters.
********************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
int n_services=lp_numservices();
PRINTER_INFO_1 *tp, *printers=NULL;
PRINTER_INFO_1 current_prt;
+ WERROR result = WERR_OK;
DEBUG(4,("enum_all_printers_info_1\n"));
@@ -4438,29 +4403,36 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_printer_info_1(&printers[i]);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_printer_info_1("", buffer, &printers[i], 0);
+out:
/* clear memory */
+
SAFE_FREE(printers);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
/********************************************************************
enum_all_printers_info_1_local.
*********************************************************************/
-static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
DEBUG(4,("enum_all_printers_info_1_local\n"));
@@ -4471,7 +4443,7 @@ static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered,
enum_all_printers_info_1_name.
*********************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
char *s = name;
@@ -4492,13 +4464,14 @@ static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, ui
enum_all_printers_info_1_remote.
*********************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTER_INFO_1 *printer;
fstring printername;
fstring desc;
fstring comment;
DEBUG(4,("enum_all_printers_info_1_remote\n"));
+ WERROR result = WERR_OK;
/* JFM: currently it's more a place holder than anything else.
* In the spooler world there is a notion of server registration.
@@ -4525,23 +4498,27 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
/* check the required size. */
*needed += spoolss_size_printer_info_1(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
+out:
/* clear memory */
SAFE_FREE(printer);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
#endif
@@ -4550,7 +4527,7 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
enum_all_printers_info_1_network.
*********************************************************************/
-static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
char *s = name;
@@ -4579,13 +4556,14 @@ static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer,
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int snum;
int i;
int n_services=lp_numservices();
PRINTER_INFO_2 *tp, *printers=NULL;
PRINTER_INFO_2 current_prt;
+ WERROR result = WERR_OK;
for (snum=0; snum<n_services; snum++) {
if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
@@ -4610,30 +4588,31 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_printer_info_2(&printers[i]);
- if (!alloc_buffer_size(buffer, *needed)) {
- for (i=0; i<*returned; i++) {
- free_devmode(printers[i].devmode);
- }
- SAFE_FREE(printers);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_printer_info_2("", buffer, &(printers[i]), 0);
+out:
/* clear memory */
for (i=0; i<*returned; i++) {
free_devmode(printers[i].devmode);
}
SAFE_FREE(printers);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
/********************************************************************
@@ -4641,7 +4620,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
********************************************************************/
static WERROR enumprinters_level1( uint32 flags, fstring name,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
/* Not all the flags are equals */
@@ -4668,7 +4647,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
********************************************************************/
static WERROR enumprinters_level2( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
char *s = servername;
@@ -4697,7 +4676,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername,
********************************************************************/
static WERROR enumprinters_level5( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
@@ -4715,7 +4694,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
uint32 flags = q_u->flags;
UNISTR2 *servername = &q_u->servername;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
@@ -4723,8 +4702,11 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
fstring name;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumprinters\n"));
@@ -4764,9 +4746,10 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_0 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
return WERR_NOMEM;
@@ -4776,30 +4759,34 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* check the required size. */
*needed += spoolss_size_printer_info_0(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_0("", buffer, printer, 0);
+out:
/* clear memory */
- SAFE_FREE(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
+ SAFE_FREE(printer);
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_1 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
return WERR_NOMEM;
@@ -4809,30 +4796,33 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* check the required size. */
*needed += spoolss_size_printer_info_1(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_1("", buffer, printer, 0);
+out:
/* clear memory */
SAFE_FREE(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_2 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
return WERR_NOMEM;
@@ -4842,33 +4832,34 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* check the required size. */
*needed += spoolss_size_printer_info_2(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_2(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
- /* fill the buffer with the structures */
- if (!smb_io_printer_info_2("", buffer, printer, 0)) {
- free_printer_info_2(printer);
- return WERR_NOMEM;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
+
+ /* fill the buffer with the structures */
+ if (!smb_io_printer_info_2("", buffer, printer, 0))
+ result = WERR_NOMEM;
+out:
/* clear memory */
free_printer_info_2(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_3 *printer=NULL;
+ WERROR result = WERR_OK;
if (!construct_printer_info_3(print_hnd, &printer, snum))
return WERR_NOMEM;
@@ -4876,30 +4867,33 @@ static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* check the required size. */
*needed += spoolss_size_printer_info_3(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_3(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_3("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_3(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_4 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
return WERR_NOMEM;
@@ -4910,30 +4904,33 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* 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;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_4("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_4(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_5 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
return WERR_NOMEM;
@@ -4944,27 +4941,30 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* 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;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_info_5("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_5(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
PRINTER_INFO_7 *printer=NULL;
+ WERROR result = WERR_OK;
if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
return WERR_NOMEM;
@@ -4975,22 +4975,25 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER
/* check the required size. */
*needed += spoolss_size_printer_info_7(printer);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_info_7(printer);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+
}
/* fill the buffer with the structures */
smb_io_printer_info_7("", buffer, printer, 0);
+out:
/* clear memory */
free_printer_info_7(printer);
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -5000,7 +5003,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
@@ -5008,8 +5011,11 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
int snum;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
*needed=0;
@@ -5433,149 +5439,154 @@ 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);
-
}
/****************************************************************************
****************************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_1 *info=NULL;
- WERROR status;
+ WERROR result;
if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
return WERR_NOMEM;
- status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(info);
- return status;
- }
+ result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_1(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_1("", buffer, info, 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_2 *info=NULL;
- WERROR status;
+ WERROR result;
if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
return WERR_NOMEM;
- status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- SAFE_FREE(info);
- return status;
- }
+ result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_2(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_2("", buffer, info, 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_3 info;
- WERROR status;
+ WERROR result;
ZERO_STRUCT(info);
- status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
+ result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_3(&info);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_driver_info_3(&info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_3("", buffer, &info, 0);
+out:
free_printer_driver_info_3(&info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
****************************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
DRIVER_INFO_6 info;
- WERROR status;
+ WERROR result;
ZERO_STRUCT(info);
- status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
+ result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
+ if (!W_ERROR_IS_OK(result))
+ goto out;
/* check the required size. */
*needed += spoolss_size_printer_driver_info_6(&info);
- if (!alloc_buffer_size(buffer, *needed)) {
- free_printer_driver_info_6(&info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
smb_io_printer_driver_info_6("", buffer, &info, 0);
+out:
free_printer_driver_info_6(&info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -5587,7 +5598,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
UNISTR2 *uni_arch = &q_u->architecture;
uint32 level = q_u->level;
uint32 clientmajorversion = q_u->clientmajorversion;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *servermajorversion = &r_u->servermajorversion;
@@ -5599,8 +5610,11 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
int snum;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_getprinterdriver2\n"));
@@ -6015,7 +6029,6 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
{
- extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
char **qlines;
pstring command;
@@ -6389,8 +6402,10 @@ 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)
{
- /* that's an [in out] buffer (despite appearences to the contrary) */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+ /* that's an [in out] buffer */
+
+ if ( q_u->buffer )
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
r_u->needed = 0;
return WERR_INVALID_PARAM; /* this is what a NT server
@@ -6476,11 +6491,12 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
NT_PRINTER_INFO_LEVEL *ntprinter,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
JOB_INFO_1 *info;
int i;
+ WERROR result = WERR_OK;
info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
if (info==NULL) {
@@ -6498,24 +6514,28 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
for (i=0; i<*returned; i++)
(*needed) += spoolss_size_job_info_1(&info[i]);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_job_info_1("", buffer, &info[i], 0);
+out:
/* clear memory */
SAFE_FREE(info);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -6524,19 +6544,17 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
NT_PRINTER_INFO_LEVEL *ntprinter,
- NEW_BUFFER *buffer, uint32 offered,
+ RPC_BUFFER *buffer, uint32 offered,
uint32 *needed, uint32 *returned)
{
JOB_INFO_2 *info = NULL;
int i;
- WERROR result;
+ WERROR result = WERR_OK;
DEVICEMODE *devmode = NULL;
- info=SMB_MALLOC_ARRAY(JOB_INFO_2,*returned);
- if (info==NULL) {
+ if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
*returned=0;
- result = WERR_NOMEM;
- goto done;
+ return WERR_NOMEM;
}
/* this should not be a failure condition if the devmode is NULL */
@@ -6544,8 +6562,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
devmode = construct_dev_mode(snum);
for (i=0; i<*returned; i++)
- fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter,
- devmode);
+ fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
free_a_printer(&ntprinter, 2);
SAFE_FREE(queue);
@@ -6555,29 +6572,26 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
(*needed) += spoolss_size_job_info_2(&info[i]);
if (*needed > offered) {
- *returned=0;
result = WERR_INSUFFICIENT_BUFFER;
- goto done;
+ goto out;
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info);
- result = WERR_INSUFFICIENT_BUFFER;
- goto done;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
smb_io_job_info_2("", buffer, &info[i], 0);
- result = WERR_OK;
-
- done:
- free_a_printer(&ntprinter, 2);
+out:
free_devmode(devmode);
- SAFE_FREE(queue);
SAFE_FREE(info);
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
return result;
}
@@ -6590,7 +6604,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
{
POLICY_HND *handle = &q_u->handle;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
@@ -6601,8 +6615,11 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
print_queue_struct *queue=NULL;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumjobs\n"));
@@ -6703,15 +6720,15 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
Enumerates all printer drivers at level 1.
****************************************************************************/
-static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
+ WERROR result = WERR_OK;
*returned=0;
@@ -6757,9 +6774,14 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
*needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_1);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the driver structures */
@@ -6768,29 +6790,28 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
}
+out:
SAFE_FREE(driver_info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
Enumerates all printer drivers at level 2.
****************************************************************************/
-static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
+ WERROR result = WERR_OK;
*returned=0;
@@ -6837,9 +6858,14 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
*needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_2);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the form structures */
@@ -6848,29 +6874,28 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
}
+out:
SAFE_FREE(driver_info_2);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
Enumerates all printer drivers at level 3.
****************************************************************************/
-static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
-
NT_PRINTER_DRIVER_INFO_LEVEL driver;
DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
+ WERROR result = WERR_OK;
*returned=0;
@@ -6917,28 +6942,32 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
*needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(driver_info_3);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
-
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
+
/* fill the buffer with the driver structures */
for (i=0; i<*returned; i++) {
DEBUGADD(6,("adding driver [%d] to buffer\n",i));
smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
}
+out:
for (i=0; i<*returned; i++)
SAFE_FREE(driver_info_3[i].dependentfiles);
-
+
SAFE_FREE(driver_info_3);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -6948,22 +6977,25 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
- fstring *list = NULL;
fstring servername;
fstring architecture;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumprinterdrivers\n"));
- *needed=0;
- *returned=0;
+
+ *needed = 0;
+ *returned = 0;
unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1);
unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1);
@@ -6979,8 +7011,6 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
case 3:
return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
default:
- *returned=0;
- SAFE_FREE(list);
return WERR_UNKNOWN_LEVEL;
}
}
@@ -7006,7 +7036,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *numofforms = &r_u->numofforms;
@@ -7019,8 +7049,11 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
int i;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumforms\n"));
DEBUGADD(5,("Offered buffer size [%d]\n", offered));
@@ -7032,7 +7065,8 @@ WERROR _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 WERR_NO_MORE_ITEMS;
+ if (*numofforms == 0)
+ return WERR_NO_MORE_ITEMS;
switch (level) {
case 1:
@@ -7068,10 +7102,17 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
*needed=buffer_size;
- if (!alloc_buffer_size(buffer, buffer_size)){
+ if (*needed > offered) {
SAFE_FREE(forms_1);
+ *numofforms=0;
return WERR_INSUFFICIENT_BUFFER;
}
+
+ if (!rpcbuf_alloc_size(buffer, buffer_size)){
+ SAFE_FREE(forms_1);
+ *numofforms=0;
+ return WERR_NOMEM;
+ }
/* fill the buffer with the form structures */
for (i=0; i<numbuiltinforms; i++) {
@@ -7085,12 +7126,7 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
SAFE_FREE(forms_1);
- if (*needed > offered) {
- *numofforms=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
- else
- return WERR_OK;
+ return WERR_OK;
default:
SAFE_FREE(list);
@@ -7107,7 +7143,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
{
uint32 level = q_u->level;
UNISTR2 *uni_formname = &q_u->formname;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
@@ -7120,8 +7156,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
int numofforms=0, i=0;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
@@ -7165,13 +7204,11 @@ WERROR _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)){
+ if (*needed > offered)
return WERR_INSUFFICIENT_BUFFER;
- }
- if (*needed > offered) {
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if (!rpcbuf_alloc_size(buffer, buffer_size))
+ return WERR_NOMEM;
/* fill the buffer with the form structures */
DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
@@ -7209,10 +7246,11 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
enumports level 1.
****************************************************************************/
-static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PORT_INFO_1 *ports=NULL;
int i=0;
+ WERROR result = WERR_OK;
if (*lp_enumports_cmd()) {
char *cmd = lp_enumports_cmd();
@@ -7274,9 +7312,14 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*needed += spoolss_size_port_info_1(&ports[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(ports);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the ports structures */
@@ -7285,24 +7328,24 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
smb_io_port_1("", buffer, &ports[i], 0);
}
+out:
SAFE_FREE(ports);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
enumports level 2.
****************************************************************************/
-static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PORT_INFO_2 *ports=NULL;
int i=0;
+ WERROR result = WERR_OK;
if (*lp_enumports_cmd()) {
char *cmd = lp_enumports_cmd();
@@ -7372,9 +7415,14 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*needed += spoolss_size_port_info_2(&ports[i]);
}
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(ports);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
/* fill the buffer with the ports structures */
@@ -7383,14 +7431,13 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
smb_io_port_2("", buffer, &ports[i], 0);
}
+out:
SAFE_FREE(ports);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -7400,14 +7447,17 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_enumports\n"));
@@ -7543,7 +7593,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
{
- UNISTR2 *uni_srv_name = &q_u->server_name;
+ UNISTR2 *uni_srv_name = q_u->server_name;
uint32 level = q_u->level;
SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
@@ -7741,7 +7791,7 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
/****************************************************************************
****************************************************************************/
-static WERROR 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, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
{
pstring path;
pstring long_archi;
@@ -7749,6 +7799,7 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
char *pservername;
const char *short_archi;
DRIVER_DIRECTORY_1 *info=NULL;
+ WERROR result = WERR_OK;
unistr2_to_ascii(servername, name, sizeof(servername)-1);
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
@@ -7778,19 +7829,22 @@ static WERROR 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 WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
smb_io_driverdir_1("", buffer, info, 0);
+out:
SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -7801,13 +7855,16 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
UNISTR2 *name = &q_u->name;
UNISTR2 *uni_environment = &q_u->environment;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_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;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
@@ -8367,9 +8424,10 @@ done:
enumprintprocessors level 1.
****************************************************************************/
-static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCESSOR_1 *info_1=NULL;
+ WERROR result = WERR_OK;
if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
return WERR_NOMEM;
@@ -8380,19 +8438,25 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
*needed += spoolss_size_printprocessor_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printprocessor_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -8401,14 +8465,17 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_enumprintprocessors\n"));
@@ -8434,9 +8501,10 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
enumprintprocdatatypes level 1.
****************************************************************************/
-static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTPROCDATATYPE_1 *info_1=NULL;
+ WERROR result = WERR_NOMEM;
if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
return WERR_NOMEM;
@@ -8447,19 +8515,25 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
*needed += spoolss_size_printprocdatatype_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -8468,14 +8542,17 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
@@ -8494,9 +8571,10 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
enumprintmonitors level 1.
****************************************************************************/
-static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_1 *info_1=NULL;
+ WERROR result = WERR_OK;
if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL)
return WERR_NOMEM;
@@ -8507,28 +8585,35 @@ static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printmonitor_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
- return WERR_OK;
+ return result;
}
/****************************************************************************
enumprintmonitors level 2.
****************************************************************************/
-static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
{
PRINTMONITOR_2 *info_2=NULL;
+ WERROR result = WERR_OK;
if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL)
return WERR_NOMEM;
@@ -8541,19 +8626,25 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_2(info_2);
- if (!alloc_buffer_size(buffer, *needed))
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
+ }
smb_io_printmonitor_info_2("", buffer, info_2, 0);
+out:
SAFE_FREE(info_2);
- if (*needed > offered) {
- *returned=0;
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- return WERR_OK;
+ if ( !W_ERROR_IS_OK(result) )
+ *returned = 0;
+
+ return result;
}
/****************************************************************************
@@ -8562,14 +8653,17 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
{
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
uint32 *returned = &r_u->returned;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_enumprintmonitors\n"));
@@ -8598,12 +8692,13 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
NT_PRINTER_INFO_LEVEL *ntprinter,
- uint32 jobid, NEW_BUFFER *buffer, uint32 offered,
+ uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
uint32 *needed)
{
int i=0;
BOOL found=False;
JOB_INFO_1 *info_1=NULL;
+ WERROR result = WERR_OK;
info_1=SMB_MALLOC_P(JOB_INFO_1);
@@ -8626,19 +8721,22 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
*needed += spoolss_size_job_info_1(info_1);
- if (!alloc_buffer_size(buffer, *needed)) {
- SAFE_FREE(info_1);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
+ goto out;
}
smb_io_job_info_1("", buffer, info_1, 0);
+out:
SAFE_FREE(info_1);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
-
- return WERR_OK;
+ return result;
}
/****************************************************************************
@@ -8646,36 +8744,31 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
NT_PRINTER_INFO_LEVEL *ntprinter,
- uint32 jobid, NEW_BUFFER *buffer, uint32 offered,
+ uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
uint32 *needed)
{
int i = 0;
BOOL found = False;
JOB_INFO_2 *info_2;
- WERROR ret;
+ WERROR result;
DEVICEMODE *devmode = NULL;
NT_DEVICEMODE *nt_devmode = NULL;
- info_2=SMB_MALLOC_P(JOB_INFO_2);
+ if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
+ return WERR_NOMEM;
ZERO_STRUCTP(info_2);
- if (info_2 == NULL) {
- ret = WERR_NOMEM;
- goto done;
- }
-
for ( i=0; i<count && found==False; i++ )
{
if ((*queue)[i].job == (int)jobid)
found = True;
}
- if ( !found )
- {
+ if ( !found ) {
/* NT treats not found as bad param... yet another bad
choice */
- ret = WERR_INVALID_PARAM;
+ result = WERR_INVALID_PARAM;
goto done;
}
@@ -8698,19 +8791,19 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
*needed += spoolss_size_job_info_2(info_2);
- if (!alloc_buffer_size(buffer, *needed)) {
- ret = WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
goto done;
}
- smb_io_job_info_2("", buffer, info_2, 0);
-
- if (*needed > offered) {
- ret = WERR_INSUFFICIENT_BUFFER;
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_NOMEM;
goto done;
}
- ret = WERR_OK;
+ smb_io_job_info_2("", buffer, info_2, 0);
+
+ result = WERR_OK;
done:
/* Cleanup allocated memory */
@@ -8718,7 +8811,7 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
free_job_info_2(info_2); /* Also frees devmode */
SAFE_FREE(info_2);
- return ret;
+ return result;
}
/****************************************************************************
@@ -8729,7 +8822,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
POLICY_HND *handle = &q_u->handle;
uint32 jobid = q_u->jobid;
uint32 level = q_u->level;
- NEW_BUFFER *buffer = NULL;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
WERROR wstatus = WERR_OK;
@@ -8740,8 +8833,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
print_status_struct prt_status;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("spoolss_getjob\n"));
@@ -9307,13 +9403,14 @@ static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, cha
static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
UNISTR2 *environment,
- NEW_BUFFER *buffer,
+ RPC_BUFFER *buffer,
uint32 offered,
uint32 *needed)
{
pstring path;
pstring long_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+ WERROR result = WERR_OK;
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
@@ -9329,32 +9426,38 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
*needed += spoolss_size_printprocessordirectory_info_1(info);
- if (!alloc_buffer_size(buffer, *needed)) {
- safe_free(info);
- return WERR_INSUFFICIENT_BUFFER;
+ if (*needed > offered) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
+ }
+
+ if (!rpcbuf_alloc_size(buffer, *needed)) {
+ result = WERR_INSUFFICIENT_BUFFER;
+ goto out;
}
smb_io_printprocessordirectory_1("", buffer, info, 0);
- safe_free(info);
+out:
+ SAFE_FREE(info);
- if (*needed > offered)
- return WERR_INSUFFICIENT_BUFFER;
- else
- return WERR_OK;
+ return result;
}
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;
+ RPC_BUFFER *buffer = NULL;
uint32 offered = q_u->offered;
uint32 *needed = &r_u->needed;
WERROR result;
/* that's an [in out] buffer */
- spoolss_move_buffer(q_u->buffer, &r_u->buffer);
- buffer = r_u->buffer;
+
+ if ( q_u->buffer ) {
+ rpcbuf_move(q_u->buffer, &r_u->buffer);
+ buffer = r_u->buffer;
+ }
DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c
index 9d85088e568..0b4eac5cc73 100644
--- a/source/rpc_server/srv_srvsvc.c
+++ b/source/rpc_server/srv_srvsvc.c
@@ -166,6 +166,34 @@ static BOOL api_srv_net_sess_enum(pipes_struct *p)
}
/*******************************************************************
+ Delete session.
+********************************************************************/
+
+static BOOL api_srv_net_sess_del(pipes_struct *p)
+{
+ SRV_Q_NET_SESS_DEL q_u;
+ SRV_R_NET_SESS_DEL 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 net server get enum */
+ if (!srv_io_q_net_sess_del("", &q_u, data, 0))
+ return False;
+
+ /* construct reply. always indicate success */
+ r_u.status = _srv_net_sess_del(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if (!srv_io_r_net_sess_del("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
RPC to enumerate shares.
********************************************************************/
@@ -530,6 +558,7 @@ static struct api_struct api_srv_cmds[] =
{
{ "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum },
{ "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum },
+ { "SRV_NET_SESS_DEL" , SRV_NET_SESS_DEL , api_srv_net_sess_del },
{ "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all },
{ "SRV_NET_SHARE_ENUM" , SRV_NET_SHARE_ENUM , api_srv_net_share_enum },
{ "SRV_NET_SHARE_ADD" , SRV_NET_SHARE_ADD , api_srv_net_share_add },
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index 13e1971925a..b5768a09af0 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -24,6 +24,8 @@
#include "includes.h"
+extern struct generic_mapping file_generic_mapping;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -170,8 +172,6 @@ BOOL share_info_db_init(void)
static SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, int snum, size_t *psize)
{
- extern DOM_SID global_sid_World;
- extern struct generic_mapping file_generic_mapping;
SEC_ACCESS sa;
SEC_ACE ace;
SEC_ACL *psa = NULL;
@@ -293,7 +293,6 @@ static BOOL delete_share_security(int snum)
void map_generic_share_sd_bits(SEC_DESC *psd)
{
- extern struct generic_mapping file_generic_mapping;
int i;
SEC_ACL *ps_dacl = NULL;
@@ -1349,6 +1348,70 @@ WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_S
}
/*******************************************************************
+net sess del
+********************************************************************/
+
+WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u)
+{
+ struct sessionid *session_list;
+ struct current_user user;
+ int num_sessions, snum, ret;
+ fstring username;
+ fstring machine;
+ BOOL not_root = False;
+
+ rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name);
+ rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name);
+
+ /* strip leading backslashes if any */
+ while (machine[0] == '\\') {
+ memmove(machine, &machine[1], strlen(machine));
+ }
+
+ num_sessions = list_sessions(&session_list);
+
+ DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
+
+ r_u->status = WERR_ACCESS_DENIED;
+
+ get_current_user(&user, p);
+
+ /* fail out now if you are not root or not a domain admin */
+
+ if ((user.uid != sec_initial_uid()) &&
+ ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
+
+ goto done;
+ }
+
+ for (snum = 0; snum < num_sessions; snum++) {
+
+ if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) &&
+ strequal(session_list[snum].remote_machine, machine)) {
+
+ if (user.uid != sec_initial_uid()) {
+ not_root = True;
+ become_root();
+ }
+
+ if ((ret = message_send_pid(session_list[snum].pid, MSG_SHUTDOWN, NULL, 0, False)))
+ r_u->status = WERR_OK;
+
+ if (not_root)
+ unbecome_root();
+ }
+ }
+
+ DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
+
+
+done:
+ SAFE_FREE(session_list);
+
+ return r_u->status;
+}
+
+/*******************************************************************
Net share enum all.
********************************************************************/
@@ -1454,7 +1517,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
char *path;
SEC_DESC *psd = NULL;
SE_PRIV se_diskop = SE_DISK_OPERATOR;
- BOOL is_disk_op;
+ BOOL is_disk_op = False;
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
diff --git a/source/rpc_server/srv_svcctl.c b/source/rpc_server/srv_svcctl.c
new file mode 100644
index 00000000000..85fb9f9ce3d
--- /dev/null
+++ b/source/rpc_server/srv_svcctl.c
@@ -0,0 +1,294 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Gerald Carter 2005.
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_close_service(pipes_struct *p)
+{
+ SVCCTL_Q_CLOSE_SERVICE q_u;
+ SVCCTL_R_CLOSE_SERVICE 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(!svcctl_io_q_close_service("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_close_service(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_close_service("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_open_scmanager(pipes_struct *p)
+{
+ SVCCTL_Q_OPEN_SCMANAGER q_u;
+ SVCCTL_R_OPEN_SCMANAGER 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(!svcctl_io_q_open_scmanager("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_open_scmanager(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_open_scmanager("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_open_service(pipes_struct *p)
+{
+ SVCCTL_Q_OPEN_SERVICE q_u;
+ SVCCTL_R_OPEN_SERVICE 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(!svcctl_io_q_open_service("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_open_service(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_open_service("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_get_display_name(pipes_struct *p)
+{
+ SVCCTL_Q_GET_DISPLAY_NAME q_u;
+ SVCCTL_R_GET_DISPLAY_NAME 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(!svcctl_io_q_get_display_name("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_get_display_name(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_get_display_name("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_query_status(pipes_struct *p)
+{
+ SVCCTL_Q_QUERY_STATUS q_u;
+ SVCCTL_R_QUERY_STATUS 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(!svcctl_io_q_query_status("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_query_status(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_query_status("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_enum_services_status(pipes_struct *p)
+{
+ SVCCTL_Q_ENUM_SERVICES_STATUS q_u;
+ SVCCTL_R_ENUM_SERVICES_STATUS 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(!svcctl_io_q_enum_services_status("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_enum_services_status(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_enum_services_status("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_enum_dependent_services(pipes_struct *p)
+{
+ SVCCTL_Q_ENUM_DEPENDENT_SERVICES q_u;
+ SVCCTL_R_ENUM_DEPENDENT_SERVICES 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(!svcctl_io_q_enum_dependent_services("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_enum_dependent_services(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_enum_dependent_services("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_start_service(pipes_struct *p)
+{
+ SVCCTL_Q_START_SERVICE q_u;
+ SVCCTL_R_START_SERVICE 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(!svcctl_io_q_start_service("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_start_service(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_start_service("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_control_service(pipes_struct *p)
+{
+ SVCCTL_Q_CONTROL_SERVICE q_u;
+ SVCCTL_R_CONTROL_SERVICE 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(!svcctl_io_q_control_service("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_control_service(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_control_service("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_query_service_config(pipes_struct *p)
+{
+ SVCCTL_Q_QUERY_SERVICE_CONFIG q_u;
+ SVCCTL_R_QUERY_SERVICE_CONFIG 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(!svcctl_io_q_query_service_config("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_query_service_config(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_query_service_config("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ \PIPE\svcctl commands
+ ********************************************************************/
+
+static struct api_struct api_svcctl_cmds[] =
+{
+ { "SVCCTL_CLOSE_SERVICE" , SVCCTL_CLOSE_SERVICE , api_svcctl_close_service },
+ { "SVCCTL_OPEN_SCMANAGER_W" , SVCCTL_OPEN_SCMANAGER_W , api_svcctl_open_scmanager },
+ { "SVCCTL_OPEN_SERVICE_W" , SVCCTL_OPEN_SERVICE_W , api_svcctl_open_service },
+ { "SVCCTL_GET_DISPLAY_NAME" , SVCCTL_GET_DISPLAY_NAME , api_svcctl_get_display_name },
+ { "SVCCTL_QUERY_STATUS" , SVCCTL_QUERY_STATUS , api_svcctl_query_status },
+ { "SVCCTL_QUERY_SERVICE_CONFIG_W", SVCCTL_QUERY_SERVICE_CONFIG_W, api_svcctl_query_service_config },
+ { "SVCCTL_ENUM_SERVICES_STATUS_W", SVCCTL_ENUM_SERVICES_STATUS_W, api_svcctl_enum_services_status },
+ { "SVCCTL_ENUM_DEPENDENT_SERVICES_W", SVCCTL_ENUM_DEPENDENT_SERVICES_W, api_svcctl_enum_dependent_services },
+ { "SVCCTL_START_SERVICE_W" , SVCCTL_START_SERVICE_W , api_svcctl_start_service },
+ { "SVCCTL_CONTROL_SERVICE" , SVCCTL_CONTROL_SERVICE , api_svcctl_control_service }
+};
+
+void svcctl_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_svcctl_cmds;
+ *n_fns = sizeof(api_svcctl_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_svcctl_init(void)
+{
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "svcctl", "ntsvcs", api_svcctl_cmds,
+ sizeof(api_svcctl_cmds) / sizeof(struct api_struct));
+}
diff --git a/source/rpc_server/srv_svcctl_nt.c b/source/rpc_server/srv_svcctl_nt.c
new file mode 100644
index 00000000000..a76e68a312c
--- /dev/null
+++ b/source/rpc_server/srv_svcctl_nt.c
@@ -0,0 +1,295 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Gerald (Jerry) Carter 2005
+ *
+ * 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 "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*
+ * sertup the \PIPE\svcctl db API
+ */
+
+#define SCVCTL_DATABASE_VERSION_V1 1
+
+/********************************************************************
+********************************************************************/
+
+#if 0 /* unused static function and static variable*/
+
+static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */
+
+static BOOL init_svcctl_db( void )
+{
+ static pid_t local_pid;
+ const char *vstring = "INFO/version";
+
+ /* see if we've already opened the tdb */
+
+ if (svcctl_tdb && local_pid == sys_getpid())
+ return True;
+
+ /* so open it */
+ if ( !(svcctl_tdb = tdb_open_log(lock_path("svcctl.tdb"), 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0600)))
+ {
+ DEBUG(0,("Failed to open svcctl database %s (%s)\n",
+ lock_path("svcctl.tdb"), strerror(errno) ));
+ return False;
+ }
+
+ local_pid = sys_getpid();
+
+ /***** BEGIN Check the tdb version ******/
+
+ tdb_lock_bystring(svcctl_tdb, vstring, 0);
+
+ if ( tdb_fetch_int32(svcctl_tdb, vstring) != SCVCTL_DATABASE_VERSION_V1 )
+ tdb_store_int32(svcctl_tdb, vstring, SCVCTL_DATABASE_VERSION_V1);
+
+ tdb_unlock_bystring(svcctl_tdb, vstring);
+
+ /***** END Check the tdb version ******/
+
+ return True;
+}
+
+#endif
+
+/********************************************************************
+ TODO
+ (a) get and set security descriptors on services
+ (b) read and write QUERY_SERVICE_CONFIG structures
+ (c) create default secdesc objects for services and SCM
+ (d) check access control masks with se_access_check()
+ (e) implement SERVICE * for associating with open handles
+********************************************************************/
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u)
+{
+ /* just fake it for now */
+
+ if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
+ return WERR_ACCESS_DENIED;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u)
+{
+ fstring service;
+
+ rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
+
+ /* can only be called on service name (not displayname) */
+
+ if ( !(strequal( service, "NETLOGON") || strequal(service, "Spooler")) )
+ return WERR_NO_SUCH_SERVICE;
+
+ if ( !create_policy_hnd( p, &r_u->handle, NULL, NULL ) )
+ return WERR_ACCESS_DENIED;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCTL_R_CLOSE_SERVICE *r_u)
+{
+ if ( !close_policy_hnd( p, &q_u->handle ) )
+ return WERR_BADFID;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u)
+{
+ fstring service;
+ fstring displayname;
+
+ rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
+
+ DEBUG(10,("_svcctl_get_display_name: service name [%s]\n", service));
+
+ if ( !strequal( service, "NETLOGON" ) )
+ return WERR_ACCESS_DENIED;
+
+ fstrcpy( displayname, "Net Logon");
+ init_svcctl_r_get_display_name( r_u, displayname );
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u)
+{
+
+ r_u->svc_status.type = 0x0110;
+ r_u->svc_status.state = 0x0004;
+ r_u->svc_status.controls_accepted = 0x0005;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, SVCCTL_R_ENUM_SERVICES_STATUS *r_u)
+{
+ ENUM_SERVICES_STATUS *services = NULL;
+ uint32 num_services = 0;
+ int i = 0;
+ size_t buffer_size;
+ WERROR result = WERR_OK;
+
+ /* num_services = str_list_count( lp_enable_svcctl() ); */
+ num_services = 2;
+
+ if ( !(services = TALLOC_ARRAY( p->mem_ctx, ENUM_SERVICES_STATUS, num_services )) )
+ return WERR_NOMEM;
+
+ DEBUG(8,("_svcctl_enum_services_status: Enumerating %d services\n", num_services));
+
+ init_unistr( &services[i].servicename, "Spooler" );
+ init_unistr( &services[i].displayname, "Spooler" );
+
+ services[i].status.type = 0x110;
+ services[i].status.controls_accepted = 0x0;
+ services[i].status.win32_exit_code = 0x0;
+ services[i].status.service_exit_code = 0x0;
+ services[i].status.check_point = 0x0;
+ services[i].status.wait_hint = 0x0;
+ if ( !lp_disable_spoolss() )
+ services[i].status.state = SVCCTL_RUNNING;
+ else
+ services[i].status.state = SVCCTL_STOPPED;
+
+ i++;
+
+ init_unistr( &services[i].servicename, "Netlogon" );
+ init_unistr( &services[i].displayname, "Net Logon" );
+
+ services[i].status.type = 0x20;
+ services[i].status.controls_accepted = 0x0;
+ services[i].status.win32_exit_code = 0x0;
+ services[i].status.service_exit_code = 0x0;
+ services[i].status.check_point = 0x0;
+ services[i].status.wait_hint = 0x0;
+ if ( lp_servicenumber("NETLOGON") != -1 )
+ services[i].status.state = SVCCTL_RUNNING;
+ else
+ services[i].status.state = SVCCTL_STOPPED;
+
+ buffer_size = 0;
+ for (i=0; i<num_services; i++ )
+ buffer_size += svcctl_sizeof_enum_services_status( &services[i] );
+
+ buffer_size += buffer_size % 4;
+
+ if ( buffer_size > q_u->buffer_size ) {
+ num_services = 0;
+ result = WERR_MORE_DATA;
+ }
+
+ /* we have to set the outgoing buffer size to the same as the
+ incoming buffer size (even in the case of failure */
+
+ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
+
+ if ( W_ERROR_IS_OK(result) ) {
+ for ( i=0; i<num_services; i++ )
+ svcctl_io_enum_services_status( "", &services[i], &r_u->buffer, 0 );
+ }
+
+ r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
+ r_u->returned = num_services;
+
+ if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
+ return WERR_NOMEM;
+
+ *r_u->resume = 0x0;
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u)
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u)
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u )
+{
+
+ /* we have to set the outgoing buffer size to the same as the
+ incoming buffer size (even in the case of failure */
+
+ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
+
+ r_u->needed = q_u->buffer_size;
+
+ /* no dependent services...basically a stub function */
+ r_u->returned = 0;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u )
+{
+
+ /* we have to set the outgoing buffer size to the same as the
+ incoming buffer size (even in the case of failure */
+
+ r_u->needed = q_u->buffer_size;
+
+ /* no dependent services...basically a stub function */
+
+ return WERR_ACCESS_DENIED;
+}
+
+
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 802e7673a40..79d5d06d23a 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -42,6 +42,7 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+#if 0 /* these aren't used currently but are here if you need them */
/*
* A list of the rids of well known BUILTIN and Domain users
* and groups.
@@ -78,7 +79,7 @@ static const rid_name domain_group_rids[] =
{ DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
{ 0 , NULL }
};
-
+#endif
/*******************************************************************
gets a domain user's groups from their already-calculated NT_USER_TOKEN
diff --git a/source/rpcclient/cmd_reg.c b/source/rpcclient/cmd_reg.c
index 7b9bb9b39e5..fcc18cd9f52 100644
--- a/source/rpcclient/cmd_reg.c
+++ b/source/rpcclient/cmd_reg.c
@@ -57,6 +57,7 @@ static void cmd_reg_enum(struct client_info *info)
POLICY_HND key_pol;
fstring full_keyname;
fstring key_name;
+ uint32 reg_type;
/*
* query key info
@@ -87,6 +88,11 @@ static void cmd_reg_enum(struct client_info *info)
return;
}
+ if (!reg_split_key(full_keyname, &reg_type, key_name)) {
+ fprintf(out_hnd, "Unknown registry hive '%s'\n", key_name);
+ return;
+ }
+
/* open WINREG session. */
res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
@@ -130,7 +136,7 @@ static void cmd_reg_enum(struct client_info *info)
time_t key_mod_time;
/* unknown 1a it */
- res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)
@@ -166,11 +172,11 @@ static void cmd_reg_enum(struct client_info *info)
*/
uint32 val_type;
- BUFFER2 value;
+ REGVAL_BUFFER value;
fstring val_name;
/* unknown 1a it */
- res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)
@@ -314,7 +320,7 @@ static void cmd_reg_query_key(struct client_info *info)
/****************************************************************************
nt registry create value
****************************************************************************/
-static void cmd_reg_create_val(struct client_info *info)
+static void cmd_reg_set_val(struct client_info *info)
{
BOOL res = True;
BOOL res3 = True;
@@ -327,7 +333,7 @@ static void cmd_reg_create_val(struct client_info *info)
fstring val_name;
fstring tmp;
uint32 val_type;
- BUFFER3 value;
+ RPC_DATA_BLOB value;
#if 0
uint32 unk_0;
@@ -337,7 +343,7 @@ static void cmd_reg_create_val(struct client_info *info)
val_name, *val_type) : False;
#endif
- DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli->fd));
+ DEBUG(5, ("cmd_reg_set_val: smb_cli->fd:%d\n", smb_cli->fd));
if (!next_token_nr(NULL, full_keyname, NULL, sizeof(full_keyname)))
{
@@ -377,12 +383,12 @@ static void cmd_reg_create_val(struct client_info *info)
{
case 0x01: /* UNISTR */
{
- init_buffer3_str(&value, tmp, strlen(tmp)+1);
+ init_rpc_blob_str(&value, tmp, strlen(tmp)+1);
break;
}
case 0x03: /* BYTES */
{
- init_buffer3_hex(&value, tmp);
+ init_rpc_blob_hex(&value, tmp);
break;
}
case 0x04: /* DWORD */
@@ -396,7 +402,7 @@ static void cmd_reg_create_val(struct client_info *info)
{
tmp_val = strtol(tmp, (char**)NULL, 10);
}
- init_buffer3_uint32(&value, tmp_val);
+ init_rpc_blob_uint32(&value, tmp_val);
break;
}
default:
@@ -428,7 +434,7 @@ static void cmd_reg_create_val(struct client_info *info)
}
/* create an entry */
- res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
+ res4 = res3 ? do_reg_set_val(smb_cli, &parent_pol,
val_name, val_type, &value) : False;
/* flush the modified key */
@@ -448,12 +454,12 @@ static void cmd_reg_create_val(struct client_info *info)
if (res && res3 && res4)
{
- DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
+ DEBUG(5,("cmd_reg_set_val: query succeeded\n"));
fprintf(out_hnd,"OK\n");
}
else
{
- DEBUG(5,("cmd_reg_create_val: query failed\n"));
+ DEBUG(5,("cmd_reg_set_val: query failed\n"));
}
}
@@ -982,7 +988,7 @@ struct cmd_set reg_commands[] = {
{ "regqueryval", cmd_reg_query_info, "Registry Value Query", "<valname>" },
{ "regquerykey", cmd_reg_query_key, "Registry Key Query", "<keyname>" },
{ "regdeleteval", cmd_reg_delete_val, "Registry Value Delete", "<valname>" },
- { "regcreateval", cmd_reg_create_val, "Registry Key Create", "<valname> <valtype> <value>" },
+ { "regsetval", cmd_reg_set_val, "Registry Key Create", "<valname> <valtype> <value>" },
{ "reggetsec", cmd_reg_get_key_sec, "Registry Key Security", "<keyname>" },
{ "regtestsec", cmd_reg_test_key_sec, "Test Registry Key Security", "<keyname>" },
#endif
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index d3f89540502..53019dc1b23 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -568,25 +568,39 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 user_rid, num_aliases, *alias_rids;
+ DOM_SID *sids;
+ int num_sids;
+ uint32 num_aliases, *alias_rids;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
int i;
fstring server;
- DOM_SID tmp_sid;
- DOM_SID2 sid;
- DOM_SID global_sid_Builtin;
+ DOM_SID2 *sid2;
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
+ if (argc < 3) {
+ printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if ((argc < 3) || (argc > 4)) {
- printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
- return NT_STATUS_OK;
+ sids = NULL;
+ num_sids = 0;
+
+ for (i=2; i<argc; i++) {
+ DOM_SID tmp_sid;
+ if (!string_to_sid(&tmp_sid, argv[i])) {
+ printf("%s is not a legal SID\n", argv[i]);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids);
}
- sscanf(argv[2], "%i", &user_rid);
-
- if (argc > 3)
- sscanf(argv[3], "%x", &access_mask);
+ sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+ if (sid2 == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_sids; i++) {
+ sid_copy(&sid2[i].sid, &sids[i]);
+ sid2[i].num_auths = sid2[i].sid.num_auths;
+ }
slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper_m(server);
@@ -604,18 +618,19 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
else if (StrCaseCmp(argv[1], "builtin")==0)
result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
- &global_sid_Builtin, &domain_pol);
- else
- return NT_STATUS_OK;
+ &global_sid_Builtin,
+ &domain_pol);
+ else {
+ printf("Usage: %s builtin|domain sid1 sid2 ...\n", argv[0]);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
if (!NT_STATUS_IS_OK(result))
goto done;
- sid_copy(&tmp_sid, &domain_sid);
- sid_append_rid(&tmp_sid, user_rid);
- init_dom_sid2(&sid, &tmp_sid);
-
- result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol, 1, &sid, &num_aliases, &alias_rids);
+ result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
+ num_sids, sid2,
+ &num_aliases, &alias_rids);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -851,11 +866,8 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
uint32 start_idx, size, num_als_groups, i;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
struct acct_info *als_groups;
- DOM_SID global_sid_Builtin;
BOOL got_connect_pol = False, got_domain_pol = False;
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
if ((argc < 2) || (argc > 3)) {
printf("Usage: %s builtin|domain [access mask]\n", argv[0]);
return NT_STATUS_OK;
@@ -933,9 +945,6 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
uint32 alias_rid, num_members, i;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
DOM_SID *alias_sids;
- DOM_SID global_sid_Builtin;
-
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
if ((argc < 3) || (argc > 4)) {
printf("Usage: %s builtin|domain rid [access mask]\n", argv[0]);
@@ -1261,6 +1270,15 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
+ result = cli_samr_close(cli, mem_ctx, &user_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
+ result = cli_samr_close(cli, mem_ctx, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
+ result = cli_samr_close(cli, mem_ctx, &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
done:
return result;
}
@@ -1312,6 +1330,15 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
+ result = cli_samr_close(cli, mem_ctx, &group_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
+ result = cli_samr_close(cli, mem_ctx, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
+ result = cli_samr_close(cli, mem_ctx, &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) goto done;
+
done:
return result;
}
@@ -1328,9 +1355,6 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
uint32 num_rids, num_names, *name_types, *rids;
const char **names;
int i;
- DOM_SID global_sid_Builtin;
-
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
if (argc < 3) {
printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]);
diff --git a/source/rpcclient/cmd_shutdown.c b/source/rpcclient/cmd_shutdown.c
index e42ec30ac13..b0b92949c2a 100644
--- a/source/rpcclient/cmd_shutdown.c
+++ b/source/rpcclient/cmd_shutdown.c
@@ -24,6 +24,9 @@
#include "includes.h"
#include "rpcclient.h"
+#if 0 /* don't uncomment this unless you remove the getopt() calls */
+ /* use net rpc shutdown instead */
+
/****************************************************************************
nt shutdown init
****************************************************************************/
@@ -96,6 +99,7 @@ static NTSTATUS cmd_shutdown_abort(struct cli_state *cli,
return result;
}
+#endif
/* List of commands exported by this module */
@@ -103,10 +107,12 @@ struct cmd_set shutdown_commands[] = {
{ "SHUTDOWN" },
+#if 0
{ "shutdowninit", RPC_RTYPE_NTSTATUS, cmd_shutdown_init, NULL, PI_SHUTDOWN, "Remote Shutdown (over shutdown pipe)",
"syntax: shutdown [-m message] [-t timeout] [-r] [-h] [-f] (-r == reboot, -h == halt, -f == force)" },
{ "shutdownabort", RPC_RTYPE_NTSTATUS, cmd_shutdown_abort, NULL, PI_SHUTDOWN, "Abort Shutdown (over shutdown pipe)",
"syntax: shutdownabort" },
+#endif
{ NULL }
};
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 49f22b36546..ec9d3048822 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -1283,7 +1283,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
wrapper for strtok to get the next parameter from a delimited list.
Needed to handle the empty parameter string denoted by "NULL"
*************************************************************************/
-static char* get_driver_3_param (const char* str, const char* delim, UNISTR* dest)
+static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest)
{
char *ptr;
@@ -1310,11 +1310,8 @@ static char* get_driver_3_param (const char* str, const char* delim, UNISTR* des
<Config File Name>:<Help File Name>:<Language Monitor Name>:\
<Default Data Type>:<Comma Separated list of Files>
*******************************************************************************/
-static BOOL init_drv_info_3_members (
- TALLOC_CTX *mem_ctx,
- DRIVER_INFO_3 *info,
- const char *args
-)
+static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
+ char *args )
{
char *str, *str2;
uint32 len, i;
@@ -1370,6 +1367,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
DRIVER_INFO_3 info3;
const char *arch;
fstring driver_name;
+ char *driver_args;
/* parse the command arguements */
if (argc != 3 && argc != 4)
@@ -1393,7 +1391,8 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
else
set_drv_info_3_env(&info3, arch);
- if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
+ driver_args = talloc_strdup( mem_ctx, argv[2] );
+ if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
{
printf ("Error Invalid parameter list - %s.\n", argv[2]);
return WERR_INVALID_PARAM;
@@ -1813,6 +1812,38 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return werror;
}
+static const char *get_form_flag(int form_flag)
+{
+ switch (form_flag) {
+ case FORM_USER:
+ return "FORM_USER";
+ case FORM_BUILTIN:
+ return "FORM_BUILTIN";
+ case FORM_PRINTER:
+ return "FORM_PRINTER";
+ default:
+ return "unknown";
+ }
+}
+
+static void display_form(FORM_1 *form)
+{
+ fstring form_name = "";
+
+ if (form->name.buffer)
+ rpcstr_pull(form_name, form->name.buffer,
+ sizeof(form_name), -1, STR_TERMINATE);
+
+ printf("%s\n" \
+ "\tflag: %s (%d)\n" \
+ "\twidth: %d, length: %d\n" \
+ "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
+ form_name, get_form_flag(form->flag), form->flag,
+ form->width, form->length,
+ form->left, form->right,
+ form->top, form->bottom);
+}
+
/* Get a form */
static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -1847,7 +1878,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
got_handle = True;
- /* Set the form */
+ /* Get the form */
werror = cli_spoolss_getform(cli, mem_ctx, 0, &needed,
&handle, argv[2], 1, &form);
@@ -1859,12 +1890,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!W_ERROR_IS_OK(werror))
goto done;
- printf("width: %d\n", form.width);
- printf("length: %d\n", form.length);
- printf("left: %d\n", form.left);
- printf("top: %d\n", form.top);
- printf("right: %d\n", form.right);
- printf("bottom: %d\n", form.bottom);
+ display_form(&form);
done:
if (got_handle)
@@ -1925,20 +1951,6 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
/* Enumerate forms */
-static const char *get_form_flag(int form_flag)
-{
- switch (form_flag) {
- case FORM_USER:
- return "FORM_USER";
- case FORM_BUILTIN:
- return "FORM_BUILTIN";
- case FORM_PRINTER:
- return "FORM_PRINTER";
- default:
- return "unknown";
- }
-}
-
static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
@@ -1988,20 +2000,9 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
/* Display output */
for (i = 0; i < num_forms; i++) {
- fstring form_name;
-
- if (forms[i].name.buffer)
- rpcstr_pull(form_name, forms[i].name.buffer,
- sizeof(form_name), -1, STR_TERMINATE);
-
- printf("%s\n" \
- "\tflag: %s (%d)\n" \
- "\twidth: %d, length: %d\n" \
- "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
- form_name, get_form_flag(forms[i].flag), forms[i].flag,
- forms[i].width, forms[i].length,
- forms[i].left, forms[i].right,
- forms[i].top, forms[i].bottom);
+
+ display_form(&forms[i]);
+
}
done:
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index acb65b7f7ce..c02a279db9e 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -24,7 +24,6 @@
#include "rpcclient.h"
DOM_SID domain_sid;
-static int pipe_idx;
/* List to hold groups of commands.
@@ -559,7 +558,6 @@ static NTSTATUS do_cmd(struct cli_state *cli,
/* Run command */
- pipe_idx = cmd_entry->pipe_idx;
if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
ntresult = cmd_entry->ntfn(cli, mem_ctx, argc, (const char **) argv);
if (!NT_STATUS_IS_OK(ntresult)) {
diff --git a/source/sam/idmap_util.c b/source/sam/idmap_util.c
index f28e11cde74..41689f413b9 100644
--- a/source/sam/idmap_util.c
+++ b/source/sam/idmap_util.c
@@ -190,106 +190,3 @@ NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags)
return ret;
}
-
-
-/***************************************************************************
- Check first, call set_mapping if it doesn't already exist.
-***************************************************************************/
-
-static NTSTATUS wellknown_id_init(DOM_SID *sid, unid_t id, int flags)
-{
- unid_t storedid;
- int qflags = flags | ID_QUERY_ONLY;
-
- if (!NT_STATUS_IS_OK(idmap_get_id_from_sid(&storedid, &qflags, sid))) {
- return idmap_set_mapping(sid, id, flags);
- } else {
- if (flags == ID_USERID && id.uid != storedid.uid) {
- DEBUG(0,("wellknown_id_init: WARNING ! Stored uid %u for SID %s is not the same as the requested uid %u\n",
- (unsigned int)storedid.uid, sid_string_static(sid), (unsigned int)id.uid ));
- DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
- return idmap_set_mapping(sid, id, flags);
- } else if (flags == ID_GROUPID && id.gid != storedid.gid) {
- DEBUG(0,("wellknown_id_init: WARNING ! Stored gid %u for SID %s is not the same as the requested gid %u\n",
- (unsigned int)storedid.gid, sid_string_static(sid), (unsigned int)id.gid ));
- DEBUG(0,("wellknown_id_init: Attempting to overwrite old mapping with new.\n"));
- return idmap_set_mapping(sid, id, flags);
- }
- }
- return NT_STATUS_OK;
-}
-
-/***************************************************************************
- Initialize idmap withWellknown SIDs like Guest, that are necessary
- to make samba run properly.
-***************************************************************************/
-
-BOOL idmap_init_wellknown_sids(void)
-{
- const char *guest_account = lp_guestaccount();
- struct passwd *pass;
- GROUP_MAP *map=NULL;
- int num_entries=0;
- DOM_SID sid;
- unid_t id;
- fstring sid_string;
-
- if (!(guest_account && *guest_account)) {
- DEBUG(1, ("NULL guest account!?!?\n"));
- return False;
- }
-
- pass = getpwnam_alloc(guest_account);
- if (!pass) {
- return False;
- }
-
- /* Fill in the SID for the guest account. */
- id.uid = pass->pw_uid;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_USER_RID_GUEST);
-
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
- DEBUG(0, ("Failed to setup UID mapping for GUEST (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.uid));
- passwd_free(&pass);
- return False;
- }
-
- /* check if DOMAIN_GROUP_RID_GUESTS SID is set, if not store the
- * guest account gid as mapping */
- id.gid = pass->pw_gid;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_GROUP_RID_GUESTS);
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_GROUPID))) {
- DEBUG(0, ("Failed to setup GID mapping for Group DOMAIN GUESTS (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.gid));
- passwd_free(&pass);
- return False;
- }
-
- passwd_free(&pass);
- /* now fill in group mappings */
- if(pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) {
- int i;
-
- for (i = 0; i < num_entries; i++) {
- id.gid = map[i].gid;
- wellknown_id_init(&map[i].sid, id, ID_GROUPID);
- }
- SAFE_FREE(map);
- }
-
- /* Fill in the SID for the administrator account. */
- id.uid = 0;
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, DOMAIN_USER_RID_ADMIN);
-
- if (!NT_STATUS_IS_OK(wellknown_id_init(&sid, id, ID_USERID))) {
- DEBUG(0, ("Failed to setup UID mapping for ADMINISTRATOR (%s) to (%u)\n",
- sid_to_string(sid_string, &sid), (unsigned int)id.uid));
- return False;
- }
-
- return True;
-}
diff --git a/source/script/installman.sh b/source/script/installman.sh
index c7a8f450951..d30429d50a0 100755
--- a/source/script/installman.sh
+++ b/source/script/installman.sh
@@ -15,7 +15,7 @@ fi
for lang in $langs; do
- if [ "X$lang" = Xen ]; then
+ if [ "X$lang" = XC ]; then
echo Installing default man pages in $MANDIR/
lang=.
else
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 540acfc2250..d0e0f6e143a 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -747,8 +747,8 @@ static NTSTATUS check_oem_password(const char *user,
static uchar null_pw[16];
static uchar null_ntpw[16];
SAM_ACCOUNT *sampass = NULL;
- char *password_encrypted;
- const char *encryption_key;
+ uint8 *password_encrypted;
+ const uint8 *encryption_key;
const uint8 *lanman_pw, *nt_pw;
uint16 acct_ctrl;
uint32 new_pw_len;
@@ -943,7 +943,8 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext)
const uint8 *nt_pw;
const uint8 *pwhistory;
BOOL found = False;
- int i, pwHisLen, curr_pwHisLen;
+ int i;
+ uint32 pwHisLen, curr_pwHisLen;
account_policy_get(AP_PASSWORD_HISTORY, &pwHisLen);
if (pwHisLen == 0) {
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 309f4adf478..0f32dddd2d7 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -24,6 +24,8 @@
This module implements directory related functions for Samba.
*/
+extern struct current_user current_user;
+
/* Make directory handle internals available. */
#define NAME_CACHE_SIZE 100
@@ -697,7 +699,7 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype)
static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
{
mangle_map(filename,True,False,SNUM(conn));
- return mask_match(filename,mask,False);
+ return mask_match_search(filename,mask,False);
}
/****************************************************************************
@@ -712,16 +714,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
SMB_STRUCT_STAT sbuf;
pstring path;
pstring pathreal;
- BOOL isrootdir;
pstring filename;
BOOL needslash;
*path = *pathreal = *filename = 0;
- isrootdir = (strequal(conn->dirpath,"./") ||
- strequal(conn->dirpath,".") ||
- strequal(conn->dirpath,"/"));
-
needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
if (!conn->dirptr)
@@ -744,10 +741,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
see masktest for a demo
*/
if ((strcmp(mask,"*.*") == 0) ||
- mask_match(filename,mask,False) ||
+ mask_match_search(filename,mask,False) ||
mangle_mask_match(conn,filename,mask)) {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
if (!mangle_is_8_3(filename, False))
mangle_map(filename,True,False,SNUM(conn));
@@ -792,7 +787,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
{
- extern struct current_user current_user;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
@@ -845,7 +839,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
{
- extern struct current_user current_user;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index ff00b5dc6b1..3a0e81e5fef 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -431,7 +431,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
than POSIX.
*******************************************************************/
-int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
+int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times)
{
int ret = -1;
@@ -467,7 +467,7 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
Change a filetime - possibly allowing DOS semantics.
*******************************************************************/
-BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
+BOOL set_filetime(connection_struct *conn, const char *fname, time_t mtime)
{
struct utimbuf times;
diff --git a/source/smbd/error.c b/source/smbd/error.c
index d611e0ef873..090a2f6d813 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -20,23 +20,44 @@
#include "includes.h"
-/* these can be set by some functions to override the error codes */
-int unix_ERR_class=SMB_SUCCESS;
-int unix_ERR_code=0;
-NTSTATUS unix_ERR_ntstatus = NT_STATUS_OK;
-
/* From lib/error.c */
extern struct unix_error_map unix_dos_nt_errmap[];
+extern uint32 global_client_caps;
+/* these can be set by some functions to override the error codes */
+static int override_ERR_class;
+static int override_ERR_code;
+static NTSTATUS override_ERR_ntstatus;
+
/****************************************************************************
- Ensure we don't have any errors cached.
+ Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors.
+ Setting status only and eclass and ecode to -1 forces NT errors.
****************************************************************************/
-void clear_cached_errors(void)
+void set_saved_error_triple(int eclass, int ecode, NTSTATUS status)
+{
+ override_ERR_class = eclass;
+ override_ERR_code = ecode;
+ override_ERR_ntstatus = status;
+}
+
+/****************************************************************************
+ Return the current settings of the error triple. Return True if any are set.
+****************************************************************************/
+
+BOOL get_saved_error_triple(int *peclass, int *pecode, NTSTATUS *pstatus)
{
- unix_ERR_class = SMB_SUCCESS;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
+ if (peclass) {
+ *peclass = override_ERR_class;
+ }
+ if (pecode) {
+ *pecode = override_ERR_code;
+ }
+ if (pstatus) {
+ *pstatus = override_ERR_ntstatus;
+ }
+
+ return (override_ERR_class || !NT_STATUS_IS_OK(override_ERR_ntstatus));
}
/****************************************************************************
@@ -46,36 +67,29 @@ void clear_cached_errors(void)
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;
+ NTSTATUS ntstatus = wbmpx->wr_status;
/* We can now delete the auxiliary struct */
- free((char *)wbmpx);
- fsp->wbmpx_ptr = NULL;
- return error_packet(outbuf,NT_STATUS_OK,eclass,err,False,line,file);
+ SAFE_FREE(fsp->wbmpx_ptr);
+ return error_packet(outbuf,eclass,err,ntstatus,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, NTSTATUS def_status, int line, const char *file)
{
int eclass=def_class;
int ecode=def_code;
- NTSTATUS ntstatus = NT_STATUS_OK;
+ NTSTATUS ntstatus = def_status;
int i=0;
- if (unix_ERR_class != SMB_SUCCESS) {
- eclass = unix_ERR_class;
- ecode = unix_ERR_code;
- ntstatus = unix_ERR_ntstatus;
- unix_ERR_class = SMB_SUCCESS;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
- } else {
+ if (errno != 0) {
+ DEBUG(3,("unix_error_packet: error string = %s\n",strerror(errno)));
+
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;
@@ -87,39 +101,43 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code,
}
}
- return error_packet(outbuf,ntstatus,eclass,ecode,False,line,file);
+ return error_packet(outbuf,eclass,ecode,ntstatus,line,file);
}
/****************************************************************************
Create an error packet. Normally called using the ERROR() macro.
+ Setting eclass and ecode only and status to NT_STATUS_OK forces DOS errors.
+ Setting status only and eclass and ecode to zero forces NT errors.
+ If the override errors are set they take precedence over any passed in values.
****************************************************************************/
-int error_packet(char *outbuf,NTSTATUS ntstatus,
- uint8 eclass,uint32 ecode,BOOL force_dos, int line, const char *file)
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
{
int outsize = set_message(outbuf,0,0,True);
- extern uint32 global_client_caps;
+ BOOL force_nt_status = False;
+ BOOL force_dos_status = False;
+
+ if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) {
+ eclass = override_ERR_class;
+ ecode = override_ERR_code;
+ ntstatus = override_ERR_ntstatus;
+ override_ERR_class = SMB_SUCCESS;
+ override_ERR_code = 0;
+ override_ERR_ntstatus = NT_STATUS_OK;
+ }
- if (errno != 0)
- DEBUG(3,("error string = %s\n",strerror(errno)));
-
-#if defined(DEVELOPER)
- if (unix_ERR_class != SMB_SUCCESS || unix_ERR_code != 0 || !NT_STATUS_IS_OK(unix_ERR_ntstatus))
- smb_panic("logic error in error processing");
-#endif
-
- /*
- * We can explicitly force 32 bit error codes even when the
- * parameter "nt status" is set to no by pre-setting the
- * FLAGS2_32_BIT_ERROR_CODES bit in the smb_flg2 outbuf.
- * This is to allow work arounds for client bugs that are needed
- * when talking with clients that normally expect nt status codes. JRA.
- */
-
- if ((lp_nt_status_support() || (SVAL(outbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) && (global_client_caps & CAP_STATUS32) && (!force_dos)) {
- if (NT_STATUS_V(ntstatus) == 0 && eclass)
+ if (eclass == (uint8)-1) {
+ force_nt_status = True;
+ } else if (NT_STATUS_IS_INVALID(ntstatus)) {
+ force_dos_status = True;
+ }
+
+ if (force_nt_status || (!force_dos_status && lp_nt_status_support() && (global_client_caps & CAP_STATUS32))) {
+ /* We're returning an NT error. */
+ 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",
@@ -127,22 +145,23 @@ int error_packet(char *outbuf,NTSTATUS ntstatus,
(int)CVAL(outbuf,smb_com),
smb_fn_name(CVAL(outbuf,smb_com)),
nt_errstr(ntstatus)));
- return outsize;
- }
-
- if (eclass == 0 && NT_STATUS_V(ntstatus))
- ntstatus_to_dos(ntstatus, &eclass, &ecode);
-
- 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));
+ } else {
+ /* We're returning a DOS error only. */
+ if (eclass == 0 && NT_STATUS_V(ntstatus)) {
+ ntstatus_to_dos(ntstatus, &eclass, &ecode);
+ }
+
+ 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/fake_file.c b/source/smbd/fake_file.c
index 53aac1e0364..ee510eb003f 100644
--- a/source/smbd/fake_file.c
+++ b/source/smbd/fake_file.c
@@ -20,6 +20,8 @@
#include "includes.h"
+extern struct current_user current_user;
+
/****************************************************************************
Open a file with a share mode.
****************************************************************************/
@@ -29,7 +31,6 @@ files_struct *open_fake_file_shared1(enum FAKE_FILE_TYPE fake_file_type, connect
int share_mode,int ofun, uint32 new_dos_attr, int oplock_request,
int *Access,int *action)
{
- extern struct current_user current_user;
int flags=0;
files_struct *fsp = NULL;
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index 8c484dd232a..9ca2c0efae9 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -397,7 +397,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
a valid one for the user to access.
****************************************************************************/
-BOOL check_name(pstring name,connection_struct *conn)
+BOOL check_name(const pstring name,connection_struct *conn)
{
BOOL ret = True;
diff --git a/source/smbd/files.c b/source/smbd/files.c
index 143c1196937..e893e9fefc1 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -95,15 +95,13 @@ files_struct *file_new(connection_struct *conn)
}
DEBUG(0,("ERROR! Out of file structures\n"));
- unix_ERR_class = ERRSRV;
- unix_ERR_code = ERRnofids;
+ set_saved_error_triple(ERRSRV, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES);
return NULL;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
- unix_ERR_class = ERRSRV;
- unix_ERR_code = ERRnofids;
+ set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
return NULL;
}
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index d8c5201ce67..127480f0b3d 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -27,6 +27,9 @@
#include "includes.h"
+extern struct current_user current_user;
+extern userdom_struct current_user_info;
+
#ifdef CHECK_TYPES
#undef CHECK_TYPES
#endif
@@ -1652,9 +1655,10 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
char *str1 = param+2;
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
- BOOL ret;
- GROUP_MAP *group_list;
+ struct pdb_search *search;
+ struct samr_displayentry *entries;
+
int num_entries;
if (strcmp(str1,"WrLeh") != 0)
@@ -1672,30 +1676,39 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
/* get list of domain groups SID_DOMAIN_GRP=2 */
become_root();
- ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False);
+ search = pdb_search_groups();
unbecome_root();
-
- if( !ret ) {
- DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
+
+ if (search == NULL) {
+ DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
return False;
}
resume_context = SVAL(p,0);
cli_buf_size=SVAL(p+2,0);
- DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: %d\n", resume_context, cli_buf_size));
+ DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
+ "%d\n", resume_context, cli_buf_size));
+
+ become_root();
+ num_entries = pdb_search_entries(search, resume_context, 0xffffffff,
+ &entries);
+ unbecome_root();
*rdata_len = cli_buf_size;
*rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
p = *rdata;
- for(i=resume_context; i<num_entries; i++) {
- char* name=group_list[i].nt_name;
+ for(i=0; i<num_entries; i++) {
+ fstring name;
+ fstrcpy(name, entries[i].account_name);
if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
/* truncate the name at 21 chars. */
memcpy(p, name, 21);
DEBUG(10,("adding entry %d group %s\n", i, p));
- p += 21;
+ p += 21;
+ p += 5; /* Both NT4 and W2k3SP1 do padding here.
+ No idea why... */
} else {
/* set overflow error */
DEBUG(3,("overflow on entry %d group %s\n", i, name));
@@ -1704,6 +1717,8 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
}
}
+ pdb_search_destroy(search);
+
*rdata_len = PTR_DIFF(p,*rdata);
*rparam_len = 8;
@@ -1711,8 +1726,8 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
SSVAL(*rparam, 0, errflags);
SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam, 4, i-resume_context); /* is this right?? */
- SSVAL(*rparam, 6, num_entries); /* is this right?? */
+ SSVAL(*rparam, 4, i); /* is this right?? */
+ SSVAL(*rparam, 6, resume_context+num_entries); /* is this right?? */
return(True);
}
@@ -1831,11 +1846,12 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- SAM_ACCOUNT *pwd=NULL;
int count_sent=0;
- int count_total=0;
+ int num_users=0;
int errflags=0;
- int resume_context, cli_buf_size;
+ int i, resume_context, cli_buf_size;
+ struct pdb_search *search;
+ struct samr_displayentry *users;
char *str1 = param+2;
char *str2 = skip_string(str1,1);
@@ -1867,49 +1883,47 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
p = *rdata;
- /* to get user list enumerations for NetUserEnum in B21 format */
- pdb_init_sam(&pwd);
-
- /* Open the passgrp file - not for update. */
become_root();
- if(!pdb_setsampwent(False, 0)) {
+ search = pdb_search_users(ACB_NORMAL);
+ unbecome_root();
+ if (search == NULL) {
DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
- unbecome_root();
return False;
}
- errflags=NERR_Success;
- while ( pdb_getsampwent(pwd) ) {
- const char *name=pdb_get_username(pwd);
- if ((name) && (*(name+strlen(name)-1)!='$')) {
- count_total++;
- if(count_total>=resume_context) {
- if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21) ) {
- pstrcpy(p,name);
- DEBUG(10,("api_RNetUserEnum:adding entry %d username %s\n",count_sent,p));
- p += 21;
- count_sent++;
- } else {
- /* set overflow error */
- DEBUG(10,("api_RNetUserEnum:overflow on entry %d username %s\n",count_sent,name));
- errflags=234;
- break;
- }
- }
- }
- } ;
-
- pdb_endsampwent();
+ become_root();
+ num_users = pdb_search_entries(search, resume_context, 0xffffffff,
+ &users);
unbecome_root();
- pdb_free_sam(&pwd);
+ errflags=NERR_Success;
+
+ for (i=0; i<num_users; i++) {
+ const char *name = users[i].account_name;
+
+ if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
+ pstrcpy(p,name);
+ DEBUG(10,("api_RNetUserEnum:adding entry %d username "
+ "%s\n",count_sent,p));
+ p += 21;
+ count_sent++;
+ } else {
+ /* set overflow error */
+ DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
+ "username %s\n",count_sent,name));
+ errflags=234;
+ break;
+ }
+ }
+
+ pdb_search_destroy(search);
*rdata_len = PTR_DIFF(p,*rdata);
SSVAL(*rparam,0,errflags);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,count_sent); /* is this right?? */
- SSVAL(*rparam,6,count_total); /* is this right?? */
+ SSVAL(*rparam,6,num_users); /* is this right?? */
return True;
}
@@ -2116,7 +2130,6 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
int snum;
fstring sharename;
int errcode;
- extern struct current_user current_user;
WERROR werr = WERR_OK;
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
@@ -2183,7 +2196,6 @@ static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid, char *param
int errcode = NERR_notsupported;
int snum;
WERROR werr = WERR_OK;
- extern struct current_user current_user;
/* check it's a supported varient */
if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
@@ -2435,7 +2447,6 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
char *p2;
- extern userdom_struct current_user_info;
int level = SVAL(p,0);
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c
index 184dde16354..b61a3280808 100644
--- a/source/smbd/msdfs.c
+++ b/source/smbd/msdfs.c
@@ -64,7 +64,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename));
/* rest is reqpath */
- check_path_syntax(pdp->reqpath, p+1,True);
+ check_path_syntax(pdp->reqpath, p+1);
DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath));
return True;
@@ -75,7 +75,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
into the dfs_path structure
**********************************************************************/
-static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
+static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp, BOOL allow_wcards)
{
pstring pathname_local;
char* p,*temp;
@@ -110,7 +110,11 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename));
/* rest is reqpath */
- check_path_syntax(pdp->reqpath, p+1,True);
+ if (allow_wcards) {
+ check_path_syntax_wcard(pdp->reqpath, p+1);
+ } else {
+ check_path_syntax(pdp->reqpath, p+1);
+ }
DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath));
return True;
@@ -278,8 +282,7 @@ should try the remaining path on the redirected server.
*****************************************************************/
static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
- connection_struct* conn,
- BOOL findfirst_flag,
+ connection_struct* conn, BOOL search_flag,
struct referral** reflistpp, int* refcntp,
BOOL* self_referralp, int* consumedcntp)
{
@@ -311,18 +314,17 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
/* check if need to redirect */
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
- if (findfirst_flag) {
+ if ( search_flag ) {
DEBUG(6,("resolve_dfs_path (FindFirst) No redirection "
"for dfs link %s.\n", dfspath));
return False;
- } else {
- DEBUG(6,("resolve_dfs_path: %s resolves to a valid Dfs link.\n",
- dfspath));
- if (consumedcntp)
- *consumedcntp = strlen(dfspath);
- return True;
}
- }
+
+ DEBUG(6,("resolve_dfs_path: %s resolves to a valid Dfs link.\n", dfspath));
+ if (consumedcntp)
+ *consumedcntp = strlen(dfspath);
+ return True;
+ }
/* redirect if any component in the path is a link */
pstrcpy(reqpath, dp->reqpath);
@@ -331,6 +333,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
*p = '\0';
pstrcpy(localpath, reqpath);
if (is_msdfs_link(conn, localpath, reflistpp, refcntp, NULL)) {
+
DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath));
/* To find the path consumed, we truncate the original
@@ -338,6 +341,7 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
component. The length of the resulting string is
the path consumed
*/
+
if (consumedcntp) {
char *q;
pstring buf;
@@ -364,17 +368,20 @@ static BOOL resolve_dfs_path(pstring dfspath, struct dfs_path* dp,
/*****************************************************************
Decides if a dfs pathname should be redirected or not.
If not, the pathname is converted to a tcon-relative local unix path
+
+ search_wcard_flag: this flag performs 2 functions bother related
+ to searches. See resolve_dfs_path() and parse_processed_dfs_path()
+ for details.
*****************************************************************/
-BOOL dfs_redirect(pstring pathname, connection_struct* conn,
- BOOL findfirst_flag)
+BOOL dfs_redirect( pstring pathname, connection_struct* conn, BOOL search_wcard_flag )
{
struct dfs_path dp;
if (!conn || !pathname)
return False;
- parse_processed_dfs_path(pathname, &dp);
+ parse_processed_dfs_path(pathname, &dp, search_wcard_flag);
/* if dfs pathname for a non-dfs share, convert to tcon-relative
path and return false */
@@ -386,7 +393,7 @@ BOOL dfs_redirect(pstring pathname, connection_struct* conn,
if (!strequal(dp.servicename, lp_servicename(SNUM(conn)) ))
return False;
- if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag,
+ if (resolve_dfs_path(pathname, &dp, conn, search_wcard_flag,
NULL, NULL, NULL, NULL)) {
DEBUG(3,("dfs_redirect: Redirecting %s\n", pathname));
return True;
@@ -802,6 +809,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
/**********************************************************************
Creates a junction structure from a Dfs pathname
**********************************************************************/
+
BOOL create_junction(char* pathname, struct junction_map* jucn)
{
struct dfs_path dp;
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 9aaa818c62a..054afac683d 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -20,6 +20,7 @@
#include "includes.h"
+extern fstring remote_proto;
extern enum protocol_types Protocol;
extern int max_recv;
BOOL global_encrypted_passwords_negotiated = False;
@@ -419,6 +420,7 @@ static const struct {
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
{"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
@@ -548,7 +550,6 @@ int reply_negprot(connection_struct *conn,
SSVAL(outbuf,smb_vwv0,choice);
if(choice != -1) {
- extern fstring remote_proto;
fstrcpy(remote_proto,supported_protocols[protocol].short_name);
reload_services(True);
outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c
index 8fcc18a09f9..c368fd79a12 100644
--- a/source/smbd/notify_kernel.c
+++ b/source/smbd/notify_kernel.c
@@ -101,8 +101,9 @@ static BOOL kernel_check_notify(connection_struct *conn, uint16 vuid, char *path
close((int)fd_pending_array[i]);
fd_pending_array[i] = (SIG_ATOMIC_T)-1;
if (signals_received - i - 1) {
- memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
- sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
+ memmove(CONST_DISCARD(void *, &fd_pending_array[i]),
+ CONST_DISCARD(void *, &fd_pending_array[i+1]),
+ sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
}
data->directory_handle = -1;
signals_received--;
@@ -129,8 +130,9 @@ static void kernel_remove_notify(void *datap)
if (fd == (int)fd_pending_array[i]) {
fd_pending_array[i] = (SIG_ATOMIC_T)-1;
if (signals_received - i - 1) {
- memmove((void *)&fd_pending_array[i], (void *)&fd_pending_array[i+1],
- sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
+ memmove(CONST_DISCARD(void *, &fd_pending_array[i]),
+ CONST_DISCARD(void *, &fd_pending_array[i+1]),
+ sizeof(SIG_ATOMIC_T)*(signals_received-i-1));
}
data->directory_handle = -1;
signals_received--;
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index fbb73640901..a3ffaad24ac 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -21,6 +21,7 @@
#include "includes.h"
+extern int max_send;
extern enum protocol_types Protocol;
extern int smb_read_error;
extern int global_oplock_break;
@@ -40,6 +41,8 @@ static const char *known_nt_pipes[] = {
"\\spoolss",
"\\netdfs",
"\\rpcecho",
+ "\\svcctl",
+ "\\eventlog",
NULL
};
@@ -81,7 +84,6 @@ static char *nttrans_realloc(char **ptr, size_t size)
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;
int params_to_send = paramsize;
int useable_space;
@@ -353,6 +355,11 @@ static int map_share_mode( char *fname, uint32 create_options,
int smb_open_mode = -1;
uint32 original_desired_access = *desired_access;
+ /* This is a nasty hack - must fix... JRA. */
+ if (*desired_access == MAXIMUM_ALLOWED_ACCESS) {
+ *desired_access = FILE_GENERIC_ALL;
+ }
+
/*
* Convert GENERIC bits to specific bits.
*/
@@ -581,7 +588,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
- SMB_BIG_UINT allocation_size = 0;
int smb_ofun;
int smb_open_mode;
/* Breakout the oplock request bits so we can set the
@@ -630,7 +636,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
END_PROFILE(SMBntcreateX);
- return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
/*
@@ -883,10 +889,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(conn, file_attributes);
- SSVAL(outbuf, smb_flg2,
- SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
- return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
+ return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
@@ -903,7 +907,6 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
END_PROFILE(SMBntcreateX);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@@ -915,8 +918,9 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
file_len = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
- if(fmode == 0)
+ if(fmode == 0) {
fmode = FILE_ATTRIBUTE_NORMAL;
+ }
if (!fsp->is_directory && (fmode & aDIR)) {
close_file(fsp,False);
END_PROFILE(SMBntcreateX);
@@ -924,25 +928,27 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
}
/* Save the requested allocation size. */
- allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
+ if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
+ SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
#ifdef LARGE_SMB_OFF_T
- allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
+ allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
#endif
- if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
- fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
- if (fsp->is_directory) {
- close_file(fsp,False);
- END_PROFILE(SMBntcreateX);
- /* Can't set allocation size on a directory. */
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
- if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
- close_file(fsp,False);
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(NT_STATUS_DISK_FULL);
+ if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+ if (fsp->is_directory) {
+ close_file(fsp,False);
+ END_PROFILE(SMBntcreateX);
+ /* Can't set allocation size on a directory. */
+ return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+ }
+ if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+ close_file(fsp,False);
+ END_PROFILE(SMBntcreateX);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ } else {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
}
- } else {
- fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
}
/*
@@ -951,11 +957,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
* correct bit for extended oplock reply.
*/
- if (oplock_request && lp_fake_oplocks(SNUM(conn)))
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
extended_oplock_granted = True;
+ }
- if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
extended_oplock_granted = True;
+ }
#if 0
/* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
@@ -1159,6 +1167,34 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
}
/****************************************************************************
+ Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+
+static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+ struct ea_list *ea_list_head = NULL;
+ size_t offset = 0;
+
+ if (data_size < 4) {
+ return NULL;
+ }
+
+ while (offset + 4 <= data_size) {
+ size_t next_offset = IVAL(pdata,offset);
+ struct ea_list *tmp;
+ struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
+
+ DLIST_ADD_END(ea_list_head, eal, tmp);
+ if (next_offset == 0) {
+ break;
+ }
+ offset += next_offset;
+ }
+
+ return ea_list_head;
+}
+
+/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
@@ -1187,11 +1223,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
uint32 create_disposition;
uint32 create_options;
uint32 sd_len;
+ uint32 ea_len;
uint16 root_dir_fid;
- SMB_BIG_UINT allocation_size = 0;
int smb_ofun;
int smb_open_mode;
time_t c_time;
+ struct ea_list *ea_list = NULL;
+ TALLOC_CTX *ctx = NULL;
+ char *pdata = NULL;
NTSTATUS status;
DEBUG(5,("call_nt_transact_create\n"));
@@ -1217,7 +1256,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if(parameter_count < 54) {
DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
- return ERROR_DOS(ERRDOS,ERRnoaccess);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
flags = IVAL(params,0);
@@ -1227,8 +1266,32 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
create_disposition = IVAL(params,28);
create_options = IVAL(params,32);
sd_len = IVAL(params,36);
+ ea_len = IVAL(params,40);
root_dir_fid = (uint16)IVAL(params,4);
+ /* Ensure the data_len is correct for the sd and ea values given. */
+ if ((ea_len + sd_len > data_count) ||
+ (ea_len > data_count) || (sd_len > data_count) ||
+ (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
+ (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (ea_len) {
+ if (!lp_ea_support(SNUM(conn))) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
+ (unsigned int)ea_len ));
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
+
+ if (ea_len < 10) {
+ DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
+ (unsigned int)ea_len ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
if (create_options & FILE_OPEN_BY_FILE_ID) {
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
@@ -1238,8 +1301,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* NT values, as that's what our code is structured to accept.
*/
- if((smb_ofun = map_create_disposition( create_disposition )) == -1)
- return ERROR_DOS(ERRDOS,ERRbadmem);
+ if((smb_ofun = map_create_disposition( create_disposition )) == -1) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
/*
* Get the file name.
@@ -1361,6 +1425,25 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
}
+ if (ea_len) {
+ ctx = talloc_init("NTTRANS_CREATE_EA");
+ if (!ctx) {
+ talloc_destroy(ctx);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ pdata = data + sd_len;
+
+ /* We have already checked that ea_len <= data_count here. */
+ ea_list = read_nttrans_ea_list(ctx, pdata, ea_len);
+ if (!ea_list ) {
+ talloc_destroy(ctx);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
/*
* If it's a request for a directory open, deal with it separately.
*/
@@ -1369,6 +1452,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
/* Can't open a temp directory. IFS kit test. */
if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
+ talloc_destroy(ctx);
+ restore_case_semantics(conn, file_attributes);
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
@@ -1383,6 +1468,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
if(!fsp) {
+ talloc_destroy(ctx);
restore_case_semantics(conn, file_attributes);
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
@@ -1398,7 +1484,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
oplock_request,&rmode,&smb_action);
if (!fsp) {
-
if(errno == EISDIR) {
/*
@@ -1407,84 +1492,113 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(conn, file_attributes);
- SSVAL(outbuf, smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
- return ERROR_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
+ return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
oplock_request = 0;
fsp = open_directory(conn, fname, &sbuf, desired_access, smb_open_mode, smb_ofun, &smb_action);
if(!fsp) {
+ talloc_destroy(ctx);
restore_case_semantics(conn, file_attributes);
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
} else {
+ talloc_destroy(ctx);
restore_case_semantics(conn, file_attributes);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
}
-
- file_len = sbuf.st_size;
- fmode = dos_mode(conn,fname,&sbuf);
- if(fmode == 0)
- fmode = FILE_ATTRIBUTE_NORMAL;
-
- if (fmode & aDIR) {
- close_file(fsp,False);
- restore_case_semantics(conn, file_attributes);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
-
- /*
- * If the caller set the extended oplock request bit
- * and we granted one (by whatever means) - set the
- * correct bit for extended oplock reply.
- */
-
- if (oplock_request && lp_fake_oplocks(SNUM(conn)))
- extended_oplock_granted = True;
-
- if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- extended_oplock_granted = True;
}
/*
- * Now try and apply the desired SD.
+ * According to the MS documentation, the only time the security
+ * descriptor is applied to the opened file is iff we *created* the
+ * file; an existing file stays the same.
+ *
+ * Also, it seems (from observation) that you can open the file with
+ * any access mask but you can still write the sd. We need to override
+ * the granted access before we call set_sd
+ * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
*/
- if (lp_nt_acl_support(SNUM(conn)) && sd_len &&
- !NT_STATUS_IS_OK(status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION))) {
- close_file(fsp,False);
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(status);
- }
+ if (lp_nt_acl_support(SNUM(conn)) && sd_len && smb_action == FILE_WAS_CREATED) {
+ uint32 saved_access = fsp->desired_access;
+
+ /* We have already checked that sd_len <= data_count here. */
+
+ fsp->desired_access = FILE_GENERIC_ALL;
+
+ status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_destroy(ctx);
+ close_file(fsp,False);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(status);
+ }
+ fsp->desired_access = saved_access;
+ }
+ if (ea_len && (smb_action == FILE_WAS_CREATED)) {
+ status = set_ea(conn, fsp, fname, ea_list);
+ talloc_destroy(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ close_file(fsp,False);
+ restore_case_semantics(conn, file_attributes);
+ return ERROR_NT(status);
+ }
+ }
+
restore_case_semantics(conn, file_attributes);
+ file_len = sbuf.st_size;
+ fmode = dos_mode(conn,fname,&sbuf);
+ if(fmode == 0) {
+ fmode = FILE_ATTRIBUTE_NORMAL;
+ }
+ if (!fsp->is_directory && (fmode & aDIR)) {
+ close_file(fsp,False);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
+
/* Save the requested allocation size. */
- allocation_size = (SMB_BIG_UINT)IVAL(params,12);
+ if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
+ SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
#ifdef LARGE_SMB_OFF_T
- allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
+ allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
#endif
- if (allocation_size && (allocation_size > file_len)) {
- fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
- if (fsp->is_directory) {
- close_file(fsp,False);
- END_PROFILE(SMBntcreateX);
- /* Can't set allocation size on a directory. */
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
- }
- if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
- close_file(fsp,False);
- return ERROR_NT(NT_STATUS_DISK_FULL);
+ if (allocation_size && (allocation_size > file_len)) {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+ if (fsp->is_directory) {
+ close_file(fsp,False);
+ /* Can't set allocation size on a directory. */
+ return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+ }
+ if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+ close_file(fsp,False);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ } else {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
}
- } else {
- fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
+ }
+
+ /*
+ * If the caller set the extended oplock request bit
+ * and we granted one (by whatever means) - set the
+ * correct bit for extended oplock reply.
+ */
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ extended_oplock_granted = True;
+ }
+
+ if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ extended_oplock_granted = True;
}
/* Realloc the size of parameters and data we will return */
@@ -1662,12 +1776,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&access_mode,&smb_action);
if (!fsp1) {
- status = NT_STATUS_ACCESS_DENIED;
- if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
- status = NT_STATUS_SHARING_VIOLATION;
- unix_ERR_class = 0;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
+ get_saved_error_triple(NULL, NULL, &status);
+ if (NT_STATUS_IS_OK(status)) {
+ status = NT_STATUS_ACCESS_DENIED;
+ }
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
return status;
}
@@ -1676,12 +1789,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&access_mode,&smb_action);
if (!fsp2) {
- status = NT_STATUS_ACCESS_DENIED;
- if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
- status = NT_STATUS_SHARING_VIOLATION;
- unix_ERR_class = 0;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
+ get_saved_error_triple(NULL, NULL, &status);
+ if (NT_STATUS_IS_OK(status)) {
+ status = NT_STATUS_ACCESS_DENIED;
+ }
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
close_file(fsp1,False);
return status;
}
@@ -1787,7 +1899,6 @@ int reply_ntrename(connection_struct *conn,
END_PROFILE(SMBntrename);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return ERROR_NT(status);
@@ -1909,7 +2020,6 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
{
- extern DOM_SID global_sid_World;
size_t sd_size;
*ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
@@ -2836,6 +2946,9 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+ /* We need to re-calcuate the new length after we've read the secondary packet. */
+ length = smb_len(inbuf) + 4;
+
/*
* The sequence number for the trans reply is always
* based on the last secondary received.
@@ -2883,7 +2996,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
goto bad_param;
if (parameter_displacement > total_parameter_count)
goto bad_param;
- if ((smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize) ||
+ if ((smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length) ||
(smb_base(inbuf) + parameter_offset + parameter_count < smb_base(inbuf)))
goto bad_param;
if (parameter_displacement + params < params)
@@ -2900,7 +3013,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
goto bad_param;
if (data_displacement > total_data_count)
goto bad_param;
- if ((smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize) ||
+ if ((smb_base(inbuf) + data_offset + data_count > inbuf + length) ||
(smb_base(inbuf) + data_offset + data_count < smb_base(inbuf)))
goto bad_param;
if (data_displacement + data < data)
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 0a3903234dd..559994ca46c 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -21,6 +21,7 @@
#include "includes.h"
+extern struct current_user current_user;
extern userdom_struct current_user_info;
extern uint16 global_oplock_port;
extern uint16 global_smbpid;
@@ -76,9 +77,92 @@ static void check_for_pipe(const char *fname)
strlower_m(s);
if (strstr(s,"pipe/")) {
DEBUG(3,("Rejecting named pipe open for %s\n",fname));
- unix_ERR_class = ERRSRV;
- unix_ERR_code = ERRaccess;
- unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
+ set_saved_error_triple(ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED);
+ }
+}
+
+/****************************************************************************
+ Change the ownership of a file to that of the parent directory.
+ Do this by fd if possible.
+****************************************************************************/
+
+void change_owner_to_parent(connection_struct *conn, files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf)
+{
+ const char *parent_path = parent_dirname(fname);
+ SMB_STRUCT_STAT parent_st;
+ int ret;
+
+ ret = SMB_VFS_STAT(conn, parent_path, &parent_st);
+ if (ret == -1) {
+ DEBUG(0,("change_owner_to_parent: failed to stat parent directory %s. Error was %s\n",
+ parent_path, strerror(errno) ));
+ return;
+ }
+
+ if (fsp && fsp->fd != -1) {
+ become_root();
+ ret = SMB_VFS_FCHOWN(fsp, fsp->fd, parent_st.st_uid, (gid_t)-1);
+ unbecome_root();
+ if (ret == -1) {
+ DEBUG(0,("change_owner_to_parent: failed to fchown file %s to parent directory uid %u. \
+Error was %s\n",
+ fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
+ }
+
+ DEBUG(10,("change_owner_to_parent: changed new file %s to parent directory uid %u.\n",
+ fname, (unsigned int)parent_st.st_uid ));
+
+ } else {
+ /* We've already done an lstat into psbuf, and we know it's a directory. If
+ we can cd into the directory and the dev/ino are the same then we can safely
+ chown without races as we're locking the directory in place by being in it.
+ This should work on any UNIX (thanks tridge :-). JRA.
+ */
+
+ pstring saved_dir;
+ SMB_STRUCT_STAT sbuf;
+
+ if (!vfs_GetWd(conn,saved_dir)) {
+ DEBUG(0,("change_owner_to_parent: failed to get current working directory\n"));
+ return;
+ }
+
+ /* Chdir into the new path. */
+ if (vfs_ChDir(conn, fname) == -1) {
+ DEBUG(0,("change_owner_to_parent: failed to change current working directory to %s. \
+Error was %s\n", fname, strerror(errno) ));
+ goto out;
+ }
+
+ if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
+ DEBUG(0,("change_owner_to_parent: failed to stat directory '.' (%s) \
+Error was %s\n", fname, strerror(errno)));
+ goto out;
+ }
+
+ /* Ensure we're pointing at the same place. */
+ if (sbuf.st_dev != psbuf->st_dev || sbuf.st_ino != psbuf->st_ino || sbuf.st_mode != psbuf->st_mode ) {
+ DEBUG(0,("change_owner_to_parent: device/inode/mode on directory %s changed. Refusing to chown !\n",
+ fname ));
+ goto out;
+ }
+
+ become_root();
+ ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1);
+ unbecome_root();
+ if (ret == -1) {
+ DEBUG(10,("change_owner_to_parent: failed to chown directory %s to parent directory uid %u. \
+Error was %s\n",
+ fname, (unsigned int)parent_st.st_uid, strerror(errno) ));
+ goto out;
+ }
+
+ DEBUG(10,("change_owner_to_parent: changed ownership of new directory %s to parent directory uid %u.\n",
+ fname, (unsigned int)parent_st.st_uid ));
+
+ out:
+
+ vfs_ChDir(conn,saved_dir);
}
}
@@ -89,7 +173,6 @@ static void check_for_pipe(const char *fname)
static BOOL open_file(files_struct *fsp,connection_struct *conn,
const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
{
- extern struct current_user current_user;
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
@@ -165,9 +248,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
/* Don't create files with Microsoft wildcard characters. */
if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
+ set_saved_error_triple(ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID);
return False;
}
@@ -402,9 +483,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
DEBUG(5,("check_share_mode: Failing open on file %s as delete on close flag is set.\n",
fname ));
/* Use errno to map to correct error. */
- unix_ERR_class = SMB_SUCCESS;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
+ set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
return False;
}
@@ -444,10 +523,7 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
(!GET_ALLOW_SHARE_DELETE(share->share_mode) || !GET_ALLOW_SHARE_DELETE(share_mode))) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access requests conflict.\n",
fname ));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@@ -472,10 +548,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
if ((desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share->share_mode)) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access requested and allow share delete not set.\n",
fname ));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@@ -488,18 +561,14 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
if ((share->desired_access & DELETE_ACCESS) && !GET_ALLOW_SHARE_DELETE(share_mode)) {
DEBUG(5,("check_share_mode: Failing open on file %s as delete access granted and allow share delete not requested.\n",
fname ));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
#if 0
/* Bluarc test may need this ... needs further investigation. */
if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
#endif
@@ -529,10 +598,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
deny_mode,old_deny_mode,old_open_mode,
(int)share->pid,fname, fcbopen, *flags, access_allowed));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
-
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return False;
}
@@ -683,10 +749,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
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));
SAFE_FREE(old_shares);
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return -1;
}
@@ -750,9 +813,7 @@ after break ! For file %s, dev = %x, inode = %.0f. Deleting it to continue...\n"
if (del_share_entry(dev, inode, &broken_entry->entry, NULL) == -1) {
free_broken_entry_list(broken_entry_list);
errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return -1;
}
@@ -1019,9 +1080,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
delete_defered_open_entry_record(conn, dib.dev, dib.inode);
unlock_share_entry(conn, dib.dev, dib.inode);
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return NULL;
}
/* Ensure we don't reprocess this message. */
@@ -1039,15 +1098,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
return print_fsp_open(conn, fname);
}
- fsp = file_new(conn);
- if(!fsp)
- return NULL;
-
DEBUG(10,("open_file_shared: fname = %s, dos_attrs = %x, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
fname, new_dos_mode, share_mode, ofun, (int)mode, oplock_request ));
if (!check_name(fname,conn)) {
- file_free(fsp);
return NULL;
}
@@ -1063,21 +1117,15 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
/* this is for OS/2 long file names - say we don't support them */
if (strstr(fname,".+,;=[].")) {
- unix_ERR_class = ERRDOS;
/* OS/2 Workplace shell fix may be main code stream in a later release. */
- unix_ERR_code = ERRcannotopen;
- unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ set_saved_error_triple(ERRDOS, ERRcannotopen, NT_STATUS_OBJECT_NAME_NOT_FOUND);
DEBUG(5,("open_file_shared: OS/2 long filenames are not supported.\n"));
- /* need to reset errno or DEVELOPER will cause us to coredump */
- errno = 0;
- file_free(fsp);
return NULL;
}
if ((GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_FAIL) && file_existed) {
DEBUG(5,("open_file_shared: create new requested for file %s and file already exists.\n",
fname ));
- file_free(fsp);
if (S_ISDIR(psbuf->st_mode)) {
errno = EISDIR;
} else {
@@ -1099,7 +1147,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
DEBUG(5,("open_file_shared: attributes missmatch for file %s (%x %x) (0%o, 0%o)\n",
fname, existing_dos_mode, new_dos_mode,
(int)psbuf->st_mode, (int)mode ));
- file_free(fsp);
errno = EACCES;
return NULL;
}
@@ -1112,6 +1159,11 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
append does not mean the same thing under dos and unix */
switch (GET_OPEN_MODE(share_mode)) {
+ case DOS_OPEN_RDONLY:
+ flags = O_RDONLY;
+ if (desired_access == 0)
+ desired_access = FILE_READ_DATA;
+ break;
case DOS_OPEN_WRONLY:
flags = O_WRONLY;
if (desired_access == 0)
@@ -1124,15 +1176,15 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
break;
case DOS_OPEN_RDWR:
+ case DOS_OPEN_EXEC:
flags = O_RDWR;
if (desired_access == 0)
desired_access = FILE_READ_DATA|FILE_WRITE_DATA;
break;
default:
- flags = O_RDONLY;
- if (desired_access == 0)
- desired_access = FILE_READ_DATA;
- break;
+ /* Force DOS error. */
+ set_saved_error_triple(ERRDOS, ERRinvalidparam, NT_STATUS_INVALID);
+ return NULL;
}
#if defined(O_SYNC)
@@ -1146,7 +1198,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
if (!fcbopen) {
DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
fname, !CAN_WRITE(conn) ? "share" : "file" ));
- file_free(fsp);
errno = EACCES;
return NULL;
}
@@ -1155,7 +1206,6 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
- file_free(fsp);
errno = EINVAL;
return NULL;
}
@@ -1171,6 +1221,10 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
}
}
+ fsp = file_new(conn);
+ if(!fsp)
+ return NULL;
+
if (file_existed) {
dev = psbuf->st_dev;
@@ -1204,9 +1258,8 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
flags,(flags2&~(O_TRUNC|O_CREAT)),(int)mode,(int)fsp_open ));
if (!fsp_open && errno) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRnoaccess;
- unix_ERR_ntstatus = NT_STATUS_ACCESS_DENIED;
+ /* Default error. */
+ set_saved_error_triple(ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED);
}
/*
@@ -1214,9 +1267,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* the braindead 1 second delay.
*/
- if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
- /* The fsp->open_time here represents the current time of day. */
- defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
+ if (!internal_only_open) {
+ NTSTATUS status;
+ get_saved_error_triple(NULL, NULL, &status);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
+ /* The fsp->open_time here represents the current time of day. */
+ defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
+ }
}
unlock_share_entry(conn, dev, inode);
@@ -1226,9 +1283,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* We have detected a sharing violation here
* so return the correct error code
*/
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
}
file_free(fsp);
return NULL;
@@ -1300,7 +1355,9 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* the braindead 1 second delay.
*/
- if (!internal_only_open && NT_STATUS_EQUAL(unix_ERR_ntstatus,NT_STATUS_SHARING_VIOLATION)) {
+ NTSTATUS status;
+ get_saved_error_triple(NULL, NULL, &status);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
/* The fsp->open_time here represents the current time of day. */
defer_open_sharing_error(conn, &fsp->open_time, fname, dev, inode);
}
@@ -1312,9 +1369,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* We have detected a sharing violation here, so
* return the correct code.
*/
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+ set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION);
return NULL;
}
@@ -1380,7 +1435,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
DEBUG(10,("open_file_shared : share_mode = %x\n", fsp->share_mode ));
if (Access) {
- (*Access) = open_mode;
+ (*Access) = (SET_DENY_MODE(deny_mode) | SET_OPEN_MODE(open_mode));
}
action = 0;
@@ -1389,8 +1444,13 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
action = FILE_WAS_OPENED;
if (file_existed && (flags2 & O_TRUNC))
action = FILE_WAS_OVERWRITTEN;
- if (!file_existed)
+ if (!file_existed) {
action = FILE_WAS_CREATED;
+ /* Change the owner if required. */
+ if (lp_inherit_owner(SNUM(conn))) {
+ change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
+ }
+ }
if (paction) {
*paction = action;
@@ -1437,9 +1497,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
fd_close(conn,fsp);
file_free(fsp);
ntstatus_to_dos(result, &u_e_c, &u_e_code);
- unix_ERR_ntstatus = result;
- unix_ERR_class = u_e_c;
- unix_ERR_code = u_e_code;
+ set_saved_error_triple(u_e_c, u_e_code, result);
return NULL;
}
}
@@ -1545,10 +1603,9 @@ int close_file_fchmod(files_struct *fsp)
Open a directory from an NT SMB call.
****************************************************************************/
-files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf,
+files_struct *open_directory(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
uint32 desired_access, int share_mode, int smb_ofun, 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);
@@ -1583,39 +1640,29 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
* Try and create the directory.
*/
- if(!CAN_WRITE(conn)) {
- DEBUG(2,("open_directory: failing create on read-only share\n"));
- file_free(fsp);
- errno = EACCES;
- return NULL;
- }
+ /* We know bad_path is false as it's caught earlier. */
- if (ms_has_wild(fname)) {
- file_free(fsp);
- DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
- return NULL;
- }
+ NTSTATUS status = mkdir_internal(conn, fname, False);
- if( strchr_m(fname, ':')) {
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
+ fname, strerror(errno) ));
file_free(fsp);
- DEBUG(5,("open_directory: failing create on filename %s with colon in name\n", fname));
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRinvalidname;
- unix_ERR_ntstatus = NT_STATUS_NOT_A_DIRECTORY;
+ /* Ensure we return the correct NT status to the client. */
+ set_saved_error_triple(0, 0, status);
return NULL;
}
- if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname, True)) < 0) {
- DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
- fname, strerror(errno) ));
+ /* Ensure we're checking for a symlink here.... */
+ /* We don't want to get caught by a symlink racer. */
+
+ if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {
file_free(fsp);
return NULL;
}
- if(SMB_VFS_STAT(conn,fname, psbuf) != 0) {
+ if(!S_ISDIR(psbuf->st_mode)) {
+ DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
file_free(fsp);
return NULL;
}
@@ -1672,13 +1719,19 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
string_set(&fsp->fsp_name,fname);
if (delete_on_close) {
- NTSTATUS result = set_delete_on_close_internal(fsp, delete_on_close, 0);
+ NTSTATUS status = set_delete_on_close_internal(fsp, delete_on_close, 0);
- if (NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_OK)) {
+ if (!NT_STATUS_IS_OK(status)) {
file_free(fsp);
return NULL;
}
}
+
+ /* Change the owner if required. */
+ if ((*action == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) {
+ change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf);
+ }
+
conn->num_files_open++;
return fsp;
@@ -1690,7 +1743,6 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
{
- extern struct current_user current_user;
files_struct *fsp = NULL;
if (!VALID_STAT(*psbuf))
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index b9e38e30fcc..9b8df98fd56 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -31,6 +31,9 @@ static int32 level_II_oplocks_open = 0;
BOOL global_client_failed_oplock_break = False;
BOOL global_oplock_break = False;
+extern struct timeval smb_last_time;
+extern uint32 global_client_caps;
+extern struct current_user current_user;
extern int smb_read_error;
static struct kernel_oplocks *koplocks;
@@ -518,8 +521,6 @@ 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;
-
if(local_request) {
struct timeval cur_tv;
long wait_left = (long)lp_oplock_break_wait_time();
@@ -603,7 +604,6 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un
static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request)
{
- extern uint32 global_client_caps;
char outbuf[128];
SMB_DEV_T dev = fsp->dev;
SMB_INO_T inode = fsp->inode;
@@ -676,8 +676,6 @@ static BOOL oplock_break_level2(files_struct *fsp, 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;
@@ -807,7 +805,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
saved_user_conn = current_user.conn;
saved_vuid = current_user.vuid;
saved_fsp_conn = fsp->conn;
- change_to_root_user();
/*
* Initialize saved_dir to something sensible: vfs_GetWd may not work well
* for root: the directory may be NFS-mounted and exported with root_squash
@@ -818,6 +815,10 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
/* Save the chain fnum. */
file_chain_save();
+ pstrcpy(file_name, fsp->fsp_name);
+
+ change_to_root_user();
+
/*
* From Charles Hoch <hoch@exemplary.com>. If the break processing
* code closes the file (as it often does), then the fsp pointer here
@@ -825,8 +826,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
* 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) {
@@ -940,6 +939,9 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
abort();
}
+ /* We know we have no saved errors here. */
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+
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 );
diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c
index 5de9dd56e68..5d6bdb98832 100644
--- a/source/smbd/oplock_linux.c
+++ b/source/smbd/oplock_linux.c
@@ -22,6 +22,22 @@
#if HAVE_KERNEL_OPLOCKS_LINUX
+/* these can be removed when they are in glibc headers */
+struct cap_user_header {
+ uint32 version;
+ int pid;
+} header;
+struct cap_user_data {
+ uint32 effective;
+ uint32 permitted;
+ uint32 inheritable;
+} data;
+
+extern int capget(struct cap_user_header * hdrp,
+ struct cap_user_data * datap);
+extern int capset(struct cap_user_header * hdrp,
+ const struct cap_user_data * datap);
+
static SIG_ATOMIC_T signals_received;
#define FD_PENDING_SIZE 100
static SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
@@ -68,17 +84,6 @@ static void set_capability(unsigned capability)
#ifndef _LINUX_CAPABILITY_VERSION
#define _LINUX_CAPABILITY_VERSION 0x19980330
#endif
- /* these can be removed when they are in glibc headers */
- struct {
- uint32 version;
- int pid;
- } header;
- struct {
- uint32 effective;
- uint32 permitted;
- uint32 inheritable;
- } data;
-
header.version = _LINUX_CAPABILITY_VERSION;
header.pid = 0;
@@ -133,7 +138,8 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l
fsp = file_find_fd(fd);
fd_pending_array[0] = (SIG_ATOMIC_T)-1;
if (signals_received > 1)
- memmove((void *)&fd_pending_array[0], (void *)&fd_pending_array[1],
+ memmove(CONST_DISCARD(void *, &fd_pending_array[0]),
+ CONST_DISCARD(void *, &fd_pending_array[1]),
sizeof(SIG_ATOMIC_T)*(signals_received-1));
signals_received--;
/* now we can receive more signals */
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 52ddf4cad6d..e0d98f4b897 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -21,6 +21,9 @@
#include "includes.h"
+extern struct current_user current_user;
+extern struct generic_mapping file_generic_mapping;
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_ACLS
@@ -916,7 +919,6 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid
if (lp_force_unknown_acl_user(snum)) {
/* this allows take ownership to work
* reasonably */
- extern struct current_user current_user;
*puser = current_user.uid;
} else {
DEBUG(3,("unpack_nt_owners: unable to validate"
@@ -938,7 +940,6 @@ static BOOL unpack_nt_owners(int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid
if (lp_force_unknown_acl_user(snum)) {
/* this allows take group ownership to work
* reasonably */
- extern struct current_user current_user;
*pgrp = current_user.gid;
} else {
DEBUG(3,("unpack_nt_owners: unable to validate"
@@ -1003,10 +1004,8 @@ static void apply_default_perms(files_struct *fsp, canon_ace *pace, mode_t type)
static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
{
- extern DOM_SID global_sid_World;
fstring u_name;
fstring g_name;
- extern struct current_user current_user;
/* "Everyone" always matches every uid. */
@@ -1041,12 +1040,11 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
files_struct *fsp,
- DOM_SID *pfile_owner_sid,
- DOM_SID *pfile_grp_sid,
+ const DOM_SID *pfile_owner_sid,
+ const DOM_SID *pfile_grp_sid,
SMB_STRUCT_STAT *pst,
BOOL setting_acl)
{
- extern DOM_SID global_sid_World;
canon_ace *pace;
BOOL got_user = False;
BOOL got_grp = False;
@@ -1220,10 +1218,6 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
canon_ace **ppfile_ace, canon_ace **ppdir_ace,
SEC_ACL *dacl)
{
- extern DOM_SID global_sid_Creator_Owner;
- extern DOM_SID global_sid_Creator_Group;
- extern DOM_SID global_sid_World;
- extern struct generic_mapping file_generic_mapping;
BOOL all_aces_are_inherit_only = (fsp->is_directory ? True : False);
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
@@ -1647,7 +1641,6 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
static void process_deny_list( canon_ace **pp_ace_list )
{
- extern DOM_SID global_sid_World;
canon_ace *ace_list = *pp_ace_list;
canon_ace *curr_ace = NULL;
canon_ace *curr_ace_next = NULL;
@@ -2065,9 +2058,8 @@ static void arrange_posix_perms( char *filename, canon_ace **pp_list_head)
****************************************************************************/
static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf,
- DOM_SID *powner, DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
+ const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
{
- extern DOM_SID global_sid_World;
connection_struct *conn = fsp->conn;
mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR);
canon_ace *list_head = NULL;
@@ -2629,10 +2621,6 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
{
- extern DOM_SID global_sid_Builtin_Administrators;
- extern DOM_SID global_sid_Builtin_Users;
- extern DOM_SID global_sid_Creator_Owner;
- extern DOM_SID global_sid_Creator_Group;
connection_struct *conn = fsp->conn;
SMB_STRUCT_STAT sbuf;
SEC_ACE *nt_ace_list = NULL;
@@ -2920,7 +2908,6 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
{
int ret;
- extern struct current_user current_user;
files_struct *fsp;
SMB_STRUCT_STAT st;
@@ -2976,7 +2963,6 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
uid_t orig_uid;
gid_t orig_gid;
BOOL need_chown = False;
- extern struct current_user current_user;
DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
@@ -3067,7 +3053,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
- &file_ace_list, &dir_ace_list, security_info_sent, psd);
+ &file_ace_list, &dir_ace_list, security_info_sent, psd);
/* Ignore W2K traverse DACL set. */
if (file_ace_list || dir_ace_list) {
@@ -3760,7 +3746,6 @@ BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *
static int check_posix_acl_group_write(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf)
{
- extern struct current_user current_user;
SMB_ACL_T posix_acl = NULL;
int entry_id = SMB_ACL_FIRST_ENTRY;
SMB_ACL_ENTRY_T entry;
@@ -3922,7 +3907,6 @@ failed to match on user or group in token.\n", fname ));
BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
{
- extern struct current_user current_user;
SMB_STRUCT_STAT sbuf;
pstring dname;
int ret;
@@ -3980,7 +3964,6 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
BOOL can_write_to_file(connection_struct *conn, const char *fname)
{
- extern struct current_user current_user;
SMB_STRUCT_STAT sbuf;
int ret;
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 54837c3b9ae..1bf6f4f9d14 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -20,6 +20,11 @@
#include "includes.h"
+extern uint16 global_smbpid;
+extern int keepalive;
+extern struct auth_context *negprot_global_auth_context;
+extern int smb_echo_count;
+
struct timeval smb_last_time;
static char *InBuffer = NULL;
@@ -211,6 +216,7 @@ BOOL open_was_deferred(uint16 mid)
for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
if (SVAL(pml->buf.data,smb_mid) == mid) {
+ set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
return True;
}
}
@@ -851,7 +857,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
{
static pid_t pid= (pid_t)-1;
int outsize = 0;
- extern uint16 global_smbpid;
type &= 0xff;
@@ -859,6 +864,8 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
pid = sys_getpid();
errno = 0;
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+
last_message = type;
/* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */
@@ -1328,7 +1335,6 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
static time_t last_idle_closed_check = 0;
time_t t;
BOOL allidle = True;
- extern int keepalive;
if (smb_read_error == READ_EOF) {
DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
@@ -1372,7 +1378,6 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
}
if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
- extern struct auth_context *negprot_global_auth_context;
if (!send_keepalive(smbd_server_fd())) {
DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
return False;
@@ -1490,7 +1495,6 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup()));
void smbd_process(void)
{
- extern int smb_echo_count;
time_t last_timeout_processing_time = time(NULL);
unsigned int num_smbs = 0;
const size_t total_buffer_size = BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN;
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index 1117461bc25..1a73fdf2223 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -882,8 +882,17 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
restore_re_uid();
if (r==-1)
+ {
+ DEBUG(5, ("quotactl for uid=%u: %s", euser_id, strerror(errno)));
return(False);
+ }
+ /* No quota for this user. */
+ if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
+ {
+ return(False);
+ }
+
/* Use softlimit to determine disk space, except when it has been exceeded */
if (
(F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
@@ -895,14 +904,10 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
*dfree = 0;
*dsize = F.d_bcount;
}
- else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
- {
- return(False);
- }
else
{
*dfree = (F.d_blk_softlimit - F.d_bcount);
- *dsize = F.d_blk_softlimit;
+ *dsize = F.d_blk_softlimit ? F.d_blk_softlimit : F.d_blk_hardlimit;
}
}
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 5802720b7e9..c3cb81ddfc4 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -35,16 +35,17 @@ extern int global_oplock_break;
unsigned int smb_echo_count = 0;
extern uint32 global_client_caps;
+extern struct current_user current_user;
extern BOOL global_encrypted_passwords_negotiated;
/****************************************************************************
- Ensure we check the path in *exactly* the same way as W2K.
+ Ensure we check the path in *exactly* the same way as W2K for regular pathnames.
We're assuming here that '/' is not the second byte in any multibyte char
set (a safe assumption). '\\' *may* be the second byte in a multibyte char
set.
****************************************************************************/
-NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_wcard_names)
+NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
{
char *d = destname;
const char *s = srcname;
@@ -118,20 +119,16 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_w
}
if (!(*s & 0x80)) {
- if (allow_wcard_names) {
- *d++ = *s++;
- } else {
- switch (*s) {
- case '*':
- case '?':
- case '<':
- case '>':
- case '"':
- return NT_STATUS_OBJECT_NAME_INVALID;
- default:
- *d++ = *s++;
- break;
- }
+ switch (*s) {
+ case '*':
+ case '?':
+ case '<':
+ case '>':
+ case '"':
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ default:
+ *d++ = *s++;
+ break;
}
} else {
switch(next_mb_char_size(s)) {
@@ -157,17 +154,127 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname, BOOL allow_w
}
if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
- /* For some strange reason being called from findfirst changes
- the num_components number to cause the error return to change. JRA. */
- if (allow_wcard_names) {
- if (num_bad_components > 2) {
- ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ if (num_bad_components > 1) {
+ ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ }
+
+ *d = '\0';
+ return ret;
+}
+
+/****************************************************************************
+ Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
+ path or anything including wildcards.
+ We're assuming here that '/' is not the second byte in any multibyte char
+ set (a safe assumption). '\\' *may* be the second byte in a multibyte char
+ set.
+****************************************************************************/
+
+NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
+{
+ char *d = destname;
+ const char *s = srcname;
+ NTSTATUS ret = NT_STATUS_OK;
+ BOOL start_of_name_component = True;
+ unsigned int num_bad_components = 0;
+
+ while (*s) {
+ if (IS_DIRECTORY_SEP(*s)) {
+ /*
+ * Safe to assume is not the second part of a mb char as this is handled below.
+ */
+ /* Eat multiple '/' or '\\' */
+ while (IS_DIRECTORY_SEP(*s)) {
+ s++;
+ }
+ if ((d != destname) && (*s != '\0')) {
+ /* We only care about non-leading or trailing '/' or '\\' */
+ *d++ = '/';
}
+
+ start_of_name_component = True;
+ continue;
+ }
+
+ if (start_of_name_component) {
+ if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
+ /* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
+
+ /*
+ * No mb char starts with '.' so we're safe checking the directory separator here.
+ */
+
+ /* If we just added a '/' - delete it */
+ if ((d > destname) && (*(d-1) == '/')) {
+ *(d-1) = '\0';
+ d--;
+ }
+
+ /* Are we at the start ? Can't go back further if so. */
+ if (d <= destname) {
+ ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+ break;
+ }
+ /* Go back one level... */
+ /* We know this is safe as '/' cannot be part of a mb sequence. */
+ /* NOTE - if this assumption is invalid we are not in good shape... */
+ /* Decrement d first as d points to the *next* char to write into. */
+ for (d--; d > destname; d--) {
+ if (*d == '/')
+ break;
+ }
+ s += 2; /* Else go past the .. */
+ /* We're still at the start of a name component, just the previous one. */
+
+ if (num_bad_components) {
+ /* Hmmm. Should we only decrement the bad_components if
+ we're removing a bad component ? Need to check this. JRA. */
+ num_bad_components--;
+ }
+
+ continue;
+
+ } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
+ /* Component of pathname can't be "." only. */
+ ret = NT_STATUS_OBJECT_NAME_INVALID;
+ num_bad_components++;
+ *d++ = *s++;
+ continue;
+ }
+ }
+
+ if (!(*s & 0x80)) {
+ *d++ = *s++;
} else {
- if (num_bad_components > 1) {
- ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ switch(next_mb_char_size(s)) {
+ case 4:
+ *d++ = *s++;
+ case 3:
+ *d++ = *s++;
+ case 2:
+ *d++ = *s++;
+ case 1:
+ *d++ = *s++;
+ break;
+ default:
+ DEBUG(0,("check_path_syntax_wcard: character length assumptions invalid !\n"));
+ *d = '\0';
+ return NT_STATUS_INVALID_PARAMETER;
}
}
+ if (start_of_name_component && num_bad_components) {
+ num_bad_components++;
+ }
+ start_of_name_component = False;
+ }
+
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_NAME_INVALID)) {
+ /* For some strange reason being called from findfirst changes
+ the num_components number to cause the error return to change. JRA. */
+ if (num_bad_components > 2) {
+ ret = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ }
}
*d = '\0';
@@ -192,7 +299,11 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
} else {
ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
}
- *err = check_path_syntax(dest, tmppath, allow_wcard_names);
+ if (allow_wcard_names) {
+ *err = check_path_syntax_wcard(dest, tmppath);
+ } else {
+ *err = check_path_syntax(dest, tmppath);
+ }
return ret;
}
@@ -361,7 +472,6 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int passlen = SVAL(inbuf,smb_vwv3);
pstring path;
char *p, *q;
- extern BOOL global_encrypted_passwords_negotiated;
START_PROFILE(SMBtconX);
@@ -821,6 +931,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL can_open = True;
BOOL bad_path = False;
NTSTATUS nt_status;
+ BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
+
START_PROFILE(SMBsearch);
*mask = *directory = *fname = 0;
@@ -839,7 +951,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(nt_status);
}
- RESOLVE_DFSPATH(path, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(path, conn, inbuf, outbuf);
p++;
status_len = SVAL(p, 0);
@@ -920,7 +1032,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (ok) {
if ((dirtype&0x1F) == aVOLID) {
memcpy(p,status,21);
- make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
+ make_dir_struct(p,"???????????",volume_label(SNUM(conn)),
+ 0,aVOLID,0,!allow_long_path_components);
dptr_fill(p+12,dptr_num);
if (dptr_zero(p+12) && (status_len==0))
numentries = 1;
@@ -940,7 +1053,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
if (!finished) {
memcpy(p,status,21);
- make_dir_struct(p,mask,fname,size,mode,date);
+ make_dir_struct(p,mask,fname,size, mode,date,
+ !allow_long_path_components);
dptr_fill(p+12,dptr_num);
numentries++;
p += DIR_STRUCT_SIZE;
@@ -978,8 +1092,11 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SCVAL(smb_buf(outbuf),0,5);
SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
- if (Protocol >= PROTOCOL_NT1)
- SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+ /* The replies here are never long name. */
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
+ if (!allow_long_path_components) {
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS));
+ }
/* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
@@ -1089,7 +1206,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBopen);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1152,6 +1268,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
BOOL bad_path = False;
files_struct *fsp;
NTSTATUS status;
+ SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
+ ssize_t retval = -1;
+
START_PROFILE(SMBopenX);
/* If it's an IPC, pass off the pipe handler. */
@@ -1179,7 +1298,17 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
END_PROFILE(SMBopenX);
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
-
+
+ /* Strange open mode mapping. */
+ if (smb_ofun == 0) {
+ if (GET_OPEN_MODE(smb_mode) == DOS_OPEN_EXEC) {
+ smb_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
+ } else {
+ END_PROFILE(SMBopenX);
+ return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
+ }
+ }
+
fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,(uint32)smb_attr,
oplock_request, &rmode,&smb_action);
@@ -1187,13 +1316,31 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
END_PROFILE(SMBopenX);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
}
size = sbuf.st_size;
+
+ /* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
+ if the file is truncated or created. */
+ if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
+ fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
+ if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
+ close_file(fsp,False);
+ END_PROFILE(SMBntcreateX);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
+ if (retval < 0) {
+ close_file(fsp,False);
+ END_PROFILE(SMBwrite);
+ return ERROR_NT(NT_STATUS_DISK_FULL);
+ }
+ size = get_allocation_size(conn,fsp,&sbuf);
+ }
+
fmode = dos_mode(conn,fname,&sbuf);
mtime = sbuf.st_mtime;
if (fmode & aDIR) {
@@ -1321,7 +1468,6 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBcreate);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1405,7 +1551,6 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBctemp);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
@@ -1467,20 +1612,19 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
return NT_STATUS_OK;
/* We need a better way to return NT status codes from open... */
- unix_ERR_class = 0;
- unix_ERR_code = 0;
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
fsp = open_file_shared1(conn, fname, pst, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
if (!fsp) {
- NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
- if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
- ret = NT_STATUS_SHARING_VIOLATION;
- unix_ERR_class = 0;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
- return ret;
+ NTSTATUS ret;
+ if (get_saved_error_triple(NULL, NULL, &ret)) {
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+ return ret;
+ }
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+ return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
return NT_STATUS_OK;
@@ -1540,22 +1684,19 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, int dirtype, BOOL bad_
don't do it here as we'll get it wrong. */
/* We need a better way to return NT status codes from open... */
- unix_ERR_class = 0;
- unix_ERR_code = 0;
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
fsp = open_file_shared1(conn, fname, &sbuf, DELETE_ACCESS, SET_DENY_MODE(DENY_ALL),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action);
if (!fsp) {
- NTSTATUS ret = NT_STATUS_ACCESS_DENIED;
- if (!NT_STATUS_IS_OK(unix_ERR_ntstatus))
- ret = unix_ERR_ntstatus;
- else if (unix_ERR_class == ERRDOS && unix_ERR_code == ERRbadshare)
- ret = NT_STATUS_SHARING_VIOLATION;
- unix_ERR_class = 0;
- unix_ERR_code = 0;
- unix_ERR_ntstatus = NT_STATUS_OK;
- return ret;
+ NTSTATUS ret;
+ if (get_saved_error_triple(NULL, NULL, &ret)) {
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+ return ret;
+ }
+ set_saved_error_triple(0, 0, NT_STATUS_OK);
+ return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
}
@@ -1716,7 +1857,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
DEBUG(3,("reply_unlink : %s\n",name));
@@ -1724,7 +1865,6 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return ERROR_NT(status);
@@ -1870,7 +2010,6 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
{
- extern struct current_user current_user;
ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
@@ -2840,7 +2979,6 @@ int reply_exit(connection_struct *conn,
int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
int dum_buffsize)
{
- extern struct current_user current_user;
int outsize = 0;
time_t mtime;
int32 eclass = 0, err = 0;
@@ -3314,29 +3452,32 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
code.
****************************************************************************/
-NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
+NTSTATUS mkdir_internal(connection_struct *conn, const pstring directory, BOOL bad_path)
{
- BOOL bad_path = False;
- SMB_STRUCT_STAT sbuf;
int ret= -1;
- unix_convert(directory,conn,0,&bad_path,&sbuf);
-
- if( strchr_m(directory, ':')) {
- return NT_STATUS_NOT_A_DIRECTORY;
- }
-
- if (ms_has_wild(directory)) {
- return NT_STATUS_OBJECT_NAME_INVALID;
+ if(!CAN_WRITE(conn)) {
+ DEBUG(5,("mkdir_internal: failing create on read-only share %s\n", lp_servicename(SNUM(conn))));
+ errno = EACCES;
+ return map_nt_error_from_unix(errno);
}
if (bad_path) {
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
- if (check_name(directory, conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
-
+ if (!check_name(directory, conn)) {
+ if(errno == ENOENT) {
+ if (bad_path) {
+ return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ } else {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ }
+ return map_nt_error_from_unix(errno);
+ }
+
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
if (ret == -1) {
if(errno == ENOENT) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -3356,6 +3497,9 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstring directory;
int outsize;
NTSTATUS status;
+ BOOL bad_path = False;
+ SMB_STRUCT_STAT sbuf;
+
START_PROFILE(SMBmkdir);
srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
@@ -3366,12 +3510,38 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
- status = mkdir_internal(conn, directory);
+ unix_convert(directory,conn,0,&bad_path,&sbuf);
+
+ if( strchr_m(directory, ':')) {
+ DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
+ END_PROFILE(SMBmkdir);
+ return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
+ }
+
+ status = mkdir_internal(conn, directory,bad_path);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmkdir);
return ERROR_NT(status);
}
+ if (lp_inherit_owner(SNUM(conn))) {
+ /* Ensure we're checking for a symlink here.... */
+ /* We don't want to get caught by a symlink racer. */
+
+ if(SMB_VFS_LSTAT(conn,directory, &sbuf) != 0) {
+ END_PROFILE(SMBmkdir);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ if(!S_ISDIR(sbuf.st_mode)) {
+ DEBUG(0,("reply_mkdir: %s is not a directory !\n", directory ));
+ END_PROFILE(SMBmkdir);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ change_owner_to_parent(conn, NULL, directory, &sbuf);
+ }
+
outsize = set_message(outbuf,0,0,True);
DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
@@ -4145,8 +4315,8 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
@@ -4155,7 +4325,6 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBmv);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return ERROR_NT(status);
@@ -4305,8 +4474,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
unix_convert(newname,conn,0,&bad_path2,&sbuf2);
@@ -4419,8 +4588,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_DOS(ERRDOS,error);
} else {
if((errno == ENOENT) && (bad_path1 || bad_path2)) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK);
}
END_PROFILE(SMBcopy);
return(UNIXERROR(ERRDOS,error));
@@ -4976,7 +5144,9 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
+ if (HAS_CACHED_ERROR(fsp)) {
+ return(CACHED_ERROR(fsp));
+ }
tcount = SVAL(inbuf,smb_vwv1);
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
@@ -5119,8 +5289,12 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
END_PROFILE(SMBwriteBs);
return(ERROR_DOS(ERRHRD,ERRdiskfull));
}
+ wbms->wr_errclass = ERRHRD;
+ wbms->wr_error = ERRdiskfull;
+ wbms->wr_status = NT_STATUS_DISK_FULL;
+ wbms->wr_discard = True;
END_PROFILE(SMBwriteBs);
- return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
+ return -1;
}
/* Increment the total written, if this matches tcount
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 7f7d55c7e3a..9d910cd14ad 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -30,6 +30,8 @@ int last_message = -1;
/* a useful macro to debug the last message processed */
#define LAST_MESSAGE() smb_fn_name(last_message)
+extern char *last_inbuf;
+extern struct auth_context *negprot_global_auth_context;
extern pstring user_socket_options;
extern SIG_ATOMIC_T got_sig_term;
extern SIG_ATOMIC_T reload_after_sighup;
@@ -598,8 +600,6 @@ static BOOL dump_core(void)
void exit_server(const char *reason)
{
static int firsttime=1;
- extern char *last_inbuf;
- extern struct auth_context *negprot_global_auth_context;
if (!firsttime)
exit(0);
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 684d49c56ae..d39d3d3836c 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -20,6 +20,7 @@
#include "includes.h"
+extern char magic_char;
extern struct timeval smb_last_time;
extern userdom_struct current_user_info;
@@ -30,7 +31,6 @@ extern userdom_struct current_user_info;
BOOL set_current_service(connection_struct *conn, uint16 flags, BOOL do_chdir)
{
- extern char magic_char;
static connection_struct *last_conn;
static uint16 last_flags;
int snum;
@@ -272,7 +272,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
struct passwd *pass = NULL;
BOOL guest = False;
connection_struct *conn;
- struct stat st;
+ SMB_STRUCT_STAT st;
fstring user;
fstring dev;
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index 19acc4b1b08..9fbf0b1d51d 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -25,6 +25,12 @@
uint32 global_client_caps = 0;
+extern BOOL global_encrypted_passwords_negotiated;
+extern BOOL global_spnego_negotiated;
+extern enum protocol_types Protocol;
+extern int max_send;
+extern struct auth_context *negprot_global_auth_context;
+
static struct auth_ntlmssp_state *global_ntlmssp_state;
/*
@@ -313,7 +319,9 @@ static int reply_spnego_kerberos(connection_struct *conn,
/* wrap that up in a nice GSS-API wrapping */
if (NT_STATUS_IS_OK(ret)) {
- ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
+ ap_rep_wrapped = spnego_gen_krb5_wrap(
+ ap_rep,
+ CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REP));
} else {
ap_rep_wrapped = data_blob(NULL, 0);
}
@@ -417,7 +425,9 @@ static int reply_spnego_negotiate(connection_struct *conn,
DATA_BLOB secblob;
int i;
DATA_BLOB chal;
- BOOL got_kerberos = False;
+#ifdef HAVE_KRB5
+ BOOL got_kerberos_mechanism = False;
+#endif
NTSTATUS nt_status;
/* parse out the OIDs and the first sec blob */
@@ -434,11 +444,13 @@ static int reply_spnego_negotiate(connection_struct *conn,
server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
NTLMSSP mechtoken. --jerry */
-
+
+#ifdef HAVE_KRB5
if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
- got_kerberos = True;
+ got_kerberos_mechanism = True;
}
+#endif
for (i=0;OIDs[i];i++) {
DEBUG(3,("Got OID %s\n", OIDs[i]));
@@ -447,7 +459,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length));
#ifdef HAVE_KRB5
- if (got_kerberos && (SEC_ADS == lp_security())) {
+ if (got_kerberos_mechanism && (SEC_ADS == lp_security())) {
int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
length, bufsize, &secblob);
data_blob_free(&secblob);
@@ -631,13 +643,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
fstring native_lanman;
fstring primary_domain;
static BOOL done_sesssetup = False;
- extern BOOL global_encrypted_passwords_negotiated;
- extern BOOL global_spnego_negotiated;
- extern enum protocol_types Protocol;
- extern int max_send;
auth_usersupplied_info *user_info = NULL;
- extern struct auth_context *negprot_global_auth_context;
auth_serversupplied_info *server_info = NULL;
NTSTATUS nt_status;
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index cfc5286327b..8e22d9687b8 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -47,10 +47,15 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
TDB_DATA data_val;
char *original_path;
size_t original_path_length;
+ size_t sc_size = lp_max_stat_cache_size();
if (!lp_stat_cache())
return;
+ if (sc_size && (tdb_stat_cache->map_size > sc_size*1024)) {
+ reset_stat_cache();
+ }
+
ZERO_STRUCT(data_val);
/*
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index daa458f3a97..adc6322ac33 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -23,6 +23,7 @@
#include "includes.h"
+extern int max_send;
extern enum protocol_types Protocol;
extern int smb_read_error;
extern int global_oplock_break;
@@ -58,14 +59,18 @@ SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB
{
SMB_BIG_UINT ret;
+ if(S_ISDIR(sbuf->st_mode)) {
+ return 0;
+ }
+
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
#else
ret = (SMB_BIG_UINT)get_file_size(*sbuf);
#endif
- if (!ret && fsp && fsp->initial_allocation_size)
- ret = fsp->initial_allocation_size;
+ if (fsp && fsp->initial_allocation_size)
+ ret = MAX(ret,fsp->initial_allocation_size);
return smb_roundup(conn, ret);
}
@@ -95,11 +100,6 @@ static BOOL samba_private_attr_name(const char *unix_ea_name)
return False;
}
-struct ea_list {
- struct ea_list *next, *prev;
- struct ea_struct ea;
-};
-
/****************************************************************************
Get one EA value. Fill in a struct ea_struct.
****************************************************************************/
@@ -152,7 +152,8 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str
Return a linked list of the total EA's. Plus the total size
****************************************************************************/
-static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pea_total_len)
+static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
+ const char *fname, size_t *pea_total_len)
{
/* Get a list of all xattrs. Max namesize is 64k. */
size_t ea_namelist_size = 1024;
@@ -186,7 +187,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
if (sizeret == -1)
return NULL;
- DEBUG(10,("get_ea_list: ea_namelist size = %d\n", sizeret ));
+ DEBUG(10,("get_ea_list_from_file: ea_namelist size = %d\n", sizeret ));
if (sizeret) {
for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) {
@@ -207,7 +208,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
fstring dos_ea_name;
push_ascii_fstring(dos_ea_name, listp->ea.name);
*pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
- DEBUG(10,("get_ea_list: total_len = %u, %s, val len = %u\n",
+ DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n",
*pea_total_len, dos_ea_name,
(unsigned int)listp->ea.value.length ));
}
@@ -219,7 +220,7 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
}
}
- DEBUG(10,("get_ea_list: total_len = %u\n", *pea_total_len));
+ DEBUG(10,("get_ea_list_from_file: total_len = %u\n", *pea_total_len));
return ea_list_head;
}
@@ -228,34 +229,16 @@ static struct ea_list *get_ea_list(TALLOC_CTX *mem_ctx, connection_struct *conn,
that was filled.
****************************************************************************/
-static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
- connection_struct *conn, files_struct *fsp, const char *fname)
+static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
+ connection_struct *conn, struct ea_list *ea_list)
{
unsigned int ret_data_size = 4;
char *p = pdata;
- size_t total_ea_len;
- TALLOC_CTX *mem_ctx;
- struct ea_list *ea_list;
SMB_ASSERT(total_data_size >= 4);
- SIVAL(pdata,0,0);
if (!lp_ea_support(SNUM(conn))) {
- return 4;
- }
- mem_ctx = talloc_init("fill_ea_buffer");
- if (!mem_ctx) {
- return 4;
- }
-
- ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
- if (!ea_list) {
- talloc_destroy(mem_ctx);
- return 4;
- }
-
- if (total_ea_len > total_data_size) {
- talloc_destroy(mem_ctx);
+ SIVAL(pdata,4,0);
return 4;
}
@@ -286,9 +269,7 @@ static unsigned int fill_ea_buffer(char *pdata, unsigned int total_data_size,
}
ret_data_size = PTR_DIFF(p, pdata);
- DEBUG(10,("fill_ea_buffer: data_size = %u, total_ea_len = %u\n",
- ret_data_size, total_ea_len ));
- talloc_destroy(mem_ctx);
+ DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
SIVAL(pdata,0,ret_data_size);
return ret_data_size;
}
@@ -302,7 +283,7 @@ static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp,
return 0;
}
mem_ctx = talloc_init("estimate_ea_size");
- (void)get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
+ (void)get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
talloc_destroy(mem_ctx);
return total_ea_len;
}
@@ -315,7 +296,7 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
{
size_t total_ea_len;
TALLOC_CTX *mem_ctx = talloc_init("canonicalize_ea_name");
- struct ea_list *ea_list = get_ea_list(mem_ctx, conn, fsp, fname, &total_ea_len);
+ struct ea_list *ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
for (; ea_list; ea_list = ea_list->next) {
if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
@@ -332,99 +313,246 @@ static void canonicalize_ea_name(connection_struct *conn, files_struct *fsp, con
Set or delete an extended attribute.
****************************************************************************/
-static NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname,
- char *pdata, int total_data)
+NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, struct ea_list *ea_list)
{
- unsigned int namelen;
- unsigned int ealen;
- int ret;
- fstring unix_ea_name;
-
if (!lp_ea_support(SNUM(conn))) {
return NT_STATUS_EAS_NOT_SUPPORTED;
}
- if (total_data < 8) {
- return NT_STATUS_INVALID_PARAMETER;
+ for (;ea_list; ea_list = ea_list->next) {
+ int ret;
+ fstring unix_ea_name;
+
+ fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
+ fstrcat(unix_ea_name, ea_list->ea.name);
+
+ canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
+
+ DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ea_list->ea.value.length));
+
+ if (samba_private_attr_name(unix_ea_name)) {
+ DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (ea_list->ea.value.length == 0) {
+ /* Remove the attribute. */
+ if (fsp && (fsp->fd != -1)) {
+ DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
+ unix_ea_name, fsp->fsp_name));
+ ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
+ } else {
+ DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
+ unix_ea_name, fname));
+ ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
+ }
+#ifdef ENOATTR
+ /* Removing a non existent attribute always succeeds. */
+ if (ret == -1 && errno == ENOATTR) {
+ DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
+ unix_ea_name));
+ ret = 0;
+ }
+#endif
+ } else {
+ if (fsp && (fsp->fd != -1)) {
+ DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
+ unix_ea_name, fsp->fsp_name));
+ ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name,
+ ea_list->ea.value.data, ea_list->ea.value.length, 0);
+ } else {
+ DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
+ unix_ea_name, fname));
+ ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name,
+ ea_list->ea.value.data, ea_list->ea.value.length, 0);
+ }
+ }
+
+ if (ret == -1) {
+#ifdef ENOTSUP
+ if (errno == ENOTSUP) {
+ return NT_STATUS_EAS_NOT_SUPPORTED;
+ }
+#endif
+ return map_nt_error_from_unix(errno);
+ }
+
+ }
+ return NT_STATUS_OK;
+}
+/****************************************************************************
+ Read a list of EA names from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+
+static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+ struct ea_list *ea_list_head = NULL;
+ size_t offset = 0;
+
+ while (offset + 2 < data_size) {
+ struct ea_list *tmp;
+ struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ unsigned int namelen = CVAL(pdata,offset);
+
+ offset++; /* Go past the namelen byte. */
+
+ /* integer wrap paranioa. */
+ if ((offset + namelen < offset) || (offset + namelen < namelen) ||
+ (offset > data_size) || (namelen > data_size) ||
+ (offset + namelen >= data_size)) {
+ break;
+ }
+ /* Ensure the name is null terminated. */
+ if (pdata[offset + namelen] != '\0') {
+ return NULL;
+ }
+ pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset]);
+ if (!eal->ea.name) {
+ return NULL;
+ }
+
+ offset += (namelen + 1); /* Go past the name + terminating zero. */
+ DLIST_ADD_END(ea_list_head, eal, tmp);
+ DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
+ }
+
+ return ea_list_head;
+}
+
+/****************************************************************************
+ Read one EA list entry from the buffer.
+****************************************************************************/
+
+struct ea_list *read_ea_list_entry(TALLOC_CTX *ctx, const char *pdata, size_t data_size, size_t *pbytes_used)
+{
+ struct ea_list *eal = TALLOC_ZERO_P(ctx, struct ea_list);
+ uint16 val_len;
+ unsigned int namelen;
+
+ if (!eal) {
+ return NULL;
}
- if (IVAL(pdata,0) > total_data) {
- DEBUG(10,("set_ea: bad total data size (%u) > %u\n", IVAL(pdata,0), (unsigned int)total_data));
- return NT_STATUS_INVALID_PARAMETER;
+ if (data_size < 6) {
+ return NULL;
}
- pdata += 4;
+ eal->ea.flags = CVAL(pdata,0);
namelen = CVAL(pdata,1);
- ealen = SVAL(pdata,2);
- pdata += 4;
- if (total_data < 8 + namelen + 1 + ealen) {
- DEBUG(10,("set_ea: bad total data size (%u) < 8 + namelen (%u) + 1 + ealen (%u)\n",
- (unsigned int)total_data, namelen, ealen));
- return NT_STATUS_INVALID_PARAMETER;
+ val_len = SVAL(pdata,2);
+
+ if (4 + namelen + 1 + val_len > data_size) {
+ return NULL;
}
- if (pdata[namelen] != '\0') {
- DEBUG(10,("set_ea: ea name not null terminated\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ /* Ensure the name is null terminated. */
+ if (pdata[namelen + 4] != '\0') {
+ return NULL;
+ }
+ pull_ascii_talloc(ctx, &eal->ea.name, pdata + 4);
+ if (!eal->ea.name) {
+ return NULL;
}
- fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
- pull_ascii(&unix_ea_name[5], pdata, sizeof(fstring) - 5, -1, STR_TERMINATE);
- pdata += (namelen + 1);
+ eal->ea.value = data_blob(NULL, (size_t)val_len + 1);
+ if (!eal->ea.value.data) {
+ return NULL;
+ }
- canonicalize_ea_name(conn, fsp, fname, unix_ea_name);
+ memcpy(eal->ea.value.data, pdata + 4 + namelen + 1, val_len);
- DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ealen));
- if (ealen) {
- DEBUG(10,("set_ea: data :\n"));
- dump_data(10, pdata, ealen);
- }
+ /* Ensure we're null terminated just in case we print the value. */
+ eal->ea.value.data[val_len] = '\0';
+ /* But don't count the null. */
+ eal->ea.value.length--;
- if (samba_private_attr_name(unix_ea_name)) {
- DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
- return NT_STATUS_ACCESS_DENIED;
+ if (pbytes_used) {
+ *pbytes_used = 4 + namelen + 1 + val_len;
}
- if (ealen == 0) {
- /* Remove the attribute. */
- if (fsp && (fsp->fd != -1)) {
- DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
- ret = SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, unix_ea_name);
- } else {
- DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_REMOVEXATTR(conn, fname, unix_ea_name);
- }
-#ifdef ENOATTR
- /* Removing a non existent attribute always succeeds. */
- if (ret == -1 && errno == ENOATTR) {
- DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n", unix_ea_name));
- ret = 0;
- }
-#endif
- } else {
- if (fsp && (fsp->fd != -1)) {
- DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
- ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, unix_ea_name, pdata, ealen, 0);
- } else {
- DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
- unix_ea_name, fname));
- ret = SMB_VFS_SETXATTR(conn, fname, unix_ea_name, pdata, ealen, 0);
+ DEBUG(10,("read_ea_list_entry: read ea name %s\n", eal->ea.name));
+ dump_data(10, eal->ea.value.data, eal->ea.value.length);
+
+ return eal;
+}
+
+/****************************************************************************
+ Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
+****************************************************************************/
+
+static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
+{
+ struct ea_list *ea_list_head = NULL;
+ size_t offset = 0;
+ size_t bytes_used = 0;
+
+ while (offset < data_size) {
+ struct ea_list *tmp;
+ struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
+
+ if (!eal) {
+ return NULL;
}
+
+ DLIST_ADD_END(ea_list_head, eal, tmp);
+ offset += bytes_used;
}
- if (ret == -1) {
-#ifdef ENOTSUP
- if (errno == ENOTSUP) {
- return NT_STATUS_EAS_NOT_SUPPORTED;
+ return ea_list_head;
+}
+
+/****************************************************************************
+ Count the total EA size needed.
+****************************************************************************/
+
+static size_t ea_list_size(struct ea_list *ealist)
+{
+ fstring dos_ea_name;
+ struct ea_list *listp;
+ size_t ret = 0;
+
+ for (listp = ealist; listp; listp = listp->next) {
+ push_ascii_fstring(dos_ea_name, listp->ea.name);
+ ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
+ }
+ /* Add on 4 for total length. */
+ if (ret) {
+ ret += 4;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ Return a union of EA's from a file list and a list of names.
+ The TALLOC context for the two lists *MUST* be identical as we steal
+ memory from one list to add to another. JRA.
+****************************************************************************/
+
+static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
+{
+ struct ea_list *nlistp, *flistp;
+
+ for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
+ for (flistp = file_list; flistp; flistp = flistp->next) {
+ if (strequal(nlistp->ea.name, flistp->ea.name)) {
+ break;
+ }
+ }
+
+ if (flistp) {
+ /* Copy the data from this entry. */
+ nlistp->ea.flags = flistp->ea.flags;
+ nlistp->ea.value = flistp->ea.value;
+ } else {
+ /* Null entry. */
+ nlistp->ea.flags = 0;
+ ZERO_STRUCT(nlistp->ea.value);
}
-#endif
- return map_nt_error_from_unix(errno);
}
- return NT_STATUS_OK;
+ *total_ea_len = ea_list_size(name_list);
+ return name_list;
}
/****************************************************************************
@@ -447,7 +575,6 @@ static int send_trans2_replies(char *outbuf,
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;
@@ -587,6 +714,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
unsigned int max_data_bytes)
{
char *params = *pparams;
+ char *pdata = *ppdata;
int16 open_mode;
int16 open_attr;
BOOL oplock_request;
@@ -606,18 +734,27 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
int smb_action = 0;
BOOL bad_path = False;
files_struct *fsp;
+ TALLOC_CTX *ctx = NULL;
+ struct ea_list *ea_list = NULL;
+ uint16 flags = 0;
NTSTATUS status;
/*
* Ensure we have enough parameters to perform the operation.
*/
- if (total_params < 29)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 29) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ flags = SVAL(params, 0);
open_mode = SVAL(params, 2);
open_attr = SVAL(params,6);
- oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ if (oplock_request) {
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+ }
+
#if 0
return_additional_info = BITSETW(params,0);
open_sattr = SVAL(params, 4);
@@ -635,7 +772,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return ERROR_NT(status);
}
- DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
+ DEBUG(3,("call_trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
fname,open_mode, open_attr, open_ofun, open_size));
/* XXXX we need to handle passed times, sattr and flags */
@@ -649,13 +786,47 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
+ /* Strange open mode mapping. */
+ if (open_ofun == 0) {
+ if (GET_OPEN_MODE(open_mode) == DOS_OPEN_EXEC) {
+ open_ofun = FILE_EXISTS_FAIL | FILE_CREATE_IF_NOT_EXIST;
+ }
+ }
+
+ /* Any data in this call is an EA list. */
+ if (total_data && !lp_ea_support(SNUM(conn))) {
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
+
+ if (total_data) {
+ if (total_data < 10) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (IVAL(pdata,0) > total_data) {
+ DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
+ IVAL(pdata,0), (unsigned int)total_data));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ctx = talloc_init("TRANS2_OPEN_SET_EA");
+ if (!ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+ if (!ea_list) {
+ talloc_destroy(ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,(uint32)open_attr,
oplock_request, &rmode,&smb_action);
if (!fsp) {
+ talloc_destroy(ctx);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
- clear_cached_errors();
return -1;
}
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
@@ -666,25 +837,37 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
if (fmode & aDIR) {
+ talloc_destroy(ctx);
close_file(fsp,False);
return(ERROR_DOS(ERRDOS,ERRnoaccess));
}
+ if (total_data && smb_action == FILE_WAS_CREATED) {
+ status = set_ea(conn, fsp, fname, ea_list);
+ talloc_destroy(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ close_file(fsp,False);
+ return ERROR_NT(status);
+ }
+ }
+
/* Realloc the size of parameters and data we will return */
- params = SMB_REALLOC(*pparams, 28);
- if( params == NULL )
- return(ERROR_DOS(ERRDOS,ERRnomem));
+ params = SMB_REALLOC(*pparams, 30);
+ if( params == NULL ) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
- memset((char *)params,'\0',28);
+ memset((char *)params,'\0',30);
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)))
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
SSVAL(params,18,smb_action);
@@ -692,9 +875,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
* WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
*/
SIVAL(params,20,inode);
-
+ if (flags & 8) {
+ uint32 ea_size = estimate_ea_size(conn, fsp, fname);
+ SIVAL(params, 26, ea_size);
+ }
+
/* Send the required number of replies */
- send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
return -1;
}
@@ -811,7 +998,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
BOOL dont_descend,char **ppdata,
char *base_data, int space_remaining,
BOOL *out_of_space, BOOL *got_exact_match,
- int *last_entry_off)
+ int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx)
{
const char *dname;
BOOL found = False;
@@ -970,8 +1157,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
switch (info_level) {
- case SMB_INFO_STANDARD:
- DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_STANDARD\n"));
+ case SMB_FIND_INFO_STANDARD:
+ DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
@@ -1002,8 +1189,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p += len;
break;
- case SMB_INFO_QUERY_EA_SIZE:
- DEBUG(10,("get_lanman2_dir_entry: SMB_INFO_QUERY_EA_SIZE\n"));
+ case SMB_FIND_EA_SIZE:
+ DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
@@ -1039,6 +1226,63 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
break;
+ case SMB_FIND_EA_LIST:
+ {
+ struct ea_list *file_list = NULL;
+ size_t ea_len = 0;
+
+ DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
+ if (!name_list) {
+ return False;
+ }
+ 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)file_size);
+ SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
+ SSVAL(p,l2_attrFile,mode);
+ p += l2_cbList; /* p now points to the EA area. */
+
+ file_list = get_ea_list_from_file(ea_ctx, conn, NULL, pathreal, &ea_len);
+ name_list = ea_list_union(name_list, file_list, &ea_len);
+
+ /* We need to determine if this entry will fit in the space available. */
+ /* Max string size is 255 bytes. */
+ if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
+ /* Move the dirptr back to prev_dirpos */
+ dptr_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 */
+ }
+
+ /* Push the ea_data followed by the name. */
+ p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list);
+ nameptr = p;
+ len = srvstr_push(outbuf, p + 1, fname, -1, STR_TERMINATE | STR_NOALIGN);
+ if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) {
+ if (len > 2) {
+ len -= 2;
+ } else {
+ len = 0;
+ }
+ } else {
+ if (len > 1) {
+ len -= 1;
+ } else {
+ len = 0;
+ }
+ }
+ SCVAL(nameptr,0,len);
+ p += len + 1;
+ SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
+ break;
+ }
+
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
was_8_3 = mangle_is_8_3(fname, True);
@@ -1338,10 +1582,13 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
int space_remaining;
BOOL bad_path = False;
SMB_STRUCT_STAT sbuf;
+ TALLOC_CTX *ea_ctx = NULL;
+ struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
- if (total_params < 12)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 12) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
*directory = *mask = 0;
@@ -1356,8 +1603,9 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
}
switch (info_level) {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
+ case SMB_FIND_INFO_STANDARD:
+ case SMB_FIND_EA_SIZE:
+ case SMB_FIND_EA_LIST:
case SMB_FIND_FILE_DIRECTORY_INFO:
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
case SMB_FIND_FILE_NAMES_INFO:
@@ -1378,7 +1626,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return ERROR_NT(ntstatus);
}
- RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH_WCARD(directory, conn, inbuf, outbuf);
unix_convert(directory,conn,0,&bad_path,&sbuf);
if (bad_path) {
@@ -1403,29 +1651,66 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
+ if (info_level == SMB_FIND_EA_LIST) {
+ uint32 ea_size;
+
+ if (total_data < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ea_size = IVAL(pdata,0);
+ if (ea_size != total_data) {
+ DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return ERROR_DOS(ERRDOS,ERReasnotsupported);
+ }
+
+ if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ /* Pull out the list of names. */
+ ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+ if (!ea_list) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
- if( pdata == NULL )
- return(ERROR_DOS(ERRDOS,ERRnomem));
+ if( pdata == NULL ) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*ppdata = pdata;
memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
/* Realloc the params space */
params = SMB_REALLOC(*pparams, 10);
- if (params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if (params == NULL) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
+ if (dptr_num < 0) {
+ talloc_destroy(ea_ctx);
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 (!dptr_set_wcard_and_attributes(dptr_num, mask, dirtype)) {
dptr_close(&dptr_num);
- return ERROR_DOS(ERRDOS,ERRnomem);
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
}
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
@@ -1455,7 +1740,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
mask,dirtype,info_level,
requires_resume_key,dont_descend,
&p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_entry_off);
+ &last_entry_off, ea_list, ea_ctx);
}
if (finished && out_of_space)
@@ -1477,6 +1762,8 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
}
+ talloc_destroy(ea_ctx);
+
/* 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));
@@ -1566,10 +1853,13 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
BOOL dont_descend = False;
BOOL out_of_space = False;
int space_remaining;
+ TALLOC_CTX *ea_ctx = NULL;
+ struct ea_list *ea_list = NULL;
NTSTATUS ntstatus = NT_STATUS_OK;
- if (total_params < 12)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 12) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
*mask = *directory = *resume_name = 0;
@@ -1600,8 +1890,9 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
}
switch (info_level) {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
+ case SMB_FIND_INFO_STANDARD:
+ case SMB_FIND_EA_SIZE:
+ case SMB_FIND_EA_LIST:
case SMB_FIND_FILE_DIRECTORY_INFO:
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
case SMB_FIND_FILE_NAMES_INFO:
@@ -1615,29 +1906,66 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
+ if (info_level == SMB_FIND_EA_LIST) {
+ uint32 ea_size;
+
+ if (total_data < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ea_size = IVAL(pdata,0);
+ if (ea_size != total_data) {
+ DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return ERROR_DOS(ERRDOS,ERReasnotsupported);
+ }
+
+ if ((ea_ctx = talloc_init("findnext_ea_list")) == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ /* Pull out the list of names. */
+ ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+ if (!ea_list) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
pdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
- if(pdata == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(pdata == NULL) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*ppdata = pdata;
memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
/* Realloc the params space */
params = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
- if( params == NULL )
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if( params == NULL ) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
/* Check that the dptr is valid */
- if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
+ if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num))) {
+ talloc_destroy(ea_ctx);
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));
+ talloc_destroy(ea_ctx);
return ERROR_DOS(ERRDOS,ERRnofiles);
}
@@ -1708,7 +2036,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
mask,dirtype,info_level,
requires_resume_key,dont_descend,
&p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_entry_off);
+ &last_entry_off, ea_list, ea_ctx);
}
if (finished && out_of_space)
@@ -1730,6 +2058,8 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
}
+ talloc_destroy(ea_ctx);
+
/* 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));
@@ -1780,8 +2110,9 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
}
pdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
- if ( pdata == NULL )
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if ( pdata == NULL ) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*ppdata = pdata;
memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
@@ -1830,7 +2161,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
* the called hostname and the service name.
*/
SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(get_local_machine_name())<<16) );
- len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
+ /*
+ * Win2k3 and previous mess this up by sending a name length
+ * one byte short. I believe only older clients (OS/2 Win9x) use
+ * this call so try fixing this by adding a terminating null to
+ * the pushed string. The change here was adding the STR_TERMINATE. JRA.
+ */
+ len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN|STR_TERMINATE);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
@@ -2098,7 +2435,7 @@ static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outb
if (total_params < 4) {
DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
total_params));
- return ERROR_DOS(ERRDOS,ERRinvalidparam);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
fsp = file_fsp(params,0);
@@ -2333,7 +2670,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
int mode=0;
SMB_OFF_T file_size=0;
SMB_BIG_UINT allocation_size=0;
- unsigned int data_size;
+ unsigned int data_size = 0;
unsigned int param_size = 2;
SMB_STRUCT_STAT sbuf;
pstring fname, dos_fname;
@@ -2346,6 +2683,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
int len;
time_t c_time;
files_struct *fsp = NULL;
+ TALLOC_CTX *ea_ctx = NULL;
+ struct ea_list *ea_list = NULL;
uint32 desired_access = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
if (!params)
@@ -2354,8 +2693,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
ZERO_STRUCT(sbuf);
if (tran_call == TRANSACT2_QFILEINFO) {
- if (total_params < 4)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
@@ -2410,8 +2750,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
NTSTATUS status = NT_STATUS_OK;
/* qpathinfo */
- if (total_params < 6)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 6) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
info_level = SVAL(params,0);
@@ -2463,7 +2804,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
fullpathname = fname;
file_size = get_file_size(sbuf);
- allocation_size = get_allocation_size(conn,fsp,&sbuf);
if (mode & aDIR) {
/* This is necessary, as otherwise the desktop.ini file in
* this folder is ignored */
@@ -2471,27 +2811,58 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
file_size = 0;
}
+ /* Pull any EA list from the data portion. */
+ if (info_level == SMB_INFO_QUERY_EAS_FROM_LIST) {
+ uint32 ea_size;
+
+ if (total_data < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ ea_size = IVAL(pdata,0);
+
+ if (total_data > 0 && ea_size != total_data) {
+ DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return ERROR_DOS(ERRDOS,ERReasnotsupported);
+ }
+
+ if ((ea_ctx = talloc_init("ea_list")) == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ /* Pull out the list of names. */
+ ea_list = read_ea_name_list(ea_ctx, pdata + 4, ea_size - 4);
+ if (!ea_list) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
params = SMB_REALLOC(*pparams,2);
- if (params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if (params == NULL) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
memset((char *)params,'\0',2);
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
pdata = SMB_REALLOC(*ppdata, data_size);
- if ( pdata == NULL )
- 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_DOS(ERRDOS,ERReasnotsupported);
+ if ( pdata == NULL ) {
+ talloc_destroy(ea_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
}
+ *ppdata = pdata;
memset((char *)pdata,'\0',data_size);
c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ allocation_size = get_allocation_size(conn,fsp,&sbuf);
+
if (fsp) {
if (fsp->pending_modtime) {
/* the pending modtime overrides the current modtime */
@@ -2504,6 +2875,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
/* the pending modtime overrides the current modtime */
sbuf.st_mtime = fsp1->pending_modtime;
}
+ if (fsp1 && fsp1->initial_allocation_size) {
+ allocation_size = get_allocation_size(conn, fsp1, &sbuf);
+ }
}
if (lp_dos_filetime_resolution(SNUM(conn))) {
@@ -2560,21 +2934,51 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
break;
case SMB_INFO_QUERY_EAS_FROM_LIST:
+ {
+ size_t total_ea_len = 0;
+ struct ea_list *ea_file_list = NULL;
+
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- data_size = 24;
- put_dos_date2(pdata,0,c_time);
- put_dos_date2(pdata,4,sbuf.st_atime);
- put_dos_date2(pdata,8,sbuf.st_mtime);
- SIVAL(pdata,12,(uint32)file_size);
- SIVAL(pdata,16,(uint32)allocation_size);
- SIVAL(pdata,20,mode);
+
+ ea_file_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
+ ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
+
+ if (!ea_list || (total_ea_len > data_size)) {
+ talloc_destroy(ea_ctx);
+ data_size = 4;
+ SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
+ break;
+ }
+
+ data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
+ talloc_destroy(ea_ctx);
break;
+ }
case SMB_INFO_QUERY_ALL_EAS:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+ {
/* We have data_size bytes to put EA's into. */
- data_size = fill_ea_buffer(pdata, data_size, conn, fsp, fname);
+ size_t total_ea_len = 0;
+
+ DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+
+ ea_ctx = talloc_init("ea_ctx");
+ if (!ea_ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ ea_list = get_ea_list_from_file(ea_ctx, conn, fsp, fname, &total_ea_len);
+ if (!ea_list || (total_ea_len > data_size)) {
+ talloc_destroy(ea_ctx);
+ data_size = 4;
+ SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
+ break;
+ }
+
+ data_size = fill_ea_buffer(ea_ctx, pdata, data_size, conn, ea_list);
+ talloc_destroy(ea_ctx);
break;
+ }
case SMB_FILE_BASIC_INFORMATION:
case SMB_QUERY_FILE_BASIC_INFO:
@@ -3177,10 +3581,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
ZERO_STRUCT(sbuf);
+ ZERO_STRUCT(tvs);
if (tran_call == TRANSACT2_SETFILEINFO) {
- if (total_params < 4)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
@@ -3226,8 +3632,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
} else {
/* set path info */
- if (total_params < 6)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 6) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
info_level = SVAL(params,0);
srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
@@ -3266,10 +3673,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
- /* Realloc the parameter and data sizes */
+ /* Realloc the parameter size */
params = SMB_REALLOC(*pparams,2);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(params == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
SSVAL(params,0,0);
@@ -3291,8 +3699,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
switch (info_level) {
case SMB_INFO_STANDARD:
{
- if (total_data < 12)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 12) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
/* access time */
tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
@@ -3302,17 +3711,50 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
case SMB_INFO_SET_EA:
- status = set_ea(conn, fsp, fname, pdata, total_data);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ {
+ struct ea_list *ea_list = NULL;
+ TALLOC_CTX *ctx = NULL;
+
+ if (total_data < 10) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (IVAL(pdata,0) > total_data) {
+ DEBUG(10,("call_trans2setfilepathinfo: bad total data size (%u) > %u\n",
+ IVAL(pdata,0), (unsigned int)total_data));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ctx = talloc_init("SMB_INFO_SET_EA");
+ if (!ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+ if (!ea_list) {
+ talloc_destroy(ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ status = set_ea(conn, fsp, fname, ea_list);
+ talloc_destroy(ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
- break;
+ }
+ /* We're done. We only get EA info in this call. */
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+
+#if 0
+ /* The following 2 info levels are only valid on query, not set. Remove them. JRA. */
/* 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));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
tvs.actime = make_unix_date2(pdata+8);
tvs.modtime = make_unix_date2(pdata+12);
@@ -3323,13 +3765,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
/* XXXX nor this. not in cifs6.txt, either. */
case SMB_INFO_QUERY_ALL_EAS:
if (total_data < 28)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
tvs.actime = make_unix_date2(pdata+8);
tvs.modtime = make_unix_date2(pdata+12);
size = IVAL(pdata,16);
dosmode = IVAL(pdata,24);
break;
+#endif
case SMB_SET_FILE_BASIC_INFO:
case SMB_FILE_BASIC_INFORMATION:
@@ -3338,8 +3781,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
time_t write_time;
time_t changed_time;
- if (total_data < 36)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 36) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
/* Ignore create time at offset pdata. */
@@ -3370,8 +3814,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
int ret = -1;
SMB_BIG_UINT allocation_size;
- if (total_data < 8)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 8) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
allocation_size = (SMB_BIG_UINT)IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
@@ -3444,8 +3889,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_SET_FILE_END_OF_FILE_INFO:
{
- if (total_data < 8)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 8) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
@@ -3463,8 +3909,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
{
BOOL delete_on_close;
- if (total_data < 1)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 1) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
delete_on_close = (CVAL(pdata,0) ? True : False);
@@ -3477,23 +3924,28 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
status = set_delete_on_close_internal(fsp, delete_on_close, dosmode);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
+ }
/* The set is across all open files on this dev/inode pair. */
status =set_delete_on_close_over_all(fsp, delete_on_close);
- if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
+ }
- break;
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
}
case SMB_FILE_POSITION_INFORMATION:
{
SMB_BIG_UINT position_information;
- if (total_data < 8)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 8) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
position_information = (SMB_BIG_UINT)IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
@@ -3504,9 +3956,38 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
fname, (double)position_information ));
- if (fsp)
+ if (fsp) {
fsp->position_information = position_information;
- break;
+ }
+
+ /* We're done. We only get position info in this call. */
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+
+ /* From tridge Samba4 :
+ * MODE_INFORMATION in setfileinfo (I have no
+ * idea what "mode information" on a file is - it takes a value of 0,
+ * 2, 4 or 6. What could it be?).
+ */
+
+ case SMB_FILE_MODE_INFORMATION:
+ {
+ uint32 mode;
+
+ if (total_data < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ mode = IVAL(pdata,0);
+ if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ /* We're done. We only get mode info in this call. */
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
}
/*
@@ -3517,8 +3998,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
{
uint32 raw_unixmode;
- if (total_data < 100)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 100) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
@@ -3567,8 +4049,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (tran_call == TRANSACT2_SETFILEINFO)
return(ERROR_DOS(ERRDOS,ERRnoaccess));
- if (raw_unixmode == SMB_MODE_NO_CHANGE)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (raw_unixmode == SMB_MODE_NO_CHANGE) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
#if defined(HAVE_MAKEDEV)
dev = makedev(dev_major, dev_minor);
@@ -3736,8 +4219,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
pstring base_name;
char *p;
- if (total_data < 12)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_data < 12) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
overwrite = (CVAL(pdata,0) ? True : False);
root_fid = IVAL(pdata,4);
@@ -3790,7 +4274,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
BOOL valid_def_acls = True;
if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
posix_acl_version = SVAL(pdata,0);
num_file_acls = SVAL(pdata,2);
@@ -3807,12 +4291,12 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
(num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
@@ -3971,17 +4455,21 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
unsigned int max_data_bytes)
{
char *params = *pparams;
+ char *pdata = *ppdata;
pstring directory;
int ret = -1;
SMB_STRUCT_STAT sbuf;
BOOL bad_path = False;
NTSTATUS status = NT_STATUS_OK;
+ TALLOC_CTX *ctx = NULL;
+ struct ea_list *ea_list = NULL;
if (!CAN_WRITE(conn))
return ERROR_DOS(ERRSRV,ERRaccess);
- if (total_params < 4)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 4) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
if (!NT_STATUS_IS_OK(status)) {
@@ -3994,18 +4482,58 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
if (bad_path) {
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
- if (check_name(directory,conn))
+
+ /* Any data in this call is an EA list. */
+ if (total_data && !lp_ea_support(SNUM(conn))) {
+ return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
+ }
+
+ if (total_data) {
+ if (total_data < 10) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (IVAL(pdata,0) > total_data) {
+ DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
+ IVAL(pdata,0), (unsigned int)total_data));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ ctx = talloc_init("TRANS2_MKDIR_SET_EA");
+ if (!ctx) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
+ if (!ea_list) {
+ talloc_destroy(ctx);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ if (check_name(directory,conn)) {
ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
+ }
if(ret < 0) {
+ talloc_destroy(ctx);
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
}
+ /* Try and set any given EA. */
+ if (total_data) {
+ status = set_ea(conn, NULL, directory, ea_list);
+ talloc_destroy(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+ }
+
/* Realloc the parameter and data sizes */
params = SMB_REALLOC(*pparams,2);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(params == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
SSVAL(params,0,0);
@@ -4028,8 +4556,9 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
char *params = *pparams;
uint16 info_level;
- if (total_params < 6)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 6) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
info_level = SVAL(params,4);
DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
@@ -4044,8 +4573,9 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
/* Realloc the parameter and data sizes */
params = SMB_REALLOC(*pparams,6);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(params == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
SSVAL(params,0,fnf_handle);
@@ -4077,8 +4607,9 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char
/* Realloc the parameter and data sizes */
params = SMB_REALLOC(*pparams,4);
- if(params == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(params == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*pparams = params;
SSVAL(params,0,0); /* No changes */
@@ -4104,8 +4635,9 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
DEBUG(10,("call_trans2getdfsreferral\n"));
- if (total_params < 2)
- return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ if (total_params < 2) {
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
max_referral_level = SVAL(params,0);
@@ -4144,8 +4676,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf,
if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
(SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
pdata = SMB_REALLOC(*ppdata, 32);
- if(pdata == NULL)
- return ERROR_DOS(ERRDOS,ERRnomem);
+ if(pdata == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
*ppdata = pdata;
/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
@@ -4288,7 +4821,7 @@ int reply_trans2(connection_struct *conn,
DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
DEBUG(2,("Transaction is %d\n",tran_call));
END_PROFILE(SMBtrans2);
- ERROR_DOS(ERRDOS,ERRinvalidparam);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
}
@@ -4303,7 +4836,7 @@ int reply_trans2(connection_struct *conn,
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
- return ERROR_DOS(ERRDOS,ERRnomem);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
}
/* Copy the param and data bytes sent with this request into
@@ -4352,6 +4885,9 @@ int reply_trans2(connection_struct *conn,
unsigned int data_off;
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+ /* We need to re-calcuate the new length after we've read the secondary packet. */
+ length = smb_len(inbuf) + 4;
/*
* The sequence number for the trans reply is always
@@ -4399,7 +4935,7 @@ int reply_trans2(connection_struct *conn,
goto bad_param;
if (param_disp > total_params)
goto bad_param;
- if ((smb_base(inbuf) + param_off + num_params >= inbuf + bufsize) ||
+ if ((smb_base(inbuf) + param_off + num_params > inbuf + length) ||
(smb_base(inbuf) + param_off + num_params < smb_base(inbuf)))
goto bad_param;
if (params + param_disp < params)
@@ -4415,7 +4951,7 @@ int reply_trans2(connection_struct *conn,
goto bad_param;
if (data_disp > total_data)
goto bad_param;
- if ((smb_base(inbuf) + data_off + num_data >= inbuf + bufsize) ||
+ if ((smb_base(inbuf) + data_off + num_data > inbuf + length) ||
(smb_base(inbuf) + data_off + num_data < smb_base(inbuf)))
goto bad_param;
if (data + data_disp < data)
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index bf60c2bc68c..edcc7a5c2f9 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -1224,7 +1224,7 @@ a wrapper for lseek()
off_t smbw_lseek(int fd, off_t offset, int whence)
{
struct smbw_file *file;
- size_t size;
+ SMB_OFF_T size;
smbw_busy++;
diff --git a/source/smbwrapper/smbw_stat.c b/source/smbwrapper/smbw_stat.c
index bb76ef006a4..6effc9a71bc 100644
--- a/source/smbwrapper/smbw_stat.c
+++ b/source/smbwrapper/smbw_stat.c
@@ -69,17 +69,33 @@ BOOL smbw_getatr(struct smbw_server *srv, char *path,
time_t *c_time, time_t *a_time, time_t *m_time,
SMB_INO_T *ino)
{
+ time_t c_a_m_time;
+ /*
+ * "size" (size_t) is only 32 bits. Rather than change the interface
+ * in this code as we change cli_qpathinfo2() and cli_getatr() to
+ * support 64-bit file sizes, we'll use a temporary variable and
+ * maintain the interface size_t. At some point, someone may want to
+ * change the interface as well. djl
+ */
+ SMB_OFF_T fullsize;
+
DEBUG(4,("sending qpathinfo\n"));
if (!srv->no_pathinfo2 &&
cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL,
- size, mode, ino)) return True;
+ &fullsize, mode, ino)) {
+ if (size != NULL) *size = (size_t) fullsize;
+ 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;
+ if (cli_getatr(&srv->cli, path, mode, &fullsize, &c_a_m_time)) {
+ if (a_time != NULL) *a_time = c_a_m_time;
+ if (c_time != NULL) *a_time = c_a_m_time;
+ if (m_time != NULL) *a_time = c_a_m_time;
+ if (size != NULL) *size = (size_t) fullsize;
srv->no_pathinfo2 = True;
return True;
}
@@ -129,7 +145,7 @@ int smbw_fstat(int fd, struct stat *st)
{
struct smbw_file *file;
time_t c_time, a_time, m_time;
- size_t size;
+ SMB_OFF_T size;
uint16 mode;
SMB_INO_T ino = 0;
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index f66e50afe46..7159550c0c2 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -128,7 +128,7 @@
/* 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)
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(CONST_DISCARD(void *, (x))); (x)=NULL;} } while(0)
#endif
#define BUCKET(hash) ((hash) % tdb->header.hash_size)
diff --git a/source/tdb/tdbbackup.c b/source/tdb/tdbbackup.c
index 1a0e1c1588f..f49cd339c79 100644
--- a/source/tdb/tdbbackup.c
+++ b/source/tdb/tdbbackup.c
@@ -69,6 +69,9 @@
#include "tdb.h"
#include "tdbback.h"
+extern int optind;
+extern char *optarg;
+
/*
see if one file is newer than another
*/
@@ -100,8 +103,6 @@ static void usage(void)
int c;
int verify = 0;
const char *suffix = ".bak";
- extern int optind;
- extern char *optarg;
while ((c = getopt(argc, argv, "vhs:")) != -1) {
switch (c) {
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 92009dcef48..2de3df961cf 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -131,7 +131,7 @@ static void help(void)
"\n");
}
-static void terror(char *why)
+static void terror(const char *why)
{
printf("%s\n", why);
}
@@ -407,7 +407,7 @@ static void info_tdb(void)
printf("%d records totalling %d bytes\n", count, total_bytes);
}
-static char *tdb_getline(char *prompt)
+static char *tdb_getline(const char *prompt)
{
static char line[1024];
char *p;
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index 45ebdae3af0..4fcfb6185ae 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -40,14 +40,19 @@ static void gotalarm_sig(void)
Make a TDB_DATA and keep the const warning in one place
****************************************************************/
-static TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
+TDB_DATA make_tdb_data(const char *dptr, size_t dsize)
{
TDB_DATA ret;
- ret.dptr = dptr;
+ ret.dptr = CONST_DISCARD(char *, dptr);
ret.dsize = dsize;
return ret;
}
+TDB_DATA string_tdb_data(const char *string)
+{
+ return make_tdb_data(string, strlen(string));
+}
+
/****************************************************************************
Lock a chain with timeout (in seconds).
****************************************************************************/
@@ -57,7 +62,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
/* Allow tdb_chainlock to be interrupted by an alarm. */
int ret;
gotalarm = 0;
- tdb_set_lock_alarm(&gotalarm);
+ tdb_set_lock_alarm(CONST_DISCARD(sig_atomic_t *, &gotalarm));
if (timeout) {
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
diff --git a/source/torture/torture.c b/source/torture/torture.c
index b37a30cf2e3..8a4de57e7ff 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -590,7 +590,7 @@ static BOOL run_readwritelarge(int dummy)
static struct cli_state *cli1;
int fnum1;
const char *lockfname = "\\large.dat";
- size_t fsize;
+ SMB_OFF_T fsize;
char buf[126*1024];
BOOL correct = True;
@@ -2360,7 +2360,7 @@ static BOOL run_trans2test(int dummy)
{
struct cli_state *cli;
int fnum;
- size_t size;
+ SMB_OFF_T size;
time_t c_time, a_time, m_time, w_time, m_time2;
const char *fname = "\\trans2.tst";
const char *dname = "\\trans2";
@@ -3591,7 +3591,7 @@ static BOOL run_opentest(int dummy)
const char *fname = "\\readonly.file";
int fnum1, fnum2;
char buf[20];
- size_t fsize;
+ SMB_OFF_T fsize;
BOOL correct = True;
char *tmp_path;
diff --git a/source/torture/utable.c b/source/torture/utable.c
index ba803a0da4f..c9b30f06e1c 100644
--- a/source/torture/utable.c
+++ b/source/torture/utable.c
@@ -137,7 +137,7 @@ BOOL torture_casetable(int dummy)
}
for (c=1; c < 0x10000; c++) {
- size_t size;
+ SMB_OFF_T size;
if (c == '.' || c == '\\') continue;
diff --git a/source/utils/net.c b/source/utils/net.c
index 9c05828357c..61c366710c6 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -87,6 +87,7 @@ const char *opt_destination = NULL;
BOOL opt_have_ip = False;
struct in_addr opt_dest_ip;
+extern struct in_addr loopback_ip;
extern BOOL AllowDebugChange;
uint32 get_sec_channel_type(const char *param)
@@ -321,7 +322,6 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
}
*server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
} else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
- extern struct in_addr loopback_ip;
*server_ip = loopback_ip;
*server_name = SMB_STRDUP("127.0.0.1");
}
@@ -632,62 +632,38 @@ static int net_afs(int argc, const char **argv)
#endif /* WITH_FAKE_KASERVER */
-static uint32 get_maxrid(void)
+static BOOL search_maxrid(struct pdb_search *search, const char *type,
+ uint32 *max_rid)
{
- SAM_ACCOUNT *pwd = NULL;
- uint32 max_rid = 0;
- GROUP_MAP *map = NULL;
- int num_entries = 0;
- int i;
-
- if (!pdb_setsampwent(False, 0)) {
- DEBUG(0, ("get_maxrid: Unable to open passdb.\n"));
- return 0;
- }
+ struct samr_displayentry *entries;
+ uint32 i, num_entries;
- for (; (NT_STATUS_IS_OK(pdb_init_sam(&pwd)))
- && pdb_getsampwent(pwd) == True; pwd=NULL) {
- uint32 rid;
-
- if (!sid_peek_rid(pdb_get_user_sid(pwd), &rid)) {
- DEBUG(0, ("can't get RID for user '%s'\n",
- pdb_get_username(pwd)));
- pdb_free_sam(&pwd);
- continue;
- }
-
- if (rid > max_rid)
- max_rid = rid;
-
- DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd)));
- pdb_free_sam(&pwd);
+ if (search == NULL) {
+ d_printf("get_maxrid: Could not search %s\n", type);
+ return False;
}
- pdb_endsampwent();
- pdb_free_sam(&pwd);
-
- if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
- ENUM_ONLY_MAPPED))
- return max_rid;
-
- for (i = 0; i < num_entries; i++) {
- uint32 rid;
+ num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
+ for (i=0; i<num_entries; i++)
+ *max_rid = MAX(*max_rid, entries[i].rid);
+ pdb_search_destroy(search);
+ return True;
+}
- if (!sid_peek_check_rid(get_global_sam_sid(), &map[i].sid,
- &rid)) {
- DEBUG(3, ("skipping map for group '%s', SID %s\n",
- map[i].nt_name,
- sid_string_static(&map[i].sid)));
- continue;
- }
- DEBUG(1,("%d is group '%s'\n", rid, map[i].nt_name));
+static uint32 get_maxrid(void)
+{
+ uint32 max_rid = 0;
- if (rid > max_rid)
- max_rid = rid;
- }
+ if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
+ return 0;
- SAFE_FREE(map);
+ if (!search_maxrid(pdb_search_groups(), "groups", &max_rid))
+ return 0;
+ if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
+ "aliases", &max_rid))
+ return 0;
+
return max_rid;
}
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 9c00f05bfbb..34a357cd46d 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -81,7 +81,7 @@ static int net_ads_lookup(int argc, const char **argv)
d_printf("Didn't find the cldap server!\n");
return -1;
} if (!ads->config.realm) {
- ads->config.realm = opt_target_workgroup;
+ ads->config.realm = CONST_DISCARD(char *, opt_target_workgroup);
ads->ldap_port = 389;
}
@@ -1168,7 +1168,7 @@ static int net_ads_password(int argc, const char **argv)
}
if (argv[1]) {
- new_password = (char *)argv[1];
+ new_password = CONST_DISCARD(char *, argv[1]);
} else {
asprintf(&prompt, "Enter new password for %s:", user);
new_password = getpass(prompt);
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
index a63e8176f8a..b20a37c7267 100644
--- a/source/utils/net_groupmap.c
+++ b/source/utils/net_groupmap.c
@@ -693,12 +693,37 @@ static int net_groupmap_listmem(int argc, const char **argv)
return 0;
}
+static BOOL print_alias_memberships(TALLOC_CTX *mem_ctx,
+ const DOM_SID *domain_sid,
+ const DOM_SID *member)
+{
+ uint32 *alias_rids;
+ int i, num_alias_rids;
+
+ alias_rids = NULL;
+ num_alias_rids = 0;
+
+ if (!pdb_enum_alias_memberships(mem_ctx, domain_sid, member, 1,
+ &alias_rids, &num_alias_rids)) {
+ d_printf("Could not list memberships for sid %s\n",
+ sid_string_static(member));
+ return False;
+ }
+
+ for (i = 0; i < num_alias_rids; i++) {
+ DOM_SID alias;
+ sid_copy(&alias, domain_sid);
+ sid_append_rid(&alias, alias_rids[i]);
+ printf("%s\n", sid_string_static(&alias));
+ }
+
+ return True;
+}
+
static int net_groupmap_memberships(int argc, const char **argv)
{
- DOM_SID member;
- DOM_SID *aliases;
- int i, num;
- NTSTATUS result;
+ TALLOC_CTX *mem_ctx;
+ DOM_SID *domain_sid, *builtin_sid, member;
if ( (argc != 1) ||
!string_to_sid(&member, argv[0]) ) {
@@ -706,17 +731,24 @@ static int net_groupmap_memberships(int argc, const char **argv)
return -1;
}
- if (!pdb_enum_alias_memberships(&member, 1, &aliases, &num)) {
- d_printf("Could not list memberships for sid %s: %s\n",
- argv[0], nt_errstr(result));
+ mem_ctx = talloc_init("net_groupmap_memberships");
+ if (mem_ctx == NULL) {
+ d_printf("talloc_init failed\n");
return -1;
}
- for (i = 0; i < num; i++) {
- printf("%s\n", sid_string_static(&(aliases[i])));
+ domain_sid = get_global_sam_sid();
+ builtin_sid = string_sid_talloc(mem_ctx, "S-1-5-32");
+ if ((domain_sid == NULL) || (builtin_sid == NULL)) {
+ d_printf("Could not get domain sid\n");
+ return -1;
}
- SAFE_FREE(aliases);
+ if (!print_alias_memberships(mem_ctx, domain_sid, &member) ||
+ !print_alias_memberships(mem_ctx, builtin_sid, &member))
+ return -1;
+
+ talloc_destroy(mem_ctx);
return 0;
}
diff --git a/source/utils/net_lookup.c b/source/utils/net_lookup.c
index 7e5f12da454..9ddfe625081 100644
--- a/source/utils/net_lookup.c
+++ b/source/utils/net_lookup.c
@@ -193,7 +193,7 @@ static int net_lookup_kdc(int argc, const char **argv)
}
if (argc>0) {
- realm.data = (krb5_pointer) argv[0];
+ realm.data = CONST_DISCARD(krb5_pointer, argv[0]);
realm.length = strlen(argv[0]);
} else if (lp_realm() && *lp_realm()) {
realm.data = (krb5_pointer) lp_realm();
@@ -209,7 +209,7 @@ static int net_lookup_kdc(int argc, const char **argv)
realm.length = strlen(realm.data);
}
- rc = krb5_locate_kdc(ctx, &realm, &addrs, &num_kdcs, 0);
+ rc = krb5_locate_kdc(ctx, &realm, (struct sockaddr **) &addrs, &num_kdcs, 0);
if (rc) {
DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
return -1;
diff --git a/source/utils/net_rap.c b/source/utils/net_rap.c
index 6e8f0d088da..8205fe3fda9 100644
--- a/source/utils/net_rap.c
+++ b/source/utils/net_rap.c
@@ -589,9 +589,7 @@ static int net_rap_user_usage(int argc, const char **argv)
return net_help_user(argc, argv);
}
-static void user_fn(const char *user_name, const char *comment,
- const char * home_dir, const char * logon_script,
- void *state)
+static void user_fn(const char *user_name, void *state)
{
d_printf("%-21.21s\n", user_name);
}
@@ -696,7 +694,7 @@ int net_rap_user(int argc, const char **argv)
cli_shutdown(cli);
goto done;
}
- ret = cli_RNetUserEnum(cli, user_fn, NULL);
+ ret = cli_RNetUserEnum0(cli, user_fn, NULL);
cli_shutdown(cli);
goto done;
}
@@ -721,7 +719,7 @@ static void long_group_fn(const char *group_name, const char *comment,
d_printf("%-21.21s %s\n", group_name, comment);
}
-static void group_fn(const char *group_name, const char *comment, void *state)
+static void group_fn(const char *group_name, void *state)
{
d_printf("%-21.21s\n", group_name);
}
@@ -787,7 +785,7 @@ int net_rap_group(int argc, const char **argv)
cli_shutdown(cli);
return ret;
}
- ret = cli_RNetGroupEnum(cli, group_fn, NULL);
+ ret = cli_RNetGroupEnum0(cli, group_fn, NULL);
cli_shutdown(cli);
return ret;
}
@@ -912,6 +910,12 @@ static int rap_service_stop(int argc, const char **argv)
return errmsg_not_implemented();
}
+static void service_fn(const char *service_name, const char *dummy,
+ void *state)
+{
+ d_printf("%-21.21s\n", service_name);
+}
+
int net_rap_service(int argc, const char **argv)
{
struct functable func[] = {
@@ -931,7 +935,7 @@ int net_rap_service(int argc, const char **argv)
d_printf("-----------------------------\n");
ret = cli_RNetServiceEnum(cli, long_group_fn, NULL);
}
- ret = cli_RNetServiceEnum(cli, group_fn, NULL);
+ ret = cli_RNetServiceEnum(cli, service_fn, NULL);
cli_shutdown(cli);
return ret;
}
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 27cc2a09186..6e884c24dfb 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -1909,7 +1909,6 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
struct acct_info *groups;
- DOM_SID global_sid_Builtin;
BOOL global = False;
BOOL local = False;
BOOL builtin = False;
@@ -1931,8 +1930,6 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
builtin = True;
}
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
/* Get sam policy handle */
result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -2702,6 +2699,11 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
strequal(netname,"global"))
continue;
+ if (opt_exclude && in_list(netname, opt_exclude, False)) {
+ printf("excluding [%s]\n", netname);
+ continue;
+ }
+
/* only work with file-shares */
if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
d_printf("skipping [%s]: not a file share.\n", netname);
@@ -2971,7 +2973,7 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
continue;
}
- if (opt_exclude && in_list(netname, (char *)opt_exclude, False)) {
+ if (opt_exclude && in_list(netname, opt_exclude, False)) {
printf("excluding [%s]\n", netname);
continue;
}
@@ -3273,7 +3275,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
{
NTSTATUS result;
POLICY_HND connect_pol;
- DOM_SID global_sid_Builtin;
result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
@@ -3281,8 +3282,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
if (!NT_STATUS_IS_OK(result))
goto done;
- string_to_sid(&global_sid_Builtin, "S-1-5-32");
-
result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
&global_sid_Builtin);
@@ -3299,14 +3298,6 @@ rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
static void init_user_token(NT_USER_TOKEN *token, DOM_SID *user_sid)
{
- DOM_SID global_sid_World;
- DOM_SID global_sid_Network;
- DOM_SID global_sid_Authenticated_Users;
-
- string_to_sid(&global_sid_World, "S-1-1-0");
- string_to_sid(&global_sid_Network, "S-1-5-2");
- string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
-
token->num_sids = 4;
token->user_sids = SMB_MALLOC_ARRAY(DOM_SID, 4);
@@ -4472,6 +4463,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
+ const char **names;
DOM_SID trust_acct_sid;
uint32 *user_rids, num_rids, *name_types;
uint32 flags = 0x000003e8; /* Unknown */
@@ -4484,13 +4476,17 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
/*
* Make valid trusting domain account (ie. uppercased and with '$' appended)
*/
-
- if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
+ acct_name = talloc_asprintf(mem_ctx, "%s$", argv[0]);
+
+ if (acct_name == NULL)
return NT_STATUS_NO_MEMORY;
- }
strupper_m(acct_name);
+ names = TALLOC_ARRAY(mem_ctx, const char *, 1);
+ names[0] = acct_name;
+
+
/* Get samr policy handle */
result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
@@ -4507,8 +4503,8 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
}
result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, 1,
- &acct_name, &num_rids, &user_rids,
- &name_types);
+ names, &num_rids,
+ &user_rids, &name_types);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -4552,7 +4548,6 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
}
done:
- SAFE_FREE(acct_name);
return result;
}
@@ -4594,7 +4589,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
- WKS_INFO_100 wks_info;
+ smb_ucs2_t *uni_domain_name;
char* domain_name;
char* domain_name_pol;
@@ -4663,44 +4658,17 @@ static int rpc_trustdom_establish(int argc, const char **argv)
for domain %s\n", domain_name));
}
- /*
- * Call WksQueryInfo to check remote server's capabilities
- * note: It is now used only to get unicode domain name
- */
-
- if (!cli_nt_session_open(cli, PI_WKSSVC)) {
- DEBUG(0, ("Couldn't not initialise wkssvc pipe\n"));
- return -1;
- }
-
- if (!(mem_ctx = talloc_init("establishing trust relationship to domain %s",
- domain_name))) {
+ if (!(mem_ctx = talloc_init("establishing trust relationship to "
+ "domain %s", domain_name))) {
DEBUG(0, ("talloc_init() failed\n"));
cli_shutdown(cli);
return -1;
}
- nt_status = cli_wks_query_info(cli, mem_ctx, &wks_info);
-
- if (NT_STATUS_IS_ERR(nt_status)) {
- DEBUG(0, ("WksQueryInfo call failed.\n"));
- return -1;
- }
-
- if (cli->nt_pipe_fnum[cli->pipe_idx])
- cli_nt_session_close(cli);
-
-
/*
* Call LsaOpenPolicy and LsaQueryInfo
*/
- if (!(mem_ctx = talloc_init("rpc_trustdom_establish"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- cli_shutdown(cli);
- return -1;
- }
-
if (!cli_nt_session_open(cli, PI_LSARPC)) {
DEBUG(0, ("Could not initialise lsa pipe\n"));
cli_shutdown(cli);
@@ -4718,16 +4686,19 @@ static int rpc_trustdom_establish(int argc, const char **argv)
/* Querying info level 5 */
nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
- 5 /* info level */, &domain_name_pol,
- &domain_sid);
+ 5 /* info level */,
+ &domain_name_pol, &domain_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
nt_errstr(nt_status)));
return -1;
}
-
-
+ if (push_ucs2_talloc(mem_ctx, &uni_domain_name, domain_name_pol) < 0) {
+ DEBUG(0, ("Could not convert domain name %s to unicode\n",
+ domain_name_pol));
+ return -1;
+ }
/* There should be actually query info level 3 (following nt serv behaviour),
but I still don't know if it's _really_ necessary */
@@ -4736,8 +4707,10 @@ static int rpc_trustdom_establish(int argc, const char **argv)
* Store the password in secrets db
*/
- if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
- wks_info.uni_lan_grp.uni_str_len, opt_password,
+ if (!secrets_store_trusted_domain_password(domain_name,
+ uni_domain_name,
+ strlen_w(uni_domain_name)+1,
+ opt_password,
*domain_sid)) {
DEBUG(0, ("Storing password for trusted domain failed.\n"));
return -1;
@@ -4756,6 +4729,8 @@ static int rpc_trustdom_establish(int argc, const char **argv)
if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
+
+ cli_shutdown(cli);
talloc_destroy(mem_ctx);
@@ -5583,6 +5558,7 @@ int net_rpc(int argc, const char **argv)
{"vampire", rpc_vampire},
{"getsid", net_rpc_getsid},
{"rights", net_rpc_rights},
+ {"service", net_rpc_service},
{"help", net_rpc_help},
{NULL, NULL}
};
diff --git a/source/utils/net_rpc_rights.c b/source/utils/net_rpc_rights.c
index 32cb6a4650b..3a986ed2516 100644
--- a/source/utils/net_rpc_rights.c
+++ b/source/utils/net_rpc_rights.c
@@ -133,6 +133,36 @@ static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
/********************************************************************
********************************************************************/
+static NTSTATUS check_privilege_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
+ POLICY_HND *pol, DOM_SID *sid, const char *right)
+{
+ NTSTATUS result;
+ uint32 count;
+ char **rights;
+ int i;
+
+ result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ return result;
+ }
+
+ if (count == 0) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (StrCaseCmp(rights[i], right) == 0) {
+ return NT_STATUS_OK;
+ }
+ }
+
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+}
+
+/********************************************************************
+********************************************************************/
+
static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
POLICY_HND *pol, DOM_SID *sid )
{
@@ -159,6 +189,52 @@ static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli
/********************************************************************
********************************************************************/
+static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *cli,
+ POLICY_HND *pol, const char *privilege)
+{
+ NTSTATUS result;
+ uint32 enum_context=0;
+ uint32 pref_max_length=0x1000;
+ DOM_SID *sids;
+ uint32 count=0;
+ int i;
+ fstring name;
+
+ result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
+ pref_max_length, &count, &sids);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ d_printf("%s:\n", privilege);
+
+ for ( i=0; i<count; i++ ) {
+
+
+ result = check_privilege_for_user( ctx, cli, pol, &sids[i], privilege);
+
+ if ( ! NT_STATUS_IS_OK(result)) {
+ if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ return result;
+ }
+ continue;
+ }
+
+ /* try to convert the SID to a name. Fall back to
+ printing the raw SID if necessary */
+ result = sid_to_name( cli, ctx, &sids[i], name );
+ if ( !NT_STATUS_IS_OK (result) )
+ fstrcpy( name, sid_string_static(&sids[i]) );
+
+ d_printf(" %s\n", name);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli,
POLICY_HND *pol )
{
@@ -208,43 +284,99 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
POLICY_HND pol;
NTSTATUS result;
DOM_SID sid;
+ fstring privname;
+ fstring description;
+ uint16 lang_id = 0;
+ uint16 lang_id_sys = 0;
+ uint16 lang_id_desc;
+
result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
if ( !NT_STATUS_IS_OK(result) )
return result;
-
- switch (argc) {
- case 0:
+
+ /* backwards compatibility; just list available privileges if no arguement */
+
+ if (argc == 0) {
result = enum_privileges( mem_ctx, cli, &pol );
- break;
-
- case 1:
- /* special case to enuemrate all privileged SIDs
- with associated rights */
-
- if ( strequal( argv[0], "accounts" ) ) {
- result = enum_privileges_for_accounts( mem_ctx, cli, &pol );
- }
- else {
+ goto done;
+ }
- result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
- if (!NT_STATUS_IS_OK(result))
- goto done;
- result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
+ if (strequal(argv[0], "privileges")) {
+ int i = 1;
+
+ if (argv[1] == NULL) {
+ result = enum_privileges( mem_ctx, cli, &pol );
+ goto done;
}
- break;
+
+ while ( argv[i] != NULL )
+ {
+ fstrcpy( privname, argv[i] );
+ i++;
+
+ /* verify that this is a valid privilege for error reporting */
+
+ result = cli_lsa_get_dispname(cli, mem_ctx, &pol, privname, lang_id,
+ lang_id_sys, description, &lang_id_desc);
+
+ if ( !NT_STATUS_IS_OK(result) ) {
+ if ( NT_STATUS_EQUAL( result, NT_STATUS_NO_SUCH_PRIVILEGE ) )
+ d_printf("No such privilege exists: %s.\n", privname);
+ else
+ d_printf("Error resolving privilege display name [%s].\n", nt_errstr(result));
+ continue;
+ }
- default:
- if ( argc > 1 ) {
- d_printf("Usage: net rpc rights list [name|SID]\n");
- result = NT_STATUS_OK;
+ result = enum_accounts_for_privilege(mem_ctx, cli, &pol, privname);
+ if (!NT_STATUS_IS_OK(result)) {
+ d_printf("Error enumerating accounts for privilege %s [%s].\n",
+ privname, nt_errstr(result));
+ continue;
+ }
}
+ goto done;
}
+ /* special case to enumerate all privileged SIDs with associated rights */
+ if (strequal( argv[0], "accounts")) {
+ int i = 1;
+
+ if (argv[1] == NULL) {
+ result = enum_privileges_for_accounts(mem_ctx, cli, &pol);
+ goto done;
+ }
+
+ while (argv[i] != NULL) {
+ result = name_to_sid(cli, mem_ctx, &sid, argv[i]);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+ result = enum_privileges_for_user(mem_ctx, cli, &pol, &sid);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+ i++;
+ }
+ goto done;
+ }
+ /* backward comaptibility: if no keyword provided, treat the key
+ as an account name */
+ if (argc > 1) {
+ d_printf("Usage: net rpc rights list [[accounts|privileges] [name|SID]]\n");
+ result = NT_STATUS_OK;
+ goto done;
+ }
+
+ result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+ result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
done:
cli_lsa_close(cli, mem_ctx, &pol);
@@ -379,9 +511,9 @@ static int rpc_rights_revoke( int argc, const char **argv )
static int net_help_rights( int argc, const char **argv )
{
- d_printf("net rpc rights list [accounts|username] View available or assigned privileges\n");
- d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n");
- d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n");
+ d_printf("net rpc rights list [{accounts|privileges} [name|SID]] View available or assigned privileges\n");
+ d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n");
+ d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n");
d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
d_printf("For example\n");
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 49aef2a23cd..fa38004fe6f 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -24,8 +24,6 @@
#include "includes.h"
#include "utils/net.h"
-extern DOM_SID global_sid_Builtin;
-
static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
{
int i;
@@ -429,7 +427,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
if (delta->buf_logon_hrs.buffer) {
pstring old, new;
pdb_sethexhours(old, pdb_get_hours(account));
- pdb_sethexhours(new, (const char *)delta->buf_logon_hrs.buffer);
+ pdb_sethexhours(new, delta->buf_logon_hrs.buffer);
if (!strequal(old, new))
pdb_set_hours(account, (const char *)delta->buf_logon_hrs.buffer, PDB_CHANGED);
}
diff --git a/source/utils/net_rpc_service.c b/source/utils/net_rpc_service.c
new file mode 100644
index 00000000000..94644f8dcf4
--- /dev/null
+++ b/source/utils/net_rpc_service.c
@@ -0,0 +1,529 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+ Copyright (C) Gerald (Jerry) Carter 2005
+
+ 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 "includes.h"
+#include "utils/net.h"
+
+
+/********************************************************************
+********************************************************************/
+
+static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, const char *service, uint32 *state )
+{
+ POLICY_HND hService;
+ SERVICE_STATUS service_status;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+ /* now cycle until the status is actually 'watch_state' */
+
+ result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
+ service, SC_RIGHT_SVC_QUERY_STATUS );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open service. [%s]\n", dos_errstr(result));
+ return result;
+ }
+
+ result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status );
+ if ( W_ERROR_IS_OK(result) ) {
+ *state = service_status.state;
+ }
+
+ cli_svcctl_close_service( cli, mem_ctx, &hService );
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, const char *service,
+ uint32 watch_state, uint32 *final_state )
+{
+ uint32 i;
+ uint32 state = 0;
+ WERROR result = WERR_GENERAL_FAILURE;
+
+
+ i = 0;
+ while ( (state != watch_state ) && i<30 ) {
+ /* get the status */
+
+ result = query_service_state( cli, mem_ctx, hSCM, service, &state );
+ if ( !W_ERROR_IS_OK(result) ) {
+ break;
+ }
+
+ d_printf(".");
+ i++;
+ usleep( 100 );
+ }
+ d_printf("\n");
+
+ *final_state = state;
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM, const char *service,
+ uint32 control, uint32 watch_state )
+{
+ POLICY_HND hService;
+ WERROR result = WERR_GENERAL_FAILURE;
+ SERVICE_STATUS service_status;
+ uint32 state = 0;
+
+ /* Open the Service */
+
+ result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
+ service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open service. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* get the status */
+
+ result = cli_svcctl_control_service( cli, mem_ctx, &hService,
+ control, &service_status );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Control service request failed. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* loop -- checking the state until we are where we want to be */
+
+ result = watch_service_state( cli, mem_ctx, hSCM, service, watch_state, &state );
+
+ d_printf("%s service is %s.\n", service, svc_status_string(state));
+
+done:
+ cli_svcctl_close_service( cli, mem_ctx, &hService );
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM;
+ ENUM_SERVICES_STATUS *services;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+ fstring displayname;
+ uint32 num_services = 0;
+ int i;
+
+ if (argc != 0 ) {
+ d_printf("Usage: net rpc service list\n");
+ return NT_STATUS_OK;
+ }
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ result = cli_svcctl_enumerate_services( cli, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
+ SVCCTL_STATE_ALL, &num_services, &services );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to enumerate services. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ if ( num_services == 0 )
+ d_printf("No services returned\n");
+
+ for ( i=0; i<num_services; i++ ) {
+ rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE );
+ rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE );
+
+ d_printf("%-20s \"%s\"\n", servicename, displayname);
+ }
+
+done:
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM, hService;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+ SERVICE_STATUS service_status;
+ SERVICE_CONFIG config;
+ fstring ascii_string;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service status <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ /* Open the Service */
+
+ result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService, servicename,
+ (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open service. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* get the status */
+
+ result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Query status request failed. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state));
+
+ /* get the config */
+
+ result = cli_svcctl_query_config( cli, mem_ctx, &hService, &config );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Query config request failed. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* print out the configuration information for the service */
+
+ d_printf("Configuration details:\n");
+ d_printf("\tService Type = 0x%x\n", config.service_type);
+ d_printf("\tStart Type = 0x%x\n", config.start_type);
+ d_printf("\tError Control = 0x%x\n", config.error_control);
+ d_printf("\tTag ID = 0x%x\n", config.tag_id);
+
+ if ( config.executablepath ) {
+ rpcstr_pull( ascii_string, config.executablepath->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+ d_printf("\tExecutable Path = %s\n", ascii_string);
+ }
+
+ if ( config.loadordergroup ) {
+ rpcstr_pull( ascii_string, config.loadordergroup->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+ d_printf("\tLoad Order Group = %s\n", ascii_string);
+ }
+
+ if ( config.dependencies ) {
+ rpcstr_pull( ascii_string, config.dependencies->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+ d_printf("\tDependencies = %s\n", ascii_string);
+ }
+
+ if ( config.startname ) {
+ rpcstr_pull( ascii_string, config.startname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+ d_printf("\tStart Name = %s\n", ascii_string);
+ }
+
+ if ( config.displayname ) {
+ rpcstr_pull( ascii_string, config.displayname->buffer, sizeof(ascii_string), -1, STR_TERMINATE );
+ d_printf("\tDisplay Name = %s\n", ascii_string);
+ }
+
+done:
+ cli_svcctl_close_service( cli, mem_ctx, &hService );
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service status <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ result = control_service( cli, mem_ctx, &hSCM, servicename,
+ SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
+
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service status <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ result = control_service( cli, mem_ctx, &hSCM, servicename,
+ SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
+
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service status <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ result = control_service( cli, mem_ctx, &hSCM, servicename,
+ SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
+
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND hSCM, hService;
+ WERROR result = WERR_GENERAL_FAILURE;
+ fstring servicename;
+ uint32 state = 0;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc service status <service>\n");
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy( servicename, argv[0] );
+
+ /* Open the Service Control Manager */
+
+ result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
+ return werror_to_ntstatus(result);
+ }
+
+ /* Open the Service */
+
+ result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService,
+ servicename, SC_RIGHT_SVC_START );
+
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Failed to open service. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ /* get the status */
+
+ result = cli_svcctl_start_service( cli, mem_ctx, &hService, NULL, 0 );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Query status request failed. [%s]\n", dos_errstr(result));
+ goto done;
+ }
+
+ result = watch_service_state( cli, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
+
+ if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
+ d_printf("Successfully started service: %s\n", servicename );
+ else
+ d_printf("Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
+
+done:
+ cli_svcctl_close_service( cli, mem_ctx, &hService );
+ cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_list( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_list_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_start( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_start_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_stop( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_stop_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_resume( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_resume_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_pause( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_pause_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_service_status( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_SVCCTL, 0,
+ rpc_service_status_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int net_help_service( int argc, const char **argv )
+{
+ d_printf("net rpc service list View configured Win32 services\n");
+ d_printf("net rpc service start <service> Start a service\n");
+ d_printf("net rpc service stop <service> Stop a service\n");
+ d_printf("net rpc service pause <service> Pause a service\n");
+ d_printf("net rpc service resume <service> Resume a paused a service\n");
+ d_printf("net rpc service status <service> View the current status of a service\n");
+
+ return -1;
+}
+
+/********************************************************************
+********************************************************************/
+
+int net_rpc_service(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"list", rpc_service_list},
+ {"start", rpc_service_start},
+ {"stop", rpc_service_stop},
+ {"pause", rpc_service_pause},
+ {"resume", rpc_service_resume},
+ {"status", rpc_service_status},
+ {NULL, NULL}
+ };
+
+ if ( argc )
+ return net_run_function( argc, argv, func, net_help_service );
+
+ return net_help_service( argc, argv );
+}
+
+
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index c5ba59487cc..88ec6b1f4fa 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -175,7 +175,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
pdb_get_bad_password_count(sam_pwent));
hours = pdb_get_hours(sam_pwent);
- pdb_sethexhours(temp, (const char *)hours);
+ pdb_sethexhours(temp, hours);
printf ("Logon hours : %s\n", temp);
} else if (smbpwdstyle) {
@@ -911,7 +911,7 @@ int main (int argc, char **argv)
if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
time_t pwd_can_change = -1;
time_t pwd_must_change = -1;
- char *errstr;
+ const char *errstr;
if (pwd_can_change_time) {
errstr = "can";
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index 2eb661c8b68..5a7b6548c29 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -428,7 +428,8 @@ static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
return False;
}
- notify_printer_byname(argv[2], attribute, argv[4]);
+ notify_printer_byname(argv[2], attribute,
+ CONST_DISCARD(char *, argv[4]));
goto send;
}
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 836a161021d..708d44df9f0 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -290,7 +290,7 @@ static BOOL password_change(const char *remote_mach, char *username,
err_str, sizeof(err_str), msg_str, sizeof(msg_str));
if(*msg_str)
- printf(msg_str);
+ printf("%s", msg_str);
if(*err_str)
fprintf(stderr, "%s", err_str);
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index 85e710cee8f..f4b022cf587 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -41,7 +41,6 @@ BOOL winbindd_running(void)
response */
BOOL nmbd_running(void)
{
- extern struct in_addr loopback_ip;
int fd, count, flags;
struct in_addr *ip_list;
@@ -66,7 +65,6 @@ BOOL nmbd_running(void)
BOOL smbd_running(void)
{
static struct cli_state cli;
- extern struct in_addr loopback_ip;
if (!cli_initialise(&cli))
return False;
diff --git a/source/web/neg_lang.c b/source/web/neg_lang.c
index ca671822d87..cc2924afde6 100644
--- a/source/web/neg_lang.c
+++ b/source/web/neg_lang.c
@@ -54,8 +54,8 @@ struct pri_list {
};
static int qsort_cmp_list(const void *x, const void *y) {
- struct pri_list *a = (struct pri_list *)x;
- struct pri_list *b = (struct pri_list *)y;
+ struct pri_list *a = CONST_DISCARD(struct pri_list *, x);
+ struct pri_list *b = CONST_DISCARD(struct pri_list *, y);
if (a->pri > b->pri) return -1;
if (a->pri == b->pri) return 0;
return 1;