1
0
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:
Gerald Carter
2005-03-23 23:26:33 +00:00
committed by Gerald (Jerry) Carter
parent 920745f0df
commit 5d1cb8e79e
45 changed files with 5819 additions and 1419 deletions

View File

@ -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@)

View File

@ -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)

View File

@ -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)

View File

@ -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"

View 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 */

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View 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 */

View File

@ -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

View File

@ -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. */

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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.
********************************************************************/

View File

@ -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;

View 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
};

View File

@ -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));

View File

@ -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;
}

View File

@ -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);
}

View 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;
}

View File

@ -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))

View File

@ -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)
{

View File

@ -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

View File

@ -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 }
};

View File

@ -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;

View File

@ -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))

View 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;
}

View 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);
}

View 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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 }
};

View File

@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 2001.
* Copyright (C) Gerald Carter 2002.
* Copyright (C) Gerald Carter 2002-2005.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -291,7 +291,7 @@ WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
/*******************************************************************
********************************************************************/
WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 );
}
@ -299,7 +299,7 @@ WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_
/*******************************************************************
********************************************************************/
WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
}
@ -307,7 +307,7 @@ WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_
/*******************************************************************
********************************************************************/
WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 );
}
@ -328,7 +328,7 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
if ( !key )
return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
result = open_registry_key( p, &pol, key, name, 0x0 );
@ -362,7 +362,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
rpcstr_pull(name, q_u->uni_type.buffer, sizeof(name), q_u->uni_type.uni_str_len*2, 0);
rpcstr_pull(name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0);
DEBUG(5,("reg_info: looking up value: [%s]\n", name));
@ -439,7 +439,7 @@ WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
out:
new_init_reg_r_info(q_u->ptr_buf, r_u, val, status);
init_reg_r_info(q_u->ptr_buf, r_u, val, status);
regval_ctr_destroy( &regvals );
free_registry_value( val );
@ -485,22 +485,22 @@ WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_
/*****************************************************************************
Implementation of REG_UNKNOWN_1A
Implementation of REG_GETVERSION
****************************************************************************/
WERROR _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
WERROR _reg_getversion(pipes_struct *p, REG_Q_GETVERSION *q_u, REG_R_GETVERSION *r_u)
{
WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_unknown_1a: Enter\n"));
DEBUG(5,("_reg_getversion: Enter\n"));
if ( !regkey )
return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
r_u->unknown = 0x00000005; /* seems to be consistent...no idea what it means */
DEBUG(5,("_reg_unknown_1a: Exit\n"));
DEBUG(5,("_reg_getversion: Exit\n"));
return status;
}
@ -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;
}
/*******************************************************************

View File

@ -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;

View 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));
}

View 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;
}

View File

@ -57,6 +57,7 @@ static void cmd_reg_enum(struct client_info *info)
POLICY_HND key_pol;
fstring full_keyname;
fstring key_name;
uint32 reg_type;
/*
* query key info
@ -87,6 +88,11 @@ static void cmd_reg_enum(struct client_info *info)
return;
}
if (!reg_split_key(full_keyname, &reg_type, key_name)) {
fprintf(out_hnd, "Unknown registry hive '%s'\n", key_name);
return;
}
/* open WINREG session. */
res = res ? cli_nt_session_open(smb_cli, PI_WINREG) : False;
@ -130,7 +136,7 @@ static void cmd_reg_enum(struct client_info *info)
time_t key_mod_time;
/* unknown 1a it */
res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)
@ -166,11 +172,11 @@ static void cmd_reg_enum(struct client_info *info)
*/
uint32 val_type;
BUFFER2 value;
REGVAL_BUFFER value;
fstring val_name;
/* unknown 1a it */
res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
res2 = res1 ? do_reg_getversion(smb_cli, &key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)

View File

@ -40,6 +40,8 @@ static const char *known_nt_pipes[] = {
"\\spoolss",
"\\netdfs",
"\\rpcecho",
"\\svcctl",
"\\eventlog",
NULL
};