mirror of
https://github.com/samba-team/samba.git
synced 2025-07-30 19:42:05 +03:00
r6014: rather large change set....
pulling back all recent rpc changes from trunk into
3.0. I've tested a compile and so don't think I've missed
any files. But if so, just mail me and I'll clean backup
in a couple of hours.
Changes include \winreg, \eventlog, \svcctl, and
general parse_misc.c updates.
I am planning on bracketing the event code with an
#ifdef ENABLE_EVENTLOG until I finish merging Marcin's
changes (very soon).
(This used to be commit 4e0ac63c36
)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
920745f0df
commit
5d1cb8e79e
@ -171,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
|
||||
@ -204,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
|
||||
|
||||
@ -258,7 +260,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.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
|
||||
|
||||
@ -275,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
|
||||
|
||||
@ -296,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 \
|
||||
rpc_parse/parse_buffer.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
|
||||
|
||||
@ -433,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) \
|
||||
@ -462,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)
|
||||
|
||||
@ -482,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@ \
|
||||
@ -504,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
|
||||
@ -515,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@)
|
||||
|
||||
@ -536,8 +543,8 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_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)
|
||||
@ -565,7 +572,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)
|
||||
@ -577,17 +584,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
|
||||
|
||||
@ -618,7 +626,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)
|
||||
@ -630,7 +639,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@)
|
||||
@ -660,7 +669,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) \
|
||||
@ -969,7 +978,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 $@
|
||||
@ -1025,6 +1034,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 \
|
||||
@ -1340,7 +1354,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@)
|
||||
|
||||
|
@ -413,7 +413,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"
|
||||
@ -4531,10 +4531,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)
|
||||
|
@ -185,6 +185,7 @@
|
||||
#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_SECURITY_DESCRIPTOR W_ERROR(1338)
|
||||
#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
|
||||
#define WERR_INVALID_FORM_NAME W_ERROR(1902)
|
||||
|
@ -398,7 +398,9 @@ typedef struct {
|
||||
#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"
|
||||
|
193
source3/include/rpc_eventlog.h
Normal file
193
source3/include/rpc_eventlog.h
Normal file
@ -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 */
|
@ -423,7 +423,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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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
|
||||
@ -28,6 +28,9 @@
|
||||
|
||||
#define SMB_RPC_INTERFACE_VERSION 1
|
||||
|
||||
#define PRS_POINTER_CAST BOOL (*)(const char*, prs_struct*, int, void*)
|
||||
|
||||
|
||||
/* well-known RIDs - Relative IDs */
|
||||
|
||||
/* RIDs - Well-known users ... */
|
||||
@ -88,12 +91,6 @@ typedef struct enum_hnd_info
|
||||
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
|
||||
{
|
||||
@ -138,17 +135,25 @@ typedef struct bufhdr_info
|
||||
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
|
||||
{
|
||||
/*
|
||||
OLD COMMENT:
|
||||
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
|
||||
|
||||
NEW COMMENT:
|
||||
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
|
||||
@ -177,6 +182,13 @@ typedef struct unistr2_info
|
||||
uint16 *buffer;
|
||||
} UNISTR2;
|
||||
|
||||
/* UNIHDR + UNISTR2* */
|
||||
typedef struct {
|
||||
uint16 length; /* number of bytes not counting NULL terminatation */
|
||||
uint16 size; /* number of bytes including NULL terminatation */
|
||||
UNISTR2 *string;
|
||||
} UNISTR4;
|
||||
|
||||
/* STRING2 - string size (in uint8 chars) and buffer */
|
||||
typedef struct string2_info
|
||||
{
|
||||
|
@ -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
|
||||
@ -28,46 +29,50 @@
|
||||
/* 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_SAVE_KEY 0x14
|
||||
#define REG_SET_KEY_SEC 0x15
|
||||
#define REG_CREATE_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 +90,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 +103,7 @@ typedef struct {
|
||||
uint8 *data_p;
|
||||
} REGISTRY_VALUE;
|
||||
|
||||
/* container for regostry values */
|
||||
/* container for registry values */
|
||||
|
||||
typedef struct {
|
||||
TALLOC_CTX *ctx;
|
||||
@ -143,379 +152,224 @@ 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 ;
|
||||
typedef struct {
|
||||
uint16 *server;
|
||||
uint32 access;
|
||||
} REG_Q_OPEN_HIVE;
|
||||
|
||||
/* REG_R_OPEN_HKCR */
|
||||
typedef struct r_reg_open_hkcr_info
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
WERROR status; /* return status */
|
||||
|
||||
} REG_R_OPEN_HKCR;
|
||||
typedef struct {
|
||||
POLICY_HND pol;
|
||||
WERROR status;
|
||||
} REG_R_OPEN_HIVE;
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
} REG_R_OPEN_HKU;
|
||||
|
||||
|
||||
/* 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 */
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND pol;
|
||||
UNISTR4 name;
|
||||
uint32 type;
|
||||
BUFFER3 *value;
|
||||
} REG_Q_CREATE_VALUE;
|
||||
|
||||
/* REG_R_CREATE_VALUE */
|
||||
typedef struct r_reg_create_value_info
|
||||
{
|
||||
WERROR status; /* return status */
|
||||
|
||||
typedef struct {
|
||||
WERROR 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;
|
||||
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
|
||||
{
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND pol; /* policy handle */
|
||||
} REG_Q_GETVERSION;
|
||||
|
||||
} REG_Q_UNKNOWN_1A;
|
||||
|
||||
/* REG_R_UNKNOWN_1A */
|
||||
typedef struct r_reg_unk_1a_info
|
||||
{
|
||||
typedef struct {
|
||||
uint32 unknown; /* 0x0500 0000 */
|
||||
WERROR status; /* return status */
|
||||
|
||||
} REG_R_UNKNOWN_1A;
|
||||
} REG_R_GETVERSION;
|
||||
|
||||
|
||||
/* 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" */
|
||||
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND pol;
|
||||
UNISTR4 filename;
|
||||
uint32 unknown; /* 0x0000 0000 */
|
||||
|
||||
} REG_Q_SAVE_KEY;
|
||||
|
||||
|
||||
/* REG_R_UNKNOWN_1A */
|
||||
typedef struct r_reg_unknown_14
|
||||
{
|
||||
typedef struct {
|
||||
WERROR status; /* return status */
|
||||
|
||||
} REG_R_SAVE_KEY;
|
||||
|
||||
|
||||
|
||||
/* REG_Q_CLOSE */
|
||||
typedef struct reg_q_close_info
|
||||
{
|
||||
POLICY_HND pol; /* policy handle */
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND pol; /* policy handle */
|
||||
} REG_Q_CLOSE;
|
||||
|
||||
/* 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;
|
||||
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 +386,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 +411,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;
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} REG_R_SHUTDOWN_EX;
|
||||
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
uint16 *server;
|
||||
} REG_Q_ABORT_SHUTDOWN;
|
||||
|
||||
/* REG_R_ABORT_SHUTDOWN */
|
||||
typedef struct r_reg_abort_shutdown_info
|
||||
{
|
||||
WERROR status; /* return status */
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} REG_R_ABORT_SHUTDOWN;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} SHUTDOWN_R_INIT_EX;
|
||||
|
||||
/***********************************************/
|
||||
|
||||
typedef struct {
|
||||
uint16 *server;
|
||||
} SHUTDOWN_Q_ABORT;
|
||||
|
||||
/* SHUTDOWN_R_ABORT */
|
||||
typedef struct r_shutdown_abort_info
|
||||
{
|
||||
NTSTATUS status; /* return status */
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} SHUTDOWN_R_ABORT;
|
||||
|
||||
|
||||
|
||||
#endif /* _RPC_SHUTDOWN_H */
|
||||
|
||||
|
@ -426,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
|
||||
@ -543,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;
|
||||
PRINTER_DEFAULT printer_default;
|
||||
}
|
||||
SPOOL_Q_OPEN_PRINTER;
|
||||
/********************************************/
|
||||
|
||||
/* SPOOL_R_OPEN_PRINTER reply to an open printer */
|
||||
typedef struct spool_r_open_printer
|
||||
{
|
||||
typedef struct {
|
||||
UNISTR2 *printername;
|
||||
PRINTER_DEFAULT printer_default;
|
||||
} SPOOL_Q_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
|
||||
{
|
||||
@ -1678,8 +1665,7 @@ SPOOL_R_ABORTPRINTER;
|
||||
|
||||
typedef struct spool_q_addprinterex
|
||||
{
|
||||
uint32 server_name_ptr;
|
||||
UNISTR2 server_name;
|
||||
UNISTR2 *server_name;
|
||||
uint32 level;
|
||||
SPOOL_PRINTER_INFO_LEVEL info;
|
||||
DEVMODE_CTR devmode_ctr;
|
||||
|
243
source3/include/rpc_svcctl.h
Normal file
243
source3/include/rpc_svcctl.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
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 ( SVC_STATE_ACTIVE | SVC_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
|
||||
|
||||
|
||||
/* 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 {
|
||||
uint32 ptr_srv;
|
||||
UNISTR2 servername;
|
||||
uint32 ptr_db;
|
||||
UNISTR2 database;
|
||||
uint32 access_mask;
|
||||
} 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_mask;
|
||||
} SVCCTL_Q_OPEN_SERVICE;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
WERROR status;
|
||||
} SVCCTL_R_OPEN_SERVICE;
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 parmcount;
|
||||
UNISTR2_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 */
|
||||
|
@ -193,6 +193,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 +210,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
|
||||
|
@ -290,6 +290,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 +340,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. */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -2172,8 +2172,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;
|
||||
|
@ -316,3 +316,42 @@ 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)
|
||||
{
|
||||
extern DOM_SID global_sid_World;
|
||||
DOM_SID adm_sid;
|
||||
DOM_SID act_sid;
|
||||
|
||||
SEC_ACE ace[3];
|
||||
SEC_ACCESS mask;
|
||||
|
||||
SEC_ACL *psa = NULL;
|
||||
|
||||
sid_copy(&adm_sid, &global_sid_Builtin);
|
||||
sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
|
||||
|
||||
sid_copy(&act_sid, &global_sid_Builtin);
|
||||
sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
|
||||
|
||||
/*basic access for every one*/
|
||||
init_sec_access(&mask, 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;
|
||||
}
|
||||
|
@ -1694,6 +1694,20 @@ void str_list_free(char ***list)
|
||||
SAFE_FREE(*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
|
||||
|
@ -282,6 +282,19 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
|
||||
pull_ucs2(NULL, dest, str->buffer, maxlen, str->uni_str_len*2, STR_NOALIGN);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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
|
||||
********************************************************************/
|
||||
@ -310,18 +323,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.
|
||||
********************************************************************/
|
||||
|
@ -183,8 +183,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;
|
||||
@ -583,6 +591,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);
|
||||
@ -935,6 +944,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},
|
||||
@ -978,6 +989,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},
|
||||
@ -1113,6 +1125,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},
|
||||
@ -1381,7 +1401,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;
|
||||
@ -1530,6 +1550,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;
|
||||
@ -1556,6 +1582,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;
|
||||
@ -1722,6 +1750,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)
|
||||
|
||||
@ -1741,6 +1770,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)
|
||||
@ -1838,6 +1875,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)
|
||||
@ -2769,6 +2807,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;
|
||||
|
302
source3/registry/reg_eventlog.c
Normal file
302
source3/registry/reg_eventlog.c
Normal file
@ -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
|
||||
};
|
@ -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));
|
||||
|
@ -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_create_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
POLICY_HND *hnd, char *val_name, uint32 type,
|
||||
BUFFER3 *data)
|
||||
{
|
||||
prs_struct rbuf;
|
||||
prs_struct qbuf;
|
||||
REG_Q_CREATE_VALUE q_o;
|
||||
REG_R_CREATE_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_create_val(&q_o, hnd, val_name, type, data);
|
||||
|
||||
if (!reg_io_q_create_val("", &q_o, &qbuf, 0) ||
|
||||
!rpc_api_pipe_req(cli, PI_WINREG, REG_CREATE_VALUE, &qbuf, &rbuf))
|
||||
goto done;
|
||||
|
||||
ZERO_STRUCT(r_o);
|
||||
|
||||
/* Unmarshal response */
|
||||
|
||||
if (reg_io_r_create_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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
457
source3/rpc_parse/parse_eventlog.c
Normal file
457
source3/rpc_parse/parse_eventlog.c
Normal file
@ -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;
|
||||
}
|
@ -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))
|
||||
|
@ -131,28 +131,6 @@ BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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.
|
||||
********************************************************************/
|
||||
@ -707,10 +685,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 +701,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)
|
||||
|
||||
prs_debug(ps, depth, desc, "smb_io_regval_buffer");
|
||||
depth++;
|
||||
|
||||
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;
|
||||
|
||||
if (buffer) {
|
||||
/* buffer advanced by indicated length of string
|
||||
NOT by searching for null-termination */
|
||||
|
||||
prs_debug(ps, depth, desc, "smb_io_buffer2");
|
||||
depth++;
|
||||
if(!prs_regval_buffer(True, "buffer ", ps, depth, buf2))
|
||||
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;
|
||||
|
||||
} else {
|
||||
|
||||
prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
|
||||
depth++;
|
||||
memset((char *)buf2, '\0', sizeof(*buf2));
|
||||
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -933,6 +900,20 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inits a UNISTR2 structure.
|
||||
* @param ctx talloc context to allocate string on
|
||||
@ -1033,6 +1014,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.
|
||||
@ -1076,10 +1108,29 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
initialise a UNISTR_ARRAY from a char**
|
||||
*/
|
||||
********************************************************************/
|
||||
|
||||
BOOL init_unistr2_array(UNISTR2_ARRAY *array,
|
||||
uint32 count, const char **strings)
|
||||
{
|
||||
|
@ -588,6 +588,37 @@ BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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
|
||||
@ -646,34 +677,6 @@ BOOL prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Stream a uint32* (allocate memory if unmarshalling)
|
||||
********************************************************************/
|
||||
|
||||
BOOL prs_uint32_p(const char *name, prs_struct *ps, int depth, uint32 **data32)
|
||||
{
|
||||
uint32 data_p;
|
||||
|
||||
/* caputure the pointer value to stream */
|
||||
|
||||
data_p = (uint32) *data32;
|
||||
|
||||
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 ( !(*data32 = PRS_ALLOC_MEM(ps, uint32, 1)) )
|
||||
return False;
|
||||
}
|
||||
|
||||
return prs_uint32(name, ps, depth, *data32);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Stream a NTSTATUS
|
||||
********************************************************************/
|
||||
@ -944,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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
@ -43,6 +43,29 @@ void init_shutdown_q_init(SHUTDOWN_Q_INIT *q_s, const char *msg,
|
||||
q_s->force = force ? 1 : 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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,30 +82,24 @@ 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)))
|
||||
return False;
|
||||
if (!prs_uint16("server", ps, depth, &(q_s->server)))
|
||||
if (!prs_pointer("server", ps, depth, (void**)&q_s->server, sizeof(uint16), (PRS_POINTER_CAST)prs_uint16))
|
||||
return False;
|
||||
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint32("ptr_msg", ps, depth, &(q_s->ptr_msg)))
|
||||
if (!prs_pointer("message", ps, depth, (void**)&q_s->message, sizeof(UNISTR4), (PRS_POINTER_CAST)prs_unistr4))
|
||||
return False;
|
||||
|
||||
if (!smb_io_unihdr("hdr_msg", &(q_s->hdr_msg), ps, depth))
|
||||
return False;
|
||||
if (!smb_io_unistr2("uni_msg", &(q_s->uni_msg), q_s->hdr_msg.buffer, ps, depth))
|
||||
return False;
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if (!prs_uint32("timeout", ps, depth, &(q_s->timeout)))
|
||||
return False;
|
||||
|
||||
if (!prs_uint8("force ", ps, depth, &(q_s->force)))
|
||||
return False;
|
||||
if (!prs_uint8("reboot ", ps, depth, &(q_s->reboot)))
|
||||
return False;
|
||||
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -101,20 +118,83 @@ BOOL shutdown_io_r_init(const char *desc, SHUTDOWN_R_INIT* r_s, prs_struct *ps,
|
||||
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;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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 REG_R_SHUTDOWN_EX structure.
|
||||
********************************************************************/
|
||||
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_ex");
|
||||
depth++;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
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;
|
||||
|
@ -550,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))
|
||||
@ -576,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;
|
||||
@ -600,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;
|
||||
@ -899,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;
|
||||
}
|
||||
@ -931,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;
|
||||
|
||||
@ -967,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;
|
||||
}
|
||||
@ -1102,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))
|
||||
@ -1158,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))
|
||||
@ -4645,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))
|
||||
|
665
source3/rpc_parse/parse_svcctl.c
Normal file
665
source3/rpc_parse/parse_svcctl.c
Normal file
@ -0,0 +1,665 @@
|
||||
/*
|
||||
* 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_uint32("srv_ptr", ps, depth, &q_u->ptr_srv))
|
||||
return False;
|
||||
if(!smb_io_unistr2("servername", &q_u->servername, q_u->ptr_srv, ps, depth))
|
||||
return False;
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("db_ptr", ps, depth, &q_u->ptr_db))
|
||||
return False;
|
||||
if(!smb_io_unistr2("database", &q_u->database, q_u->ptr_db, ps, depth))
|
||||
return False;
|
||||
|
||||
if(!prs_align(ps))
|
||||
return False;
|
||||
|
||||
if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
|
||||
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_mask", ps, depth, &q_u->access_mask))
|
||||
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(!smb_io_unistr2_array("parameters", &q_u->parameters, ps, depth))
|
||||
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;
|
||||
}
|
||||
|
||||
|
206
source3/rpc_server/srv_eventlog.c
Normal file
206
source3/rpc_server/srv_eventlog.c
Normal file
@ -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);
|
||||
}
|
923
source3/rpc_server/srv_eventlog_nt.c
Normal file
923
source3/rpc_server/srv_eventlog_nt.c
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -765,6 +765,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)
|
||||
@ -1631,6 +1632,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 );
|
||||
|
@ -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;
|
||||
@ -215,6 +215,32 @@ static BOOL api_reg_shutdown(pipes_struct *p)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
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;
|
||||
@ -383,8 +409,9 @@ 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_GETVERSION" , REG_GETVERSION , api_reg_getversion },
|
||||
{ "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }
|
||||
};
|
||||
|
||||
|
@ -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( ®vals );
|
||||
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;
|
||||
}
|
||||
@ -593,82 +593,131 @@ done:
|
||||
|
||||
WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
|
||||
{
|
||||
WERROR status = WERR_OK;
|
||||
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_ex(pipes_struct *p, REG_Q_SHUTDOWN_EX *q_u, REG_R_SHUTDOWN_EX *r_u)
|
||||
{
|
||||
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;
|
||||
|
||||
/* message */
|
||||
rpcstr_pull (message, unimsg.buffer, sizeof(message), unimsg.uni_str_len*2,0);
|
||||
/* security check */
|
||||
|
||||
pstrcpy(shutdown_script, lp_shutdown_script());
|
||||
|
||||
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 : "");
|
||||
|
||||
pstrcpy(shutdown_script, lp_shutdown_script());
|
||||
|
||||
if(*shutdown_script) {
|
||||
int shutdown_ret;
|
||||
SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
|
||||
BOOL can_shutdown;
|
||||
|
||||
can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
|
||||
fstr_sprintf(timeout, "%d", q_u->timeout);
|
||||
fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
|
||||
fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
|
||||
fstr_sprintf( reason, "%d", q_u->reason );
|
||||
|
||||
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 );
|
||||
|
||||
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
|
||||
if ( can_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. */
|
||||
|
||||
if ( can_shutdown ) {
|
||||
DEBUG(3,("_reg_shutdown_ex: Privilege Check is OK for shutdown \n"));
|
||||
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));
|
||||
}
|
||||
|
||||
ret = smbrun( shutdown_script, NULL );
|
||||
|
||||
DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
|
||||
shutdown_script, ret));
|
||||
|
||||
if ( can_shutdown )
|
||||
unbecome_root();
|
||||
/********** END SeRemoteShutdownPrivilege BLOCK **********/
|
||||
}
|
||||
|
||||
return status;
|
||||
/********** END SeRemoteShutdownPrivilege BLOCK **********/
|
||||
|
||||
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));
|
||||
|
||||
ret = smbrun( abort_shutdown_script, NULL );
|
||||
|
||||
DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
|
||||
abort_shutdown_script, ret));
|
||||
|
||||
if ( can_shutdown )
|
||||
unbecome_root();
|
||||
/********** END SeRemoteShutdownPrivilege BLOCK **********/
|
||||
|
||||
}
|
||||
/********** END SeRemoteShutdownPrivilege BLOCK **********/
|
||||
|
||||
return status;
|
||||
return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -1491,10 +1491,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);
|
||||
}
|
||||
@ -1588,7 +1588,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;
|
||||
|
||||
@ -1597,15 +1596,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));
|
||||
|
||||
@ -7595,7 +7592,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;
|
||||
|
294
source3/rpc_server/srv_svcctl.c
Normal file
294
source3/rpc_server/srv_svcctl.c
Normal file
@ -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));
|
||||
}
|
291
source3/rpc_server/srv_svcctl_nt.c
Normal file
291
source3/rpc_server/srv_svcctl_nt.c
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
static TDB_CONTEXT *svcctl_tdb; /* used for share security descriptors */
|
||||
|
||||
#define SCVCTL_DATABASE_VERSION_V1 1
|
||||
|
||||
/********************************************************************
|
||||
********************************************************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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, ®_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)
|
||||
|
@ -40,6 +40,8 @@ static const char *known_nt_pipes[] = {
|
||||
"\\spoolss",
|
||||
"\\netdfs",
|
||||
"\\rpcecho",
|
||||
"\\svcctl",
|
||||
"\\eventlog",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user