summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/LDAP/samba.schema76
-rw-r--r--source3/Makefile.in73
-rw-r--r--source3/auth/auth.c2
-rw-r--r--source3/auth/auth_domain.c204
-rw-r--r--source3/auth/auth_ntlmssp.c6
-rw-r--r--source3/auth/auth_util.c95
-rw-r--r--source3/auth/auth_winbind.c2
-rwxr-xr-xsource3/client/mount.cifs.c30
-rw-r--r--source3/client/smbspool.c11
-rw-r--r--source3/configure.in130
-rw-r--r--source3/groupdb/mapping.c60
-rw-r--r--source3/include/ads.h2
-rw-r--r--source3/include/asn_1.h5
-rw-r--r--source3/include/authdata.h41
-rw-r--r--source3/include/client.h58
-rw-r--r--source3/include/dlinklist.h14
-rw-r--r--source3/include/doserr.h8
-rw-r--r--source3/include/includes.h43
-rw-r--r--source3/include/messages.h9
-rw-r--r--source3/include/module.h2
-rw-r--r--source3/include/ntdomain.h135
-rw-r--r--source3/include/ntlmssp.h33
-rw-r--r--source3/include/passdb.h20
-rw-r--r--source3/include/printing.h2
-rw-r--r--source3/include/rpc_client.h68
-rw-r--r--source3/include/rpc_dce.h131
-rw-r--r--source3/include/rpc_dfs.h267
-rw-r--r--source3/include/rpc_ds.h3
-rw-r--r--source3/include/rpc_eventlog.h124
-rw-r--r--source3/include/rpc_lsa.h2
-rw-r--r--source3/include/rpc_misc.h66
-rw-r--r--source3/include/rpc_netlogon.h285
-rw-r--r--source3/include/rpc_ntsvcs.h147
-rw-r--r--source3/include/rpc_perfcount.h106
-rw-r--r--source3/include/rpc_perfcount_defs.h73
-rw-r--r--source3/include/rpc_reg.h21
-rw-r--r--source3/include/rpc_samr.h2
-rw-r--r--source3/include/rpc_secdes.h9
-rw-r--r--source3/include/rpc_svcctl.h84
-rw-r--r--source3/include/smb.h180
-rw-r--r--source3/include/smb_ldap.h256
-rw-r--r--source3/include/smb_share_modes.h2
-rw-r--r--source3/include/smbldap.h13
-rw-r--r--source3/include/spnego.h2
-rw-r--r--source3/include/srvstr.h2
-rw-r--r--source3/lib/account_pol.c372
-rw-r--r--source3/lib/arc4.c80
-rw-r--r--source3/lib/data_blob.c20
-rw-r--r--source3/lib/debug.c18
-rw-r--r--source3/lib/dmallocmsg.c4
-rw-r--r--source3/lib/gencache.c16
-rw-r--r--source3/lib/genrand.c61
-rw-r--r--source3/lib/messages.c57
-rw-r--r--source3/lib/module.c74
-rw-r--r--source3/lib/pidfile.c2
-rw-r--r--source3/lib/privileges.c5
-rw-r--r--source3/lib/smbldap.c6
-rw-r--r--source3/lib/smbldap_util.c66
-rw-r--r--source3/lib/smbrun.c8
-rw-r--r--source3/lib/tallocmsg.c4
-rw-r--r--source3/lib/time.c138
-rw-r--r--source3/lib/util.c70
-rw-r--r--source3/libads/authdata.c478
-rw-r--r--source3/libads/kerberos_verify.c94
-rw-r--r--source3/libads/ldap.c4
-rw-r--r--source3/libads/ldap_printer.c14
-rw-r--r--source3/libads/sasl.c2
-rw-r--r--source3/libsmb/cliconnect.c27
-rw-r--r--source3/libsmb/clidgram.c2
-rw-r--r--source3/libsmb/clientgen.c83
-rw-r--r--source3/libsmb/clierror.c17
-rw-r--r--source3/libsmb/clikrb5.c451
-rw-r--r--source3/libsmb/clireadwrite.c12
-rw-r--r--source3/libsmb/clispnego.c5
-rw-r--r--source3/libsmb/clitrans.c19
-rw-r--r--source3/libsmb/credentials.c295
-rw-r--r--source3/libsmb/errormap.c4
-rw-r--r--source3/libsmb/libsmb_compat.c2
-rw-r--r--source3/libsmb/libsmbclient.c89
-rw-r--r--source3/libsmb/ntlmssp.c84
-rw-r--r--source3/libsmb/ntlmssp_parse.c6
-rw-r--r--source3/libsmb/ntlmssp_sign.c436
-rw-r--r--source3/libsmb/passchange.c66
-rw-r--r--source3/libsmb/pwd_cache.c1
-rw-r--r--source3/libsmb/smb_share_modes.c93
-rw-r--r--source3/libsmb/smbdes.c78
-rw-r--r--source3/libsmb/smbencrypt.c30
-rw-r--r--source3/libsmb/smberr.c1
-rw-r--r--source3/libsmb/spnego.c4
-rw-r--r--source3/libsmb/trusts_util.c47
-rw-r--r--source3/locking/brlock.c24
-rw-r--r--source3/locking/locking.c1204
-rw-r--r--source3/modules/weird.c2
-rw-r--r--source3/nmbd/asyncdns.c2
-rw-r--r--source3/nmbd/nmbd.c21
-rw-r--r--source3/nmbd/nmbd_elections.c3
-rw-r--r--source3/nmbd/nmbd_packets.c4
-rw-r--r--source3/nmbd/nmbd_synclists.c2
-rw-r--r--source3/nmbd/nmbd_winsserver.c3
-rw-r--r--source3/nsswitch/wb_common.c5
-rw-r--r--source3/nsswitch/wbinfo.c1
-rw-r--r--source3/nsswitch/winbindd.c67
-rw-r--r--source3/nsswitch/winbindd.h16
-rw-r--r--source3/nsswitch/winbindd_ads.c11
-rw-r--r--source3/nsswitch/winbindd_async.c97
-rw-r--r--source3/nsswitch/winbindd_cache.c86
-rw-r--r--source3/nsswitch/winbindd_cm.c513
-rw-r--r--source3/nsswitch/winbindd_dual.c151
-rw-r--r--source3/nsswitch/winbindd_group.c23
-rw-r--r--source3/nsswitch/winbindd_misc.c30
-rw-r--r--source3/nsswitch/winbindd_nss.h8
-rw-r--r--source3/nsswitch/winbindd_pam.c172
-rw-r--r--source3/pam_smbpass/pam_smb_auth.c9
-rw-r--r--source3/param/loadparm.c39
-rw-r--r--source3/passdb/lookup_sid.c28
-rw-r--r--source3/passdb/passdb.c16
-rw-r--r--source3/passdb/pdb_get_set.c8
-rw-r--r--source3/passdb/pdb_interface.c134
-rw-r--r--source3/passdb/pdb_ldap.c354
-rw-r--r--source3/passdb/pdb_nds.c2
-rw-r--r--source3/passdb/pdb_smbpasswd.c22
-rw-r--r--source3/passdb/secrets.c66
-rw-r--r--source3/passdb/util_sam_sid.c191
-rw-r--r--source3/printing/notify.c12
-rw-r--r--source3/printing/print_cups.c6
-rw-r--r--source3/printing/print_generic.c8
-rw-r--r--source3/printing/print_iprint.c8
-rw-r--r--source3/printing/printing.c159
-rw-r--r--source3/printing/printing_db.c2
-rw-r--r--source3/profile/profile.c6
-rw-r--r--source3/registry/reg_db.c12
-rw-r--r--source3/registry/reg_dynamic.c99
-rw-r--r--source3/registry/reg_eventlog.c375
-rw-r--r--source3/registry/reg_frontend.c136
-rw-r--r--source3/registry/reg_objects.c28
-rw-r--r--source3/registry/reg_perfcount.c1225
-rw-r--r--source3/registry/reg_printing.c40
-rw-r--r--source3/registry/reg_util.c28
-rw-r--r--source3/registry/regfio.c2
-rw-r--r--source3/rpc_client/cli_dfs.c136
-rw-r--r--source3/rpc_client/cli_ds.c81
-rw-r--r--source3/rpc_client/cli_echo.c125
-rw-r--r--source3/rpc_client/cli_lsarpc.c723
-rw-r--r--source3/rpc_client/cli_netlogon.c860
-rw-r--r--source3/rpc_client/cli_pipe.c3159
-rw-r--r--source3/rpc_client/cli_reg.c101
-rw-r--r--source3/rpc_client/cli_samr.c1164
-rw-r--r--source3/rpc_client/cli_shutdown.c107
-rw-r--r--source3/rpc_client/cli_spoolss.c198
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c129
-rw-r--r--source3/rpc_client/cli_srvsvc.c302
-rw-r--r--source3/rpc_client/cli_svcctl.c74
-rw-r--r--source3/rpc_client/cli_wkssvc.c63
-rw-r--r--source3/rpc_parse/parse_buffer.c2
-rw-r--r--source3/rpc_parse/parse_dfs.c2
-rw-r--r--source3/rpc_parse/parse_ds.c28
-rw-r--r--source3/rpc_parse/parse_echo.c2
-rw-r--r--source3/rpc_parse/parse_eventlog.c84
-rw-r--r--source3/rpc_parse/parse_misc.c8
-rw-r--r--source3/rpc_parse/parse_net.c54
-rw-r--r--source3/rpc_parse/parse_ntsvcs.c415
-rw-r--r--source3/rpc_parse/parse_prs.c146
-rw-r--r--source3/rpc_parse/parse_reg.c2
-rw-r--r--source3/rpc_parse/parse_rpc.c518
-rw-r--r--source3/rpc_parse/parse_samr.c6
-rw-r--r--source3/rpc_parse/parse_svcctl.c305
-rw-r--r--source3/rpc_server/srv_eventlog.c6
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c1585
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c6
-rw-r--r--source3/rpc_server/srv_lsa_nt.c7
-rw-r--r--source3/rpc_server/srv_netlog_nt.c269
-rw-r--r--source3/rpc_server/srv_ntsvcs.c220
-rw-r--r--source3/rpc_server/srv_ntsvcs_nt.c174
-rw-r--r--source3/rpc_server/srv_pipe.c1863
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c217
-rw-r--r--source3/rpc_server/srv_reg.c57
-rw-r--r--source3/rpc_server/srv_reg_nt.c436
-rw-r--r--source3/rpc_server/srv_samr_nt.c153
-rw-r--r--source3/rpc_server/srv_samr_util.c4
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c55
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c5
-rw-r--r--source3/rpc_server/srv_svcctl.c76
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c694
-rw-r--r--source3/rpcclient/cmd_dfs.c30
-rw-r--r--source3/rpcclient/cmd_ds.c14
-rw-r--r--source3/rpcclient/cmd_echo.c24
-rw-r--r--source3/rpcclient/cmd_lsarpc.c177
-rw-r--r--source3/rpcclient/cmd_netlogon.c52
-rw-r--r--source3/rpcclient/cmd_samr.c257
-rw-r--r--source3/rpcclient/cmd_spoolss.c502
-rw-r--r--source3/rpcclient/cmd_srvsvc.c44
-rw-r--r--source3/rpcclient/cmd_test.c68
-rw-r--r--source3/rpcclient/cmd_wkssvc.c2
-rw-r--r--source3/rpcclient/rpcclient.c333
-rw-r--r--source3/rpcclient/rpcclient.h11
-rw-r--r--source3/sam/idmap_rid.c23
-rw-r--r--source3/sam/idmap_smbldap.c453
-rwxr-xr-xsource3/script/installman.sh2
-rwxr-xr-xsource3/script/installswat.sh22
-rw-r--r--source3/script/mkproto.awk2
-rw-r--r--source3/script/tests/functions22
-rw-r--r--source3/script/tests/t_001.sh22
-rw-r--r--source3/services/services_db.c829
-rw-r--r--source3/services/svc_netlogon.c66
-rw-r--r--source3/services/svc_rcinit.c64
-rw-r--r--source3/services/svc_spoolss.c8
-rw-r--r--source3/services/svc_winreg.c63
-rw-r--r--source3/smbd/blocking.c24
-rw-r--r--source3/smbd/change_trust_pw.c17
-rw-r--r--source3/smbd/chgpasswd.c4
-rw-r--r--source3/smbd/close.c87
-rw-r--r--source3/smbd/conn.c2
-rw-r--r--source3/smbd/connection.c8
-rw-r--r--source3/smbd/error.c23
-rw-r--r--source3/smbd/files.c33
-rw-r--r--source3/smbd/mangle_hash2.c4
-rw-r--r--source3/smbd/message.c11
-rw-r--r--source3/smbd/nttrans.c29
-rw-r--r--source3/smbd/open.c879
-rw-r--r--source3/smbd/oplock.c1331
-rw-r--r--source3/smbd/oplock_irix.c51
-rw-r--r--source3/smbd/oplock_linux.c56
-rw-r--r--source3/smbd/process.c457
-rw-r--r--source3/smbd/reply.c133
-rw-r--r--source3/smbd/server.c11
-rw-r--r--source3/smbd/sesssetup.c70
-rw-r--r--source3/smbd/trans2.c132
-rw-r--r--source3/tdb/tdbdump.c4
-rw-r--r--source3/tdb/tdbtool.c12
-rw-r--r--source3/tdb/tdbutil.c7
-rw-r--r--source3/torture/locktest2.c4
-rw-r--r--source3/torture/mangle_test.c2
-rw-r--r--source3/torture/msgtest.c10
-rw-r--r--source3/torture/t_asn1.c61
-rw-r--r--source3/torture/t_strappend.c45
-rw-r--r--source3/torture/torture.c1
-rw-r--r--source3/torture/vfstest.c2
-rw-r--r--source3/utils/log2pcaphex.c6
-rw-r--r--source3/utils/net.c17
-rw-r--r--source3/utils/net.h13
-rw-r--r--source3/utils/net_ads.c9
-rw-r--r--source3/utils/net_rpc.c1089
-rw-r--r--source3/utils/net_rpc_join.c130
-rw-r--r--source3/utils/net_rpc_printer.c538
-rw-r--r--source3/utils/net_rpc_registry.c45
-rw-r--r--source3/utils/net_rpc_rights.c147
-rw-r--r--source3/utils/net_rpc_samsync.c183
-rw-r--r--source3/utils/net_rpc_service.c156
-rw-r--r--source3/utils/net_status.c15
-rw-r--r--source3/utils/ntlm_auth.c31
-rw-r--r--source3/utils/pdbedit.c46
-rw-r--r--source3/utils/smbcacls.c11
-rw-r--r--source3/utils/smbcontrol.c126
-rw-r--r--source3/utils/smbcquotas.c13
-rw-r--r--source3/utils/status.c18
-rw-r--r--source3/utils/testparm.c2
-rw-r--r--source3/web/diagnose.c4
-rw-r--r--source3/web/neg_lang.c4
-rw-r--r--source3/web/startstop.c6
-rw-r--r--source3/web/statuspage.c34
-rw-r--r--source3/web/swat.c142
261 files changed, 20307 insertions, 15508 deletions
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
index 2205c17309..daf4588ead 100644
--- a/examples/LDAP/samba.schema
+++ b/examples/LDAP/samba.schema
@@ -389,16 +389,68 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
-attributetype ( 1.3.6.1.4.1.7165.2.1.56 NAME 'sambaAccountPolicyName'
- DESC 'Account Policy Name'
- EQUALITY caseIgnoreMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+# "min password length"
+attributetype ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength'
+ DESC 'Minimal password length (default: 5)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-attributetype ( 1.3.6.1.4.1.7165.2.1.57 NAME 'sambaAccountPolicyValue'
- DESC 'Account Policy Value'
+# "password history"
+attributetype ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength'
+ DESC 'Length of Password History Entries (default: 0 => off)'
EQUALITY integerMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+# "user must logon to change password"
+attributetype ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd'
+ DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "maximum password age"
+attributetype ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge'
+ DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "minimum password age"
+attributetype ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge'
+ DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "lockout duration"
+attributetype ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration'
+ DESC 'Lockout duration in minutes (default: 30, -1 => forever)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "reset count minutes"
+attributetype ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow'
+ DESC 'Reset time after lockout in minutes (default: 30)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "bad lockout attempt"
+attributetype ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold'
+ DESC 'Lockout users after bad logon attempts (default: 0 => off)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "disconnect time"
+attributetype ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff'
+ DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "refuse machine password change"
+attributetype ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange'
+ DESC 'Allow Machine Password changes (default: 0 => off)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+
+
#######################################################################
## objectClasses used by Samba 3.0 schema ##
@@ -448,7 +500,11 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
MUST ( sambaDomainName $
sambaSID )
MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
- sambaAlgorithmicRidBase ) )
+ sambaAlgorithmicRidBase $
+ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $
+ sambaMaxPwdAge $ sambaMinPwdAge $
+ sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $
+ sambaForceLogoff $ sambaRefuseMachinePwdChange ))
##
## used for idmap_ldap module
@@ -488,9 +544,3 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURA
## DESC 'Samba Privilege'
## MUST ( sambaSID )
## MAY ( sambaPrivilegeList ) )
-
-objectclass ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaAccountPolicy' SUP top STRUCTURAL
- DESC 'Samba Account Policy'
- MUST ( sambaAccountPolicyName $ sambaAccountPolicyValue )
- MAY ( description ) )
-
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 95457758a6..07c348bd84 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -63,6 +63,7 @@ RPCLIBDIR = $(LIBDIR)/rpc
IDMAPLIBDIR = $(LIBDIR)/idmap
CHARSETLIBDIR = $(LIBDIR)/charset
AUTHLIBDIR = $(LIBDIR)/auth
+CONFIGLIBDIR = $(LIBDIR)/config
CONFIGDIR = @configdir@
VARDIR = @localstatedir@
MANDIR = @mandir@
@@ -101,8 +102,7 @@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
LIBSMBSHAREMODES_MAJOR=0
LIBSMBSHAREMODES_MINOR=1
-
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -I$(srcdir)/tdb
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir)
FLAGS2 =
FLAGS3 =
FLAGS4 =
@@ -199,12 +199,12 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/talloc.o lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/messages.o \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
- lib/md5.o lib/hmacmd5.o lib/iconv.o \
+ lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
nsswitch/wb_client.o $(WBCOMMON_OBJ) \
- lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
+ lib/pam_errors.o intl/lang_tdb.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
- lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o @SOCKWRAP@
+ lib/secdesc.o lib/secace.o lib/secacl.o @SOCKWRAP@
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
@@ -256,13 +256,13 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
rpc_client/cli_ds.o rpc_client/cli_echo.o \
- rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
+ rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
REGOBJS_OBJ = registry/reg_objects.o
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \
- registry/reg_util.o registry/reg_dynamic.o
+ registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o
RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o
@@ -282,7 +282,10 @@ 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 \
- services/svc_spoolss.o services/svc_rcinit.o services/services_db.o
+ services/svc_spoolss.o services/svc_rcinit.o services/services_db.o \
+ services/svc_netlogon.o services/svc_winreg.o
+
+RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs.o rpc_server/srv_ntsvcs_nt.o
RPC_DFS_OBJ = rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
@@ -308,7 +311,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
rpc_parse/parse_svcctl.o \
- rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o $(REGOBJS_OBJ)
+ rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o \
+ rpc_parse/parse_ntsvcs.o $(REGOBJS_OBJ)
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
@@ -320,7 +324,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_sam_sid.o passdb/pdb_compat.o \
passdb/lookup_sid.o \
passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
- lib/system_smbd.o
+ lib/system_smbd.o lib/account_pol.o lib/privileges.o
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
@@ -414,8 +418,7 @@ PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
printing/print_iprint.o
PRINTBASE_OBJ = printing/notify.o printing/printing_db.o
-
-PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
+PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
@@ -432,7 +435,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
@@ -487,7 +490,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
rpcclient/display_sec.o rpcclient/cmd_ds.o \
- rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o
+ rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o \
+ rpcclient/cmd_test.o
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -521,11 +525,6 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o tdb/tdb.o tdb/spinlock.o
-CAC_OBJ = $(LIBSMBCLIENT_OBJ) \
- libmsrpc/libmsrpc.o libmsrpc/libmsrpc_internal.o \
- libmsrpc/cac_lsarpc.o libmsrpc/cac_winreg.o libmsrpc/cac_samr.o \
- libmsrpc/cac_svcctl.o
-
# This shared library is intended for linking with unit test programs
# to test Samba internals. It's called libbigballofmud.so to
# discourage casual usage.
@@ -561,7 +560,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_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) $(PRINTERDB_OBJ) $(REGFIO_OBJ)
+ $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
@@ -644,7 +643,8 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(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) $(RPC_SVCCTL_OBJ) $(RPC_EVENTLOG_OBJ) $(SMBLDAP_OBJ) \
- $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
+ $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ) \
+ $(RPC_NTSVCS_OBJ)
WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
@@ -655,8 +655,6 @@ PICOBJS = $(SMBWRAPPER_OBJ:.o=.@PICSUFFIX@)
LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
LIBSMBSHAREMODES_PICOBJS = $(LIBSMBSHAREMODES_OBJ:.o=.@PICSUFFIX@)
-CAC_PICOBJS = $(CAC_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) \
@@ -715,7 +713,7 @@ NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
libads/kerberos_verify.o $(SECRETS_OBJ) $(SERVER_MUTEX_OBJ) \
libads/authdata.o $(RPC_PARSE_OBJ0) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SMBLDAP_OBJ) $(DOSERR_OBJ)
+ $(SMBLDAP_OBJ) $(DOSERR_OBJ) rpc_parse/parse_net.o
######################################################################
# now the rules...
@@ -760,9 +758,7 @@ wins : SHOWFLAGS @WINBIND_WINS_NSS@
modules: SHOWFLAGS proto_exists $(MODULES)
-cac: SHOWFLAGS bin/libmsrpc.@SHLIBEXT@ bin/libmsrpc.a
-
-everything: all libsmbclient debug2html smbfilter talloctort modules torture cac \
+everything: all libsmbclient debug2html smbfilter talloctort modules torture \
$(EVERYTHING_PROGS)
.SUFFIXES:
@@ -1045,16 +1041,6 @@ bin/libsmbsharemodes.a: $(LIBSMBSHAREMODES_PICOBJS)
@echo Linking libsmbsharemodes non-shared library $@
@-$(AR) -rc $@ $(LIBSMBSHAREMODES_PICOBJS)
-bin/libmsrpc.@SHLIBEXT@: $(CAC_PICOBJS)
- @echo Linking libmsrpc shared library $@
- @$(SHLD) $(LDSHFLAGS) -o $@ $(CAC_PICOBJS) $(LDFLAGS) $(LIBS) \
- @SONAMEFLAG@`basename $@`
-
-bin/libmsrpc.a: $(CAC_PICOBJS)
- @echo Linking libmsrpc non-shared library $@
- @-$(AR) -rc $@ $(CAC_PICOBJS)
-
-
# This is probably wrong for anything other than the GNU linker.
bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
@echo Linking bigballofmud shared library $@
@@ -1091,6 +1077,11 @@ bin/librpc_svcctl.@SHLIBEXT@: $(RPC_SVCCTL_OBJ)
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVCCTL_OBJ) -lc \
@SONAMEFLAG@`basename $@`
+bin/librpc_ntsvcs.@SHLIBEXT@: $(RPC_NTSVCS_OBJ)
+ @echo "Linking $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_NTSVCS_OBJ) -lc \
+ @SONAMEFLAG@`basename $@`
+
bin/librpc_wkssvc.@SHLIBEXT@: $(RPC_WKS_OBJ)
@echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_WKS_OBJ) -lc \
@@ -1328,6 +1319,9 @@ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
@echo "Linking shared library $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc $(LDAP_LIBS) $(KRB5LIBS)
+bin/libmsrpc.a: $(LIBMSRPC_PICOBJ)
+ @-$(AR) -rc $@ $(LIBMSRPC_PICOBJ)
+
bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBBACKUP_OBJ) @SOCKWRAP@
@@ -1346,6 +1340,9 @@ bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
bin/t_strstr@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud
+bin/t_strappend@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strappend.o
+ $(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strappend.o -L ./bin -lbigballofmud
+
bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) torture/t_stringoverflow.o -L./bin -lbigballofmud
@@ -1634,7 +1631,7 @@ Makefile: $(srcdir)/Makefile.in config.status
# These are called by the test suite and need to be built before
# running it. For the time being we don't build all of BIN_PROGS,
# because they're not all needed.
-check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf
+# check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf bin/t_asn1
#test: all
# @if test -z "$(SMB4TORTURE)"; then \
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 9886526cf9..92c90b6241 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -235,7 +235,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
#ifdef DEBUG_PASSWORD
DEBUG(100, ("user_info has passwords of length %d and %d\n",
- user_info->lm_resp.length, user_info->nt_resp.length));
+ (int)user_info->lm_resp.length, (int)user_info->nt_resp.length));
DEBUG(100, ("lm:\n"));
dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
DEBUG(100, ("nt:\n"));
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index cdf87adebb..4abc6c6656 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -40,15 +40,17 @@ extern BOOL global_machine_password_needs_changing;
*
**/
-static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
- const char *domain, const char *dc_name,
- struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- const unsigned char *trust_passwd,
- BOOL *retry)
+static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
+ const char *domain,
+ const char *dc_name,
+ struct in_addr dc_ip,
+ struct rpc_pipe_client **pipe_ret,
+ BOOL *retry)
{
NTSTATUS result;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+
+ *pipe_ret = NULL;
/* TODO: Send a SAMLOGON request to determine whether this is a valid
logonserver. We can avoid a 30-second timeout if the DC is down
@@ -64,8 +66,9 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
*/
- if (!grab_server_mutex(dc_name))
+ if (!grab_server_mutex(dc_name)) {
return NT_STATUS_NO_LOGON_SERVERS;
+ }
/* Attempt connection */
*retry = True;
@@ -95,36 +98,65 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
*/
- if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
+ /* open the netlogon pipe. */
+ if (lp_client_schannel()) {
+ /* We also setup the creds chain in the open_schannel call. */
+ netlogon_pipe = cli_rpc_pipe_open_schannel(*cli, PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY, domain, &result);
+ } else {
+ netlogon_pipe = cli_rpc_pipe_open_noauth(*cli, PI_NETLOGON, &result);
+ }
+
+ if(!netlogon_pipe) {
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
+machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
cli_shutdown(*cli);
release_server_mutex();
- return NT_STATUS_NO_LOGON_SERVERS;
+ return result;
}
- fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as);
-
- /* This must be the remote domain (not ours) for schannel */
-
- fstrcpy( (*cli)->domain, domain );
+ if (!lp_client_schannel()) {
+ /* We need to set up a creds chain on an unauthenticated netlogon pipe. */
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 sec_chan_type = 0;
+ char machine_pwd[16];
+
+ if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
+ DEBUG(0, ("connect_to_domain_password_server: could not fetch "
+ "trust account password for domain '%s'\n",
+ domain));
+ cli_shutdown(*cli);
+ release_server_mutex();
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
- result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
+ result = rpccli_netlogon_setup_creds(netlogon_pipe,
+ dc_name,
+ domain,
+ global_myname(),
+ machine_pwd,
+ sec_chan_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_shutdown(*cli);
+ release_server_mutex();
+ return result;
+ }
+ }
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
-%s. Error was : %s.\n", dc_name, nt_errstr(result)));
- cli_nt_session_close(*cli);
- cli_ulogoff(*cli);
+ if(!netlogon_pipe) {
+ DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
+machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
cli_shutdown(*cli);
release_server_mutex();
- return result;
+ return NT_STATUS_NO_LOGON_SERVERS;
}
/* We exit here with the mutex *locked*. JRA */
+ *pipe_ret = netlogon_pipe;
+
return NT_STATUS_OK;
}
@@ -135,18 +167,17 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
************************************************************************/
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- const char *domain,
- uchar chal[8],
- auth_serversupplied_info **server_info,
- const char *dc_name, struct in_addr dc_ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- unsigned char trust_passwd[16],
- time_t last_change_time)
+ const auth_usersupplied_info *user_info,
+ const char *domain,
+ uchar chal[8],
+ auth_serversupplied_info **server_info,
+ const char *dc_name,
+ struct in_addr dc_ip)
+
{
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
int i;
BOOL retry = True;
@@ -162,8 +193,12 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
/* rety loop for robustness */
for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
- nt_status = connect_to_domain_password_server(&cli, domain, dc_name,
- dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry);
+ nt_status = connect_to_domain_password_server(&cli,
+ domain,
+ dc_name,
+ dc_ip,
+ &netlogon_pipe,
+ &retry);
}
if ( !NT_STATUS_IS_OK(nt_status) ) {
@@ -181,13 +216,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
* in the info3 structure.
*/
- nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
- NULL, user_info->smb_name.str, user_info->domain.str,
- user_info->wksta_name.str, chal, user_info->lm_resp,
- user_info->nt_resp, &info3);
-
- /* let go as soon as possible so we avoid any potential deadlocks
- with winbind lookup up users or groups */
+ nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+ mem_ctx,
+ dc_name, /* server name */
+ user_info->smb_name.str, /* user name logging on. */
+ user_info->domain.str, /* domain name */
+ user_info->wksta_name.str, /* workstation name */
+ chal, /* 8 byte challenge. */
+ user_info->lm_resp, /* lanman 24 byte response */
+ user_info->nt_resp, /* nt 24 byte response */
+ &info3); /* info3 out */
+
+ /* Let go as soon as possible so we avoid any potential deadlocks
+ with winbind lookup up users or groups. */
release_server_mutex();
@@ -195,7 +236,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
DEBUG(0,("domain_client_validate: unable to validate password "
"for user %s in domain %s to Domain controller %s. "
"Error was %s.\n", user_info->smb_name.str,
- user_info->domain.str, cli->srv_name_slash,
+ user_info->domain.str, dc_name,
nt_errstr(nt_status)));
/* map to something more useful */
@@ -203,32 +244,18 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
nt_status = NT_STATUS_NO_LOGON_SERVERS;
}
} else {
- nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
- user_info->smb_name.str, domain, server_info, &info3);
+ nt_status = make_server_info_info3(mem_ctx,
+ user_info->internal_username.str,
+ user_info->smb_name.str,
+ domain,
+ server_info,
+ &info3);
}
-#if 0
- /*
- * We don't actually need to do this - plus it fails currently with
- * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
- * send here. JRA.
- */
-
- if (NT_STATUS_IS_OK(status)) {
- if(cli_nt_logoff(&cli, &ctr) == False) {
- DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
- nt_status = NT_STATUS_LOGON_FAILURE;
- }
- }
-#endif /* 0 */
-
/* Note - once the cli stream is shutdown the mem_ctx used
to allocate the other_sids and gids structures has been deleted - so
these pointers are no longer valid..... */
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
cli_shutdown(cli);
return nt_status;
}
@@ -244,10 +271,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- unsigned char trust_passwd[16];
- time_t last_change_time;
const char *domain = lp_workgroup();
- uint32 sec_channel_type = 0;
fstring dc_name;
struct in_addr dc_ip;
@@ -273,26 +297,6 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
return NT_STATUS_NOT_IMPLEMENTED;
}
- /*
- * Get the machine account password for our primary domain
- * No need to become_root() as secrets_init() is done at startup.
- */
-
- if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type))
- {
- DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain));
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
- /* Test if machine password has expired and needs to be changed */
- if (lp_machine_password_timeout()) {
- if (last_change_time > 0 &&
- time(NULL) > (last_change_time +
- lp_machine_password_timeout())) {
- global_machine_password_needs_changing = True;
- }
- }
-
/* we need our DC to send the net_sam_logon() request to */
if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
@@ -301,9 +305,13 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
return NT_STATUS_NO_LOGON_SERVERS;
}
- nt_status = domain_client_validate(mem_ctx, user_info, domain,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- global_myname(), sec_channel_type,trust_passwd, last_change_time);
+ nt_status = domain_client_validate(mem_ctx,
+ user_info,
+ domain,
+ (uchar *)auth_context->challenge.data,
+ server_info,
+ dc_name,
+ dc_ip);
return nt_status;
}
@@ -357,7 +365,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
/* No point is bothering if this is not a trusted domain.
This return makes "map to guest = bad user" work again.
The logic is that if we know nothing about the domain, that
- user is known to us and does not exist */
+ user is not known to us and does not exist */
if ( !is_trusted_domain( user_info->domain.str ) )
return NT_STATUS_NOT_IMPLEMENTED;
@@ -367,8 +375,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
* No need to become_root() as secrets_init() is done at startup.
*/
- if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time))
- {
+ if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password,
+ &sid, &last_change_time)) {
DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str));
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
@@ -396,9 +404,13 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
return NT_STATUS_NO_LOGON_SERVERS;
}
- nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
- (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
- lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+ nt_status = domain_client_validate(mem_ctx,
+ user_info,
+ user_info->domain.str,
+ (uchar *)auth_context->challenge.data,
+ server_info,
+ dc_name,
+ dc_ip);
return nt_status;
}
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index 11d9aa09c4..738af73f49 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -114,13 +114,15 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
return nt_status;
}
if (auth_ntlmssp_state->server_info->user_session_key.length) {
- DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->user_session_key.length));
+ DEBUG(10, ("Got NT session key of length %u\n",
+ (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
*user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
auth_ntlmssp_state->server_info->user_session_key.data,
auth_ntlmssp_state->server_info->user_session_key.length);
}
if (auth_ntlmssp_state->server_info->lm_session_key.length) {
- DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length));
+ DEBUG(10, ("Got LM session key of length %u\n",
+ (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
*lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
auth_ntlmssp_state->server_info->lm_session_key.data,
auth_ntlmssp_state->server_info->lm_session_key.length);
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 6624631b53..194a1ad532 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -372,7 +372,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
unsigned char local_lm_response[24];
#ifdef DEBUG_PASSWORD
- DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
+ DEBUG(10,("Unencrypted password (len %d):\n",(int)plaintext_password.length));
dump_data(100, plaintext_password.data, plaintext_password.length);
#endif
@@ -641,6 +641,44 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
}
/******************************************************************************
+ Create a token for the root user to be used internally by smbd.
+ This is similar to running under the context of the LOCAL_SYSTEM account
+ in Windows. This is a read-only token. Do not modify it or free() it.
+ Create a copy if your need to change it.
+******************************************************************************/
+
+NT_USER_TOKEN *get_root_nt_token( void )
+{
+ static NT_USER_TOKEN *token = NULL;
+ DOM_SID u_sid, g_sid;
+ DOM_SID g_sids[1];
+ struct passwd *pw;
+ NTSTATUS result;
+
+ if ( token )
+ return token;
+
+ if ( !(pw = getpwnam( "root" )) ) {
+ DEBUG(0,("create_root_nt_token: getpwnam\"root\") failed!\n"));
+ return NULL;
+ }
+
+ /* get the user and primary group SIDs; although the
+ BUILTIN\Administrators SId is really the one that matters here */
+
+ if ( !NT_STATUS_IS_OK(uid_to_sid(&u_sid, pw->pw_uid)) )
+ return NULL;
+ if ( !NT_STATUS_IS_OK(gid_to_sid(&g_sid, pw->pw_gid)) )
+ return NULL;
+
+ sid_copy( &g_sids[0], &global_sid_Builtin_Administrators );
+
+ result = create_nt_user_token( &u_sid, &g_sid, 1, g_sids, False, &token);
+
+ return NT_STATUS_IS_OK(result) ? token : NULL;
+}
+
+/******************************************************************************
* this function returns the groups (SIDs) of the local SAM the user is in.
* If this samba server is a DC of the domain the user belongs to, it returns
* both domain groups and local / builtin groups. If the user is in a trusted
@@ -832,6 +870,61 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
}
/***************************************************************************
+ Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion
+ to a SAM_ACCOUNT
+***************************************************************************/
+
+NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info,
+ char *unix_username,
+ struct passwd *pwd,
+ PAC_LOGON_INFO *logon_info)
+{
+ NTSTATUS nt_status;
+ SAM_ACCOUNT *sampass = NULL;
+ DOM_SID user_sid, group_sid;
+ fstring dom_name;
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
+ return nt_status;
+ }
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
+ return nt_status;
+ }
+
+ /* only copy user_sid, group_sid and domain name out of the PAC for
+ * now, we will benefit from more later - Guenther */
+
+ sid_copy(&user_sid, &logon_info->info3.dom_sid.sid);
+ sid_append_rid(&user_sid, logon_info->info3.user_rid);
+ pdb_set_user_sid(sampass, &user_sid, PDB_SET);
+
+ sid_copy(&group_sid, &logon_info->info3.dom_sid.sid);
+ sid_append_rid(&group_sid, logon_info->info3.group_rid);
+ pdb_set_group_sid(sampass, &group_sid, PDB_SET);
+
+ unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1);
+ pdb_set_domain(sampass, dom_name, PDB_SET);
+
+ pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET);
+
+ (*server_info)->sam_account = sampass;
+
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
+ sampass, pwd->pw_uid, pwd->pw_gid)))
+ {
+ return nt_status;
+ }
+
+ (*server_info)->unix_name = smb_xstrdup(unix_username);
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ (*server_info)->uid = pwd->pw_uid;
+ (*server_info)->gid = pwd->pw_gid;
+ return nt_status;
+}
+
+
+/***************************************************************************
Make (and fill) a user_info struct from a 'struct passwd' by conversion
to a SAM_ACCOUNT
***************************************************************************/
diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c
index 3a81cba626..0c263b6ab3 100644
--- a/source3/auth/auth_winbind.c
+++ b/source3/auth/auth_winbind.c
@@ -38,7 +38,7 @@ static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response
}
prs_copy_data_in(&ps, (char *)info3_ndr, len);
prs_set_offset(&ps,0);
- if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+ if (!net_io_user_info3("", info3, &ps, 1, 3, False)) {
DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c
index a6136a9e2c..5750deb31c 100755
--- a/source3/client/mount.cifs.c
+++ b/source3/client/mount.cifs.c
@@ -39,7 +39,7 @@
#include <fcntl.h>
#define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "9"
+#define MOUNT_CIFS_VERSION_MINOR "8"
#ifndef MOUNT_CIFS_VENDOR_SUFFIX
#define MOUNT_CIFS_VENDOR_SUFFIX ""
@@ -127,10 +127,8 @@ static int open_cred_file(char * file_name)
if(fs == NULL)
return errno;
line_buf = malloc(4096);
- if(line_buf == NULL) {
- fclose(fs);
+ if(line_buf == NULL)
return -ENOMEM;
- }
while(fgets(line_buf,4096,fs)) {
/* parse line from credential file */
@@ -506,8 +504,6 @@ static int parse_options(char * options, int * filesys_flags)
*filesys_flags &= ~MS_NOSUID;
} else if (strncmp(data, "nodev", 5) == 0) {
*filesys_flags |= MS_NODEV;
- } else if (strncmp(data, "nobrl", 5) == 0) {
- *filesys_flags &= ~MS_MANDLOCK;
} else if (strncmp(data, "dev", 3) == 0) {
*filesys_flags &= ~MS_NODEV;
} else if (strncmp(data, "noexec", 6) == 0) {
@@ -574,15 +570,13 @@ static void check_for_comma(char ** ppasswrd)
char *pass;
int i,j;
int number_of_commas = 0;
- int len;
+ int len = strlen(*ppasswrd);
if(ppasswrd == NULL)
return;
else
(pass = *ppasswrd);
- len = strlen(pass);
-
for(i=0;i<len;i++) {
if(pass[i] == ',')
number_of_commas++;
@@ -696,8 +690,9 @@ static char * parse_server(char ** punc_name)
int length = strnlen(unc_name,1024);
char * share;
char * ipaddress_string = NULL;
- struct hostent * host_entry;
+ struct hostent * host_entry = NULL;
struct in_addr server_ipaddr;
+ int rc;
if(length > 1023) {
printf("mount error: UNC name too long");
@@ -720,13 +715,6 @@ static char * parse_server(char ** punc_name)
if(share) {
free_share_name = 1;
*punc_name = malloc(length+3);
- if(*punc_name == NULL) {
- /* put the original string back if
- no memory left */
- *punc_name = unc_name;
- return NULL;
- }
-
*share = '/';
strncpy((*punc_name)+2,unc_name,length);
unc_name = *punc_name;
@@ -756,7 +744,8 @@ continue_unc_parsing:
return NULL;
}
if(host_entry == NULL) {
- printf("mount error: could not find target server. TCP name %s not found\n", unc_name);
+ printf("mount error: could not find target server. TCP name %s not found ", unc_name);
+ printf(" rc = %d\n",rc);
return NULL;
} else {
/* BB should we pass an alternate version of the share name as Unicode */
@@ -1029,9 +1018,6 @@ mount_retry:
optlen = 0;
if(share_name)
optlen += strlen(share_name) + 4;
- else {
- printf("No server share name specified\n");
- }
if(user_name)
optlen += strlen(user_name) + 6;
if(ipaddr)
@@ -1140,6 +1126,8 @@ mount_retry:
strcat(mountent.mnt_opts,"rw");
if(flags & MS_MANDLOCK)
strcat(mountent.mnt_opts,",mand");
+ else
+ strcat(mountent.mnt_opts,",nomand");
if(flags & MS_NOEXEC)
strcat(mountent.mnt_opts,",noexec");
if(flags & MS_NOSUID)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index d13ae39416..da517297f7 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -70,6 +70,9 @@ static int smb_print(struct cli_state *, char *, FILE *);
FILE *fp; /* File to print */
int status=0; /* Status of LPD job */
struct cli_state *cli; /* SMB interface */
+ char null_str[1];
+
+ null_str[0] = '\0';
/* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
@@ -158,12 +161,12 @@ static int smb_print(struct cli_state *, char *, FILE *);
if ((password = strchr_m(username, ':')) != NULL)
*password++ = '\0';
else
- password = "";
+ password = null_str;
}
else
{
- username = "";
- password = "";
+ username = null_str;
+ password = null_str;
server = uri + 6;
}
@@ -335,10 +338,8 @@ char * get_ticket_cache( uid_t uid )
if ( ticket_file == NULL )
{
-#ifdef DEVELOPER
/* no ticket cache found */
fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
-#endif
return NULL;
}
diff --git a/source3/configure.in b/source3/configure.in
index aeb3dd5d47..deeab5886f 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -235,6 +235,7 @@ AC_SUBST(SMBWRAP_INC)
AC_SUBST(EXTRA_BIN_PROGS)
AC_SUBST(EXTRA_SBIN_PROGS)
AC_SUBST(EXTRA_ALL_TARGETS)
+AC_SUBST(CONFIG_LIBS)
# Set defaults
PIE_CFLAGS=""
@@ -359,9 +360,9 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then
changequote([,])dnl
AC_MSG_RESULT(${ac_cv_gnu_ld_date})
if test -n "$ac_cv_gnu_ld_date"; then
- if test "$ac_cv_gnu_ld_date" -lt 20030217; then
- ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes
- fi
+ if test "$ac_cv_gnu_ld_date" -lt 20030217; then
+ ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes
+ fi
else
AC_MSG_CHECKING(GNU ld release version)
changequote(,)dnl
@@ -457,10 +458,10 @@ 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_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"
+default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_ntsvcs rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
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 auth_script"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437 auth_script"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_echo"
@@ -1990,14 +1991,14 @@ dnl For IA64 HPUX systems, the libs are located in lib/hpux32 instead of lib.
for l in "lib32" "lib" "lib/hpux32"; do
if test -d "$i/$l" ; then
LDFLAGS="$save_LDFLAGS -L$i/$l"
- LIBS=
- export LDFLAGS LIBS CPPFLAGS
+ LIBS=
+ export LDFLAGS LIBS CPPFLAGS
dnl Try to find iconv(3)
jm_ICONV($i/$l)
if test x"$ICONV_FOUND" = "xyes" ; then
- libext="$l"
- break;
- fi
+ libext="$l"
+ break;
+ fi
fi
done
@@ -2005,7 +2006,7 @@ dnl Try to find iconv(3)
LDFLAGS=$save_LDFLAGS
LIB_ADD_DIR(LDFLAGS, "$i/$libext")
CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
- LIBS="$save_LIBS"
+ LIBS="$save_LIBS"
ICONV_LOCATION=$i
export LDFLAGS LIBS CPPFLAGS
dnl Now, check for a working iconv ... we want to do it here because
@@ -2820,6 +2821,7 @@ if test x"$with_ldap_support" != x"no"; then
if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then
AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
+ default_shared_modules="$default_shared_modules";
SMBLDAP="lib/smbldap.o"
SMBLDAPUTIL="lib/smbldap_util.o"
with_ldap_support=yes
@@ -3048,9 +3050,77 @@ if test x"$with_ads_support" != x"no"; then
AC_CHECK_FUNC_EXT(krb5_krbhst_get_addrinfo, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_c_enctype_compare, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_crypto_init, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_crypto_destroy, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_decode_ap_req, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(decode_krb5_ap_req, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_free_ap_req, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(free_AP_REQ, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_c_verify_checksum, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_principal_compare_any_realm, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_parse_name_norealm, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_princ_size, $KRB5_LIBS)
LIBS="$KRB5_LIBS $LIBS"
-
+
+ AC_CACHE_CHECK(whether krb5_verify_checksum takes 7 arguments, smb_krb5_verify_checksum, [
+ AC_TRY_COMPILE([
+ #include <krb5.h>],
+ [krb5_verify_checksum(0, 0, 0, 0, 0, 0, 0);],
+ [smb_krb5_verify_checksum=7],
+ [smb_krb5_verify_checksum=6],
+ )
+ ])
+ AC_DEFINE_UNQUOTED(KRB5_VERIFY_CHECKSUM_ARGS, $smb_krb5_verify_checksum, [Number of arguments to krb5_verify_checksum])
+
+ AC_CACHE_CHECK([for checksum in krb5_checksum],
+ samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_checksum cksum; cksum.checksum.length = 0;],
+ samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM=yes,
+ samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM=no)])
+
+ if test x"$samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM" = x"yes"; then
+ AC_DEFINE(HAVE_CHECKSUM_IN_KRB5_CHECKSUM,1,
+ [Whether the krb5_checksum struct has a checksum property])
+ fi
+
+ AC_CACHE_CHECK([for etype in EncryptedData],
+ samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [EncryptedData edata; edata.etype = 0;],
+ samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA=yes,
+ samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA=no)])
+
+ if test x"$samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA" = x"yes"; then
+ AC_DEFINE(HAVE_ETYPE_IN_ENCRYPTEDDATA,1,
+ [Whether the EncryptedData struct has a etype property])
+ fi
+
+ AC_CACHE_CHECK([for ticket pointer in krb5_ap_req],
+ samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_ap_req *ap_req; ap_req->ticket = NULL;],
+ samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ=yes,
+ samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ=no)])
+
+ if test x"$samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ" = x"yes"; then
+ AC_DEFINE(HAVE_TICKET_POINTER_IN_KRB5_AP_REQ,1,
+ [Whether the krb5_ap_req struct has a ticket pointer])
+ fi
+
+ AC_CACHE_CHECK([for krb5_crypto type],
+ samba_cv_HAVE_KRB5_CRYPTO,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_crypto crypto;],
+ samba_cv_HAVE_KRB5_CRYPTO=yes,
+ samba_cv_HAVE_KRB5_CRYPTO=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_CRYPTO" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_CRYPTO,1,
+ [Whether the type krb5_crypto exists])
+ fi
+
AC_CACHE_CHECK([for krb5_encrypt_block type],
samba_cv_HAVE_KRB5_ENCRYPT_BLOCK,[
AC_TRY_COMPILE([#include <krb5.h>],
@@ -3178,6 +3248,30 @@ if test x"$with_ads_support" != x"no"; then
[Whether the KV5M_KEYTAB option is available])
fi
+ AC_CACHE_CHECK([for KRB5_KU_OTHER_CKSUM],
+ samba_cv_HAVE_KRB5_KU_OTHER_CKSUM,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_keyusage usage = KRB5_KU_OTHER_CKSUM;],
+ samba_cv_HAVE_KRB5_KU_OTHER_CKSUM=yes,
+ samba_cv_HAVE_KRB5_KU_OTHER_CKSUM=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_KU_OTHER_CKSUM" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_KU_OTHER_CKSUM,1,
+ [Whether KRB5_KU_OTHER_CKSUM is available])
+ fi
+
+ AC_CACHE_CHECK([for KRB5_KEYUSAGE_APP_DATA_CKSUM],
+ samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_keyusage usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;],
+ samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM=yes,
+ samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM,1,
+ [Whether KRB5_KEYUSAGE_APP_DATA_CKSUM is available])
+ fi
+
AC_CACHE_CHECK([for the krb5_princ_component macro],
samba_cv_HAVE_KRB5_PRINC_COMPONENT,[
AC_TRY_LINK([#include <krb5.h>],
@@ -3915,7 +4009,6 @@ AC_ARG_WITH(libsmbclient,
INSTALLCLIENT=installclientlib
)
-
INSTALLCLIENTCMD_SH=:
INSTALLCLIENTCMD_A=:
INSTALLCLIENT=
@@ -3925,19 +4018,19 @@ AC_MSG_CHECKING(whether to build the libsmbsharemodes shared library)
AC_ARG_WITH(libsmbsharemodes,
[ --with-libsmbsharemodes Build the libsmbsharemodes shared library (default=yes if shared libs supported)],
[ case "$withval" in
- no)
+ no)
AC_MSG_RESULT(no)
;;
*)
if test $BLDSHARED = true; then
INSTALLCLIENTCMD_SH="\$(INSTALLCMD)"
- ## build the static version of libsmbsharemodes as well
- INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
+ ## build the static version of libsmbsharemodes as well
+ INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
LIBSMBSHAREMODES_SHARED=bin/libsmbsharemodes.$SHLIBEXT
LIBSMBSHAREMODES=libsmbsharemodes
AC_MSG_RESULT(yes)
else
- enable_static=yes
+ enable_static=yes
AC_MSG_RESULT(no shared library support -- will supply static library)
fi
if test $enable_static = yes; then
@@ -3965,7 +4058,6 @@ AC_ARG_WITH(libsmbsharemodes,
INSTALLCLIENT=installclientlib
)
-
#################################################
# these tests are taken from the GNU fileutils package
AC_CHECKING(how to get filesystem space usage)
@@ -4951,11 +5043,13 @@ SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
SMB_MODULE(pdb_guest, passdb/pdb_guest.o, "bin/guest.$SHLIBEXT", PDB)
SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o)
+
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_ntsvcs, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs.$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)
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index a30e8eed78..3ca074581c 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2001.
+ * Copyright (C) Jean François Micouleau 1998-2001.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -365,7 +365,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
Remove a group mapping entry.
****************************************************************************/
-static BOOL group_map_remove(DOM_SID sid)
+static BOOL group_map_remove(const DOM_SID *sid)
{
TDB_DATA kbuf, dbuf;
pstring key;
@@ -378,7 +378,7 @@ static BOOL group_map_remove(DOM_SID sid)
/* the key is the SID, retrieving is direct */
- sid_to_string(string_sid, &sid);
+ sid_to_string(string_sid, sid);
slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
kbuf.dptr = key;
@@ -954,7 +954,6 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
return True;
}
-
/****************************************************************************
Create a UNIX group on demand.
****************************************************************************/
@@ -988,8 +987,8 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
close(fd);
}
- }
-
+ }
+
if (*new_gid == 0) {
struct group *grp = getgrnam(unix_group);
@@ -1018,7 +1017,7 @@ int smb_delete_group(char *unix_group)
DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
return ret;
}
-
+
return -1;
}
@@ -1131,7 +1130,7 @@ NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
DOM_SID sid)
{
- return group_map_remove(sid) ?
+ return group_map_remove(&sid) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -1173,18 +1172,12 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
if (lookup_name(get_global_sam_name(), name, &sid, &type))
return NT_STATUS_ALIAS_EXISTS;
- if (!winbind_allocate_rid(&new_rid))
+ if (!winbind_allocate_rid_and_gid(&new_rid, &gid))
return NT_STATUS_ACCESS_DENIED;
sid_copy(&sid, get_global_sam_sid());
sid_append_rid(&sid, new_rid);
- /* Here we allocate the gid */
- if (!winbind_sid_to_gid(&gid, &sid)) {
- DEBUG(0, ("Could not get gid for new RID\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
map.gid = gid;
sid_copy(&map.sid, &sid);
map.sid_name_use = SID_NAME_ALIAS;
@@ -1282,7 +1275,7 @@ NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
return result;
*alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
- if ((alias_sids != 0) && (*alias_rids == NULL))
+ if (*alias_rids == NULL)
return NT_STATUS_NO_MEMORY;
*num_alias_rids = 0;
@@ -1347,3 +1340,38 @@ NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
+/****************************************************************************
+ These need to be redirected through pdb_interface.c
+****************************************************************************/
+BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info)
+{
+ GROUP_MAP map;
+ BOOL res;
+
+ become_root();
+ res = get_domain_group_from_sid(*sid, &map);
+ unbecome_root();
+
+ if (!res)
+ return False;
+
+ fstrcpy(info->acct_name, map.nt_name);
+ fstrcpy(info->acct_desc, map.comment);
+ sid_peek_rid(sid, &info->rid);
+ return True;
+}
+
+BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info)
+{
+ GROUP_MAP map;
+
+ if (!get_domain_group_from_sid(*sid, &map))
+ return False;
+
+ fstrcpy(map.nt_name, info->acct_name);
+ fstrcpy(map.comment, info->acct_desc);
+
+ return pdb_update_group_mapping_entry(&map);
+}
+
+
diff --git a/source3/include/ads.h b/source3/include/ads.h
index 8f6cc6e582..d2eeaab4d8 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -130,7 +130,7 @@ typedef void **ADS_MODLIST;
#define UF_UNUSED_5 0x00800000
#define UF_UNUSED_6 0x01000000
-#define UF_UNUSED_7 0x02000000
+#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
#define UF_UNUSED_8 0x04000000
#define UF_UNUSED_9 0x08000000
diff --git a/source3/include/asn_1.h b/source3/include/asn_1.h
index 796c8bb740..63a18c4923 100644
--- a/source3/include/asn_1.h
+++ b/source3/include/asn_1.h
@@ -27,7 +27,7 @@ struct nesting {
struct nesting *next;
};
-typedef struct {
+typedef struct asn1_data {
uint8 *data;
size_t length;
off_t ofs;
@@ -37,13 +37,16 @@ typedef struct {
#define ASN1_APPLICATION(x) ((x)+0x60)
+#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40)
#define ASN1_SEQUENCE(x) ((x)+0x30)
#define ASN1_CONTEXT(x) ((x)+0xa0)
+#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80)
#define ASN1_GENERAL_STRING 0x1b
#define ASN1_OCTET_STRING 0x4
#define ASN1_OID 0x6
#define ASN1_BOOLEAN 0x1
#define ASN1_INTEGER 0x2
+#define ASN1_BITFIELD 0x3
#define ASN1_ENUMERATED 0xa
#define ASN1_SET 0x31
diff --git a/source3/include/authdata.h b/source3/include/authdata.h
index 1be127aaac..194429ab67 100644
--- a/source3/include/authdata.h
+++ b/source3/include/authdata.h
@@ -23,12 +23,22 @@
#define _AUTHDATA_H
#include "rpc_misc.h"
+#include "rpc_netlogon.h"
#define PAC_TYPE_LOGON_INFO 1
#define PAC_TYPE_SERVER_CHECKSUM 6
#define PAC_TYPE_PRIVSVR_CHECKSUM 7
#define PAC_TYPE_LOGON_NAME 10
+#ifndef KRB5_AUTHDATA_WIN2K_PAC
+#define KRB5_AUTHDATA_WIN2K_PAC 128
+#endif
+
+#ifndef KRB5_AUTHDATA_IF_RELEVANT
+#define KRB5_AUTHDATA_IF_RELEVANT 1
+#endif
+
+
typedef struct pac_logon_name {
NTTIME logon_time;
uint16 len;
@@ -37,7 +47,7 @@ typedef struct pac_logon_name {
typedef struct pac_signature_data {
uint32 type;
- uint8 *signature;
+ RPC_DATA_BLOB signature; /* this not the on-wire-format (!) */
} PAC_SIGNATURE_DATA;
typedef struct group_membership {
@@ -50,6 +60,8 @@ typedef struct group_membership_array {
GROUP_MEMBERSHIP *group_membership;
} GROUP_MEMBERSHIP_ARRAY;
+#if 0 /* Unused, replaced by NET_USER_INFO_3 - Guenther */
+
typedef struct krb_sid_and_attrs {
uint32 sid_ptr;
uint32 attrs;
@@ -82,7 +94,7 @@ typedef struct pac_logon_info {
UNIHDR hdr_dir_drive;
uint16 logon_count; /* number of times user has logged onto domain */
- uint16 reserved12;
+ uint16 bad_password_count; /* samba4 idl */
uint32 user_rid;
uint32 group_rid;
@@ -90,15 +102,15 @@ typedef struct pac_logon_info {
uint32 group_membership_ptr;
uint32 user_flags;
- uint32 reserved13[4];
+ uint8 session_key[16]; /* samba4 idl */
UNIHDR hdr_dom_controller;
UNIHDR hdr_dom_name;
uint32 ptr_dom_sid;
-
- uint32 reserved16[2];
- uint32 reserved17; /* looks like it may be acb_info */
- uint32 reserved18[7];
+
+ uint8 lm_session_key[8]; /* samba4 idl */
+ uint32 acct_flags; /* samba4 idl */
+ uint32 unknown[7];
uint32 sid_count;
uint32 ptr_extra_sids;
@@ -122,6 +134,14 @@ typedef struct pac_logon_info {
GROUP_MEMBERSHIP_ARRAY res_groups;
} PAC_LOGON_INFO;
+#endif
+
+typedef struct pac_logon_info {
+ NET_USER_INFO_3 info3;
+ DOM_SID2 res_group_dom_sid;
+ GROUP_MEMBERSHIP_ARRAY res_groups;
+
+} PAC_LOGON_INFO;
typedef struct pac_info_ctr
{
@@ -134,18 +154,19 @@ typedef struct pac_info_ctr
} pac;
} PAC_INFO_CTR;
-typedef struct pac_info_hdr {
+typedef struct pac_buffer {
uint32 type;
uint32 size;
uint32 offset;
uint32 offsethi;
PAC_INFO_CTR *ctr;
-} PAC_INFO_HDR;
+ uint32 pad;
+} PAC_BUFFER;
typedef struct pac_data {
uint32 num_buffers;
uint32 version;
- PAC_INFO_HDR *pac_info_hdr_ptr;
+ PAC_BUFFER *pac_buffer;
} PAC_DATA;
diff --git a/source3/include/client.h b/source3/include/client.h
index e9d40c3b7c..df52e227f0 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -57,25 +57,39 @@ struct print_job_info
time_t t;
};
+struct cli_pipe_auth_data {
+ enum pipe_auth_type auth_type; /* switch for the union below. Defined in ntdomain.h */
+ enum pipe_auth_level auth_level; /* defined in ntdomain.h */
+ union {
+ struct schannel_auth_struct *schannel_auth;
+ NTLMSSP_STATE *ntlmssp_state;
+ struct kerberos_auth_struct *kerberos_auth;
+ } a_u;
+ void (*cli_auth_data_free_func)(struct cli_pipe_auth_data *);
+};
+
struct rpc_pipe_client {
+ struct rpc_pipe_client *prev, *next;
+
TALLOC_CTX *mem_ctx;
struct cli_state *cli;
int pipe_idx;
+ const char *pipe_name;
uint16 fnum;
- int pipe_auth_flags;
-
- NTLMSSP_STATE *ntlmssp_pipe_state;
- const char *user_name;
const char *domain;
+ const char *user_name;
struct pwd_info pwd;
- struct netsec_auth_struct auth_info;
-
uint16 max_xmit_frag;
uint16 max_recv_frag;
+
+ struct cli_pipe_auth_data auth;
+
+ /* The following is only non-null on a netlogon pipe. */
+ struct dcinfo *dc;
};
struct cli_state {
@@ -92,8 +106,11 @@ struct cli_state {
int privileges;
fstring desthost;
- fstring user_name;
+
+ /* The credentials used to open the cli_state connection. */
fstring domain;
+ fstring user_name;
+ struct pwd_info pwd;
/*
* The following strings are the
@@ -111,7 +128,6 @@ struct cli_state {
fstring full_dest_host_name;
struct in_addr dest_ip;
- struct pwd_info pwd;
DATA_BLOB secblob; /* cryptkey or negTokenInit */
uint32 sesskey;
int serverzone;
@@ -137,27 +153,8 @@ struct cli_state {
any per-pipe authenticaion */
DATA_BLOB user_session_key;
- /*
- * Only used in NT domain calls.
- */
-
- int pipe_idx; /* Index (into list of known pipes)
- of the pipe we're talking to,
- if any */
-
- struct rpc_pipe_client pipes[PI_MAX_PIPES];
-
- /* Secure pipe parameters */
- int pipe_auth_flags;
-
- struct rpc_pipe_client netlogon_pipe; /* The "first" pipe to get
- the session key for the
- schannel. */
- unsigned char sess_key[16]; /* Current session key. */
- DOM_CRED clnt_cred; /* Client credential. */
- fstring mach_acct; /* MYNAME$. */
- fstring srv_name_slash; /* \\remote server. */
- fstring clnt_name_slash; /* \\local client. */
+ /* The list of pipes currently open on this connection. */
+ struct rpc_pipe_client *pipe_list;
BOOL use_kerberos;
BOOL fallback_after_kerberos;
@@ -175,9 +172,6 @@ struct cli_state {
/* was this structure allocated by cli_initialise? If so, then
free in cli_shutdown() */
BOOL allocated;
-
- /* Name of the pipe we're talking to, if any */
- fstring pipe_name;
};
#define CLI_FULL_CONNECTION_DONT_SPNEGO 0x0001
diff --git a/source3/include/dlinklist.h b/source3/include/dlinklist.h
index 794aea7576..c856aaa762 100644
--- a/source3/include/dlinklist.h
+++ b/source3/include/dlinklist.h
@@ -70,6 +70,20 @@
} \
}
+/* insert 'p' after the given element 'el' in a list. If el is NULL then
+ this is the same as a DLIST_ADD() */
+#define DLIST_ADD_AFTER(list, p, el) \
+do { \
+ if (!(list) || !(el)) { \
+ DLIST_ADD(list, p); \
+ } else { \
+ p->prev = el; \
+ p->next = el->next; \
+ el->next = p; \
+ if (p->next) p->next->prev = p; \
+ }\
+} while (0)
+
/* demote an element to the top of the list, needs a tmp pointer */
#define DLIST_DEMOTE(list, p, tmp) \
{ \
diff --git a/source3/include/doserr.h b/source3/include/doserr.h
index 7c98171250..593d5d99ee 100644
--- a/source3/include/doserr.h
+++ b/source3/include/doserr.h
@@ -5,6 +5,7 @@
Copyright (C) John H Terpstra 1996-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Paul Ashton 1998-2000
+ Copyright (C) Gerald (Jerry) Carter 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -174,6 +175,7 @@
#define WERR_NOMEM W_ERROR(8)
#define WERR_GENERAL_FAILURE W_ERROR(31)
#define WERR_NOT_SUPPORTED W_ERROR(50)
+#define WERR_DEVICE_NOT_EXIST W_ERROR(55)
#define WERR_PRINTQ_FULL W_ERROR(61)
#define WERR_NO_SPOOL_SPACE W_ERROR(62)
#define WERR_NO_SUCH_SHARE W_ERROR(67)
@@ -227,6 +229,12 @@
#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse)
#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued)
+/* Configuration Manager Errors */
+/* Basically Win32 errors meanings are specific to the \ntsvcs pipe */
+
+#define WERR_CM_NO_MORE_HW_PROFILES W_ERROR(35)
+#define WERR_CM_NO_SUCH_VALUE W_ERROR(37)
+
/* DFS errors */
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 51aa218ac6..573982903b 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -27,7 +27,8 @@
#ifndef __cplusplus
#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
-#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
+/* allow to build with newer heimdal releases */
+/* #define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES */
#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
@@ -288,6 +289,7 @@
#include <net/if.h>
#endif
+
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
@@ -896,19 +898,17 @@ extern int errno;
#include "privileges.h"
-#include "rpc_creds.h"
+#include "rpc_misc.h"
+
+#include "rpc_dce.h"
#include "mapping.h"
#include "passdb.h"
-#include "ntdomain.h"
-
-#include "rpc_misc.h"
-
#include "rpc_secdes.h"
-#include "nt_printing.h"
+#include "authdata.h"
#include "msdfs.h"
@@ -923,6 +923,29 @@ extern int errno;
#include "auth.h"
+#include "ntdomain.h"
+
+#include "rpc_svcctl.h"
+#include "rpc_ntsvcs.h"
+#include "rpc_lsa.h"
+#include "rpc_netlogon.h"
+#include "reg_objects.h"
+#include "rpc_reg.h"
+#include "rpc_samr.h"
+#include "rpc_srvsvc.h"
+#include "rpc_wkssvc.h"
+#include "rpc_spoolss.h"
+#include "rpc_eventlog.h"
+#include "rpc_dfs.h"
+#include "rpc_ds.h"
+#include "rpc_echo.h"
+#include "rpc_shutdown.h"
+#include "rpc_unixinfo.h"
+#include "rpc_perfcount.h"
+#include "rpc_perfcount_defs.h"
+
+#include "nt_printing.h"
+
#include "idmap.h"
#include "client.h"
@@ -945,6 +968,8 @@ extern int errno;
#include "spnego.h"
+#include "rpc_client.h"
+
/*
* Type for wide character dirent structure.
* Only d_name is defined by POSIX.
@@ -995,6 +1020,8 @@ struct smb_ldap_privates;
#include "smbldap.h"
+#include "smb_ldap.h"
+
/***** automatically generated prototypes *****/
#ifndef NO_PROTO_H
#include "proto.h"
@@ -1414,7 +1441,7 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val);
void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
-void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt);
+BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
diff --git a/source3/include/messages.h b/source3/include/messages.h
index 1039e0d9a7..abe219374e 100644
--- a/source3/include/messages.h
+++ b/source3/include/messages.h
@@ -63,6 +63,11 @@
#define MSG_SMB_SAM_SYNC 3003
#define MSG_SMB_SAM_REPL 3004
#define MSG_SMB_UNLOCK 3005
+#define MSG_SMB_BREAK_REQUEST 3006
+#define MSG_SMB_BREAK_RESPONSE 3007
+#define MSG_SMB_ASYNC_LEVEL2_BREAK 3008
+#define MSG_SMB_OPEN_RETRY 3009
+#define MSG_SMB_KERNEL_BREAK 3010
/* winbind messages */
#define MSG_WINBIND_FINISHED 4001
@@ -77,4 +82,8 @@
#define FLAG_MSG_PRINT_NOTIFY 0x0008
#define FLAG_MSG_PRINT_GENERAL 0x0010
+struct process_id {
+ pid_t pid;
+};
+
#endif
diff --git a/source3/include/module.h b/source3/include/module.h
index c41310c7f7..8b317a9d59 100644
--- a/source3/include/module.h
+++ b/source3/include/module.h
@@ -33,6 +33,4 @@ typedef int smb_event_id_t;
typedef void (smb_idle_event_fn)(void **data,time_t *interval,time_t now);
-typedef void (smb_exit_event_fn)(void **data);
-
#endif /* _MODULE_H */
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 87fac492db..967aac2bb5 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -24,30 +24,6 @@
#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
#define _NT_DOMAIN_H
-struct uuid {
- uint32 time_low;
- uint16 time_mid;
- uint16 time_hi_and_version;
- uint8 clock_seq[2];
- uint8 node[6];
-};
-#define UUID_SIZE 16
-
-#define UUID_FLAT_SIZE 16
-typedef struct uuid_flat {
- uint8 info[UUID_FLAT_SIZE];
-} UUID_FLAT;
-
-/* dce/rpc support */
-#include "rpc_dce.h"
-
-/* miscellaneous structures / defines */
-#include "rpc_misc.h"
-
-#include "rpc_creds.h"
-
-#include "talloc.h"
-
/*
* A bunch of stuff that was put into smb.h
* in the NTDOM branch - it didn't belong there.
@@ -67,6 +43,7 @@ typedef struct _prs_struct {
uint32 grow_size; /* size requested via prs_grow() calls */
char *data_p; /* The buffer itself. */
TALLOC_CTX *mem_ctx; /* When unmarshalling, use this.... */
+ const char *sess_key; /* If we have to do encrypt/decrypt on the fly. */
} prs_struct;
/*
@@ -97,7 +74,7 @@ typedef struct _output_data {
* The current PDU being returned. This inclues
* headers, data and authentication footer.
*/
- unsigned char current_pdu[MAX_PDU_FRAG_LEN];
+ unsigned char current_pdu[RPC_MAX_PDU_FRAG_LEN];
/* The amount of data in the current_pdu buffer. */
uint32 current_pdu_len;
@@ -111,9 +88,9 @@ typedef struct _input_data {
* This is the current incoming pdu. The data here
* is collected via multiple writes until a complete
* pdu is seen, then the data is copied into the in_data
- * structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN).
+ * structure. The maximum size of this is 0x1630 (RPC_MAX_PDU_FRAG_LEN).
*/
- unsigned char current_in_pdu[MAX_PDU_FRAG_LEN];
+ unsigned char current_in_pdu[RPC_MAX_PDU_FRAG_LEN];
/*
* The amount of data needed to complete the in_pdu.
@@ -158,22 +135,22 @@ struct handle_list {
/* Domain controller authentication protocol info */
struct dcinfo {
- DOM_CHAL clnt_chal; /* Initial challenge received from client */
- DOM_CHAL srv_chal; /* Initial server challenge */
- DOM_CRED clnt_cred; /* Last client credential */
- DOM_CRED srv_cred; /* Last server credential */
+ uint32 sequence; /* "timestamp" from client. */
+ DOM_CHAL seed_chal;
+ DOM_CHAL clnt_chal; /* Client credential */
+ DOM_CHAL srv_chal; /* Server credential */
uchar sess_key[8]; /* Session key */
- uchar md4pw[16]; /* md4(machine password) */
+ uchar mach_pw[16]; /* md4(machine password) */
fstring mach_acct; /* Machine name we've authenticated. */
fstring remote_machine; /* Machine name we've authenticated. */
+ fstring domain;
BOOL challenge_sent;
BOOL got_session_key;
BOOL authenticated;
-
};
typedef struct pipe_rpc_fns {
@@ -189,6 +166,46 @@ typedef struct pipe_rpc_fns {
} PIPE_RPC_FNS;
/*
+ * Different auth types we support.
+ * Can't keep in sync with wire values as spnego wraps different auth methods.
+ */
+
+enum pipe_auth_type { PIPE_AUTH_TYPE_NONE = 0, PIPE_AUTH_TYPE_NTLMSSP, PIPE_AUTH_TYPE_SCHANNEL,
+ PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, PIPE_AUTH_TYPE_KRB5, PIPE_AUTH_TYPE_SPNEGO_KRB5 };
+
+/* Possible auth levels - keep these in sync with the wire values. */
+enum pipe_auth_level { PIPE_AUTH_LEVEL_NONE = 0,
+ PIPE_AUTH_LEVEL_CONNECT = 1, /* We treat as NONE. */
+ PIPE_AUTH_LEVEL_INTEGRITY = 5, /* Sign. */
+ PIPE_AUTH_LEVEL_PRIVACY = 6 /* Seal. */
+};
+
+/* auth state for krb5. */
+struct kerberos_auth_struct {
+ const char *service_principal;
+ DATA_BLOB session_key;
+};
+
+/* auth state for schannel. */
+struct schannel_auth_struct {
+ uchar sess_key[16];
+ uint32 seq_num;
+};
+
+/* auth state for all bind types. */
+
+struct pipe_auth_data {
+ enum pipe_auth_type auth_type; /* switch for union below. */
+ enum pipe_auth_level auth_level;
+ union {
+ struct schannel_auth_struct *schannel_auth;
+ AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
+/* struct kerberos_auth_struct *kerberos_auth; TO BE ADDED... */
+ } a_u;
+ void (*auth_data_free_func)(struct pipe_auth_data *);
+};
+
+/*
* DCE/RPC-specific samba-internal-specific handling of data on
* NamedPipes.
*/
@@ -210,20 +227,12 @@ typedef struct pipes_struct {
RPC_HDR hdr; /* Incoming RPC header. */
RPC_HDR_REQ hdr_req; /* Incoming request header. */
- uint32 ntlmssp_chal_flags; /* Client challenge flags. */
- BOOL ntlmssp_auth_requested; /* If the client wanted authenticated rpc. */
- BOOL ntlmssp_auth_validated; /* If the client *got* authenticated rpc. */
- unsigned char challenge[8];
- unsigned char ntlmssp_hash[258];
- uint32 ntlmssp_seq_num;
- struct dcinfo dc; /* Keeps the creds data. */
+ /* This context is used for pipe state storage and is freed when the pipe is closed. */
+ TALLOC_CTX *pipe_state_mem_ctx;
- /* Hmm. In my understanding the authentication happens
- implicitly later, so there are no two stages for
- schannel. */
+ struct pipe_auth_data auth;
- BOOL netsec_auth_validated;
- struct netsec_auth_struct netsec_auth;
+ struct dcinfo *dc; /* Keeps the creds data from netlogon. */
/*
* Windows user info.
@@ -233,14 +242,13 @@ typedef struct pipes_struct {
fstring wks;
/*
- * Unix user name and credentials.
+ * Unix user name and credentials used when a pipe is authenticated.
*/
fstring pipe_user_name;
struct current_user pipe_user;
-
DATA_BLOB session_key;
-
+
/*
* Set to true when an RPC bind has been done on this pipe.
*/
@@ -277,7 +285,8 @@ typedef struct pipes_struct {
output_data out_data;
- /* talloc context to use when allocating memory on this pipe. */
+ /* This context is used for PUD data and is freed between each pdu.
+ Don't use for pipe state storage. */
TALLOC_CTX *mem_ctx;
/* handle database to use on this pipe. */
@@ -383,27 +392,11 @@ typedef struct {
/* end higher order functions */
-
-/* security descriptor structures */
-#include "rpc_secdes.h"
-
-/* pac */
-#include "authdata.h"
-
-/* different dce/rpc pipes */
-#include "rpc_buffer.h"
-#include "rpc_lsa.h"
-#include "rpc_netlogon.h"
-#include "rpc_reg.h"
-#include "rpc_samr.h"
-#include "rpc_srvsvc.h"
-#include "rpc_wkssvc.h"
-#include "rpc_svcctl.h"
-#include "rpc_spoolss.h"
-#include "rpc_eventlog.h"
-#include "rpc_dfs.h"
-#include "rpc_ds.h"
-#include "rpc_echo.h"
-#include "rpc_shutdown.h"
+typedef struct {
+ uint32 size;
+ prs_struct prs;
+ uint32 struct_start;
+ uint32 string_at_end;
+} RPC_BUFFER;
#endif /* _NT_DOMAIN_H */
diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h
index 267779c434..30a37e06c3 100644
--- a/source3/include/ntlmssp.h
+++ b/source3/include/ntlmssp.h
@@ -34,7 +34,8 @@ enum NTLM_MESSAGE_TYPE
NTLMSSP_NEGOTIATE = 1,
NTLMSSP_CHALLENGE = 2,
NTLMSSP_AUTH = 3,
- NTLMSSP_UNKNOWN = 4
+ NTLMSSP_UNKNOWN = 4,
+ NTLMSSP_DONE = 5 /* samba final state */
};
/* NTLMSSP negotiation flags */
@@ -61,13 +62,15 @@ enum NTLM_MESSAGE_TYPE
#define NTLMSSP_CHAL_TARGET_INFO 0x00800000
#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
-#define NTLMSSP_NEGOTIATE_080000000 0x80000000
+#define NTLMSSP_NEGOTIATE_56 0x80000000
#define NTLMSSP_NAME_TYPE_SERVER 0x01
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03
#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04
+#define NTLMSSP_SIG_SIZE 16
+
typedef struct ntlmssp_state
{
TALLOC_CTX *mem_ctx;
@@ -142,23 +145,22 @@ typedef struct ntlmssp_state
const char *(*get_global_myname)(void);
const char *(*get_domain)(void);
- /* SMB Signing */
-
- uint32 ntlmssp_seq_num;
-
/* ntlmv2 */
- unsigned char send_sign_const[16];
- unsigned char send_seal_const[16];
- unsigned char recv_sign_const[16];
- unsigned char recv_seal_const[16];
- unsigned char send_sign_hash[258];
- unsigned char send_seal_hash[258];
- unsigned char recv_sign_hash[258];
- unsigned char recv_seal_hash[258];
+ unsigned char send_sign_key[16];
+ unsigned char send_seal_key[16];
+ unsigned char recv_sign_key[16];
+ unsigned char recv_seal_key[16];
+
+ unsigned char send_seal_arc4_state[258];
+ unsigned char recv_seal_arc4_state[258];
+
+ uint32 ntlm2_send_seq_num;
+ uint32 ntlm2_recv_seq_num;
/* ntlmv1 */
- unsigned char ntlmssp_hash[258];
+ unsigned char ntlmv1_arc4_state[258];
+ uint32 ntlmv1_seq_num;
/* it turns out that we don't always get the
response in at the time we want to process it.
@@ -166,4 +168,3 @@ typedef struct ntlmssp_state
DATA_BLOB stored_response;
} NTLMSSP_STATE;
-
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 114585346e..e985ab582d 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -233,6 +233,7 @@ struct acct_info
};
struct samr_displayentry {
+ uint32 idx;
uint32 rid;
uint16 acct_flags;
const char *account_name;
@@ -268,7 +269,7 @@ struct pdb_search {
* this SAMBA will load. Increment this if *ANY* changes are made to the interface.
*/
-#define PASSDB_INTERFACE_VERSION 8
+#define PASSDB_INTERFACE_VERSION 9
typedef struct pdb_context
{
@@ -373,6 +374,14 @@ typedef struct pdb_context
const char ***names,
uint32 **attrs);
+ NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
+ int policy_index, uint32 *value);
+
+ NTSTATUS (*pdb_set_account_policy)(struct pdb_context *context,
+ int policy_index, uint32 value);
+
+ NTSTATUS (*pdb_get_seq_num)(struct pdb_context *context, time_t *seq_num);
+
BOOL (*pdb_search_users)(struct pdb_context *context,
struct pdb_search *search,
uint16 acct_flags);
@@ -478,6 +487,7 @@ typedef struct pdb_methods
int num_members,
uint32 **alias_rids,
int *num_alias_rids);
+
NTSTATUS (*lookup_rids)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
@@ -486,6 +496,14 @@ typedef struct pdb_methods
const char ***names,
uint32 **attrs);
+ NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
+ int policy_index, uint32 *value);
+
+ NTSTATUS (*set_account_policy)(struct pdb_methods *methods,
+ int policy_index, uint32 value);
+
+ NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num);
+
BOOL (*search_users)(struct pdb_methods *methods,
struct pdb_search *search,
uint16 acct_flags);
diff --git a/source3/include/printing.h b/source3/include/printing.h
index 220fd08ef1..54f32d5954 100644
--- a/source3/include/printing.h
+++ b/source3/include/printing.h
@@ -57,7 +57,7 @@ struct printif
print_status_struct *status);
int (*queue_pause)(int snum);
int (*queue_resume)(int snum);
- int (*job_delete)(int snum, struct printjob *pjob);
+ int (*job_delete)(const char *sharename, const char *lprm_command, struct printjob *pjob);
int (*job_pause)(int snum, struct printjob *pjob);
int (*job_resume)(int snum, struct printjob *pjob);
int (*job_submit)(int snum, struct printjob *pjob);
diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h
index 9ca2d5aa8c..8a83c0f8ae 100644
--- a/source3/include/rpc_client.h
+++ b/source3/include/rpc_client.h
@@ -22,36 +22,68 @@
#define _RPC_CLIENT_H
/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */
-
-#define CLI_DO_RPC( pcli, ctx, pipe_num, opnum, q_in, r_out, \
+
+#define CLI_DO_RPC( pcli, ctx, p_idx, opnum, q_in, r_out, \
q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \
-{ r_out.status = default_error;\
- prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
- prs_init( &r_ps, 0, ctx, UNMARSHALL );\
+{\
+ SMB_ASSERT(pcli->pipe_idx == p_idx); \
+ if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
+ return NT_STATUS_NO_MEMORY;\
+ }\
+ if (!prs_init( &r_ps, 0, ctx, UNMARSHALL )) {\
+ prs_mem_free( &q_ps );\
+ return NT_STATUS_NO_MEMORY;\
+ }\
if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
- if ( rpc_api_pipe_req(pcli, pipe_num, opnum, &q_ps, &r_ps) ) {\
- if (!r_io_fn("", &r_out, &r_ps, 0)) {\
- r_out.status = default_error;\
- }\
+ NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \
+ if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return _smb_pipe_stat_;\
+ }\
+ if (!r_io_fn("", &r_out, &r_ps, 0)) {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return default_error;\
}\
+ } else {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return default_error;\
}\
prs_mem_free( &q_ps );\
prs_mem_free( &r_ps );\
}
-/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req_int() */
+/* Arrrgg. Same but with WERRORS. Needed for registry code. */
-#define CLI_DO_RPC_EX( pcli, ctx, pipe_num, opnum, q_in, r_out, \
+#define CLI_DO_RPC_WERR( pcli, ctx, p_idx, opnum, q_in, r_out, \
q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \
-{ r_out.status = default_error;\
- prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
- prs_init( &r_ps, 0, ctx, UNMARSHALL );\
+{\
+ SMB_ASSERT(pcli->pipe_idx == p_idx); \
+ if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
+ return WERR_NOMEM;\
+ }\
+ if (!prs_init( &r_ps, 0, ctx, UNMARSHALL )) {\
+ prs_mem_free( &q_ps );\
+ return WERR_NOMEM;\
+ }\
if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
- if ( rpc_api_pipe_req_int(pcli, opnum, &q_ps, &r_ps) ) {\
- if (!r_io_fn("", &r_out, &r_ps, 0)) {\
- r_out.status = default_error;\
- }\
+ NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \
+ if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return ntstatus_to_werror(_smb_pipe_stat_);\
+ }\
+ if (!r_io_fn("", &r_out, &r_ps, 0)) {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return default_error;\
}\
+ } else {\
+ prs_mem_free( &q_ps );\
+ prs_mem_free( &r_ps );\
+ return default_error;\
}\
prs_mem_free( &q_ps );\
prs_mem_free( &r_ps );\
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 88b8380870..3de4d2b691 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -23,9 +23,6 @@
#ifndef _DCE_RPC_H /* _DCE_RPC_H */
#define _DCE_RPC_H
-#include "rpc_misc.h" /* this only pulls in STRHDR */
-
-
/* DCE/RPC packet types */
enum RPC_PKT_TYPE {
@@ -37,7 +34,7 @@ enum RPC_PKT_TYPE {
RPC_BINDNACK = 0x0D,
RPC_ALTCONT = 0x0E,
RPC_ALTCONTRESP = 0x0F,
- RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
+ RPC_AUTH3 = 0x10 /* not the real name! this is undocumented! */
};
/* DCE/RPC flags */
@@ -45,29 +42,41 @@ enum RPC_PKT_TYPE {
#define RPC_FLG_LAST 0x02
#define RPC_FLG_NOCALL 0x20
+
#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1 /* ALWAYS_SIGN|NEG_NTLM|NEG_LM|NEG_SEAL|NEG_SIGN|NEG_UNICODE */
/* NTLMSSP signature version */
#define NTLMSSP_SIGN_VERSION 0x01
-/* NTLMSSP auth type */
-#define NTLMSSP_AUTH_TYPE 0xa
+/* DCE RPC auth types - extended by Microsoft. */
+#define RPC_ANONYMOUS_AUTH_TYPE 0
+#define RPC_AUTH_TYPE_KRB5_1 1
+#define RPC_SPNEGO_AUTH_TYPE 9
+#define RPC_NTLMSSP_AUTH_TYPE 10
+#define RPC_KRB5_AUTH_TYPE 16 /* Not yet implemented. */
+#define RPC_SCHANNEL_AUTH_TYPE 68 /* 0x44 */
/* DCE-RPC standard identifiers to indicate
signing or sealing of an RPC pipe */
+#define RPC_AUTH_LEVEL_NONE 1
+#define RPC_AUTH_LEVEL_CONNECT 2
+#define RPC_AUTH_LEVEL_CALL 3
+#define RPC_AUTH_LEVEL_PACKET 4
+#define RPC_AUTH_LEVEL_INTEGRITY 5
+#define RPC_AUTH_LEVEL_PRIVACY 6
+
+#if 0
#define RPC_PIPE_AUTH_SIGN_LEVEL 0x5
#define RPC_PIPE_AUTH_SEAL_LEVEL 0x6
+#endif
/* Netlogon schannel auth type and level */
-#define NETSEC_AUTH_TYPE 0x44
-#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
-#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
+#define SCHANNEL_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
+#define SCHANNEL_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
-#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20
-#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18
+#define RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN 0x20
+#define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN 0x18
-/* SPNEGO auth type. */
-#define SPNEGO_AUTH_TYPE 0x9
/* The 7 here seems to be required to get Win2k not to downgrade us
to NT4. Actually, anything other than 1ff would seem to do... */
@@ -76,20 +85,17 @@ enum RPC_PKT_TYPE {
#define NETLOGON_NEG_SCHANNEL 0x40000000
#define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000
-enum netsec_direction {
+enum schannel_direction {
SENDER_IS_INITIATOR,
SENDER_IS_ACCEPTOR
};
-/* Internal Flags to indicate what type of authentication on the pipe */
-#define AUTH_PIPE_SIGN 0x0001
-#define AUTH_PIPE_SEAL 0x0002
-#define AUTH_PIPE_NTLMSSP 0x0004
-#define AUTH_PIPE_NETSEC 0x0008
+/* Maximum size of the signing data in a fragment. */
+#define RPC_MAX_SIGN_SIZE 0x20 /* 32 */
/* Maximum PDU fragment size. */
/* #define MAX_PDU_FRAG_LEN 0x1630 this is what wnt sets */
-#define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
+#define RPC_MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
/* RPC_IFACE */
typedef struct rpc_iface_info {
@@ -163,7 +169,7 @@ typedef struct rpc_addr_info {
fstring str; /* the string above in single byte, null terminated form */
} RPC_ADDR_STR;
-/* RPC_HDR_BBA */
+/* RPC_HDR_BBA - bind acknowledge, and alter context response. */
typedef struct rpc_hdr_bba_info {
uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
uint16 max_rsize; /* max receive fragment size (0x1630) */
@@ -183,39 +189,24 @@ typedef struct rpc_hdr_auth_info {
#define RPC_HDR_AUTH_LEN 8
-/* RPC_HDR_AUTHA */
-typedef struct rpc_hdr_autha_info {
- uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
- uint16 max_rsize; /* max receive fragment size (0x1630) */
- RPC_HDR_AUTH auth;
-} RPC_HDR_AUTHA;
-
-#define RPC_HDR_AUTHA_LEN (RPC_HDR_AUTH_LEN+4)
-
/* this is TEMPORARILY coded up as a specific structure */
/* this structure comes after the bind request */
-/* RPC_AUTH_NETSEC_NEG */
-typedef struct rpc_auth_netsec_neg_info {
+/* RPC_AUTH_SCHANNEL_NEG */
+typedef struct rpc_auth_schannel_neg_info {
uint32 type1; /* Always zero ? */
uint32 type2; /* Types 0x3 and 0x13 seen. Check AcquireSecurityContext() docs.... */
fstring domain; /* calling workstations's domain */
fstring myname; /* calling workstation's name */
-} RPC_AUTH_NETSEC_NEG;
+} RPC_AUTH_SCHANNEL_NEG;
/* attached to the end of encrypted rpc requests and responses */
-/* RPC_AUTH_NETSEC_CHK */
-typedef struct rpc_auth_netsec_chk_info {
+/* RPC_AUTH_SCHANNEL_CHK */
+typedef struct rpc_auth_schannel_chk_info {
uint8 sig [8]; /* 77 00 7a 00 ff ff 00 00 */
uint8 packet_digest[8]; /* checksum over the packet, MD5'ed with session key */
uint8 seq_num[8]; /* verifier, seq num */
uint8 confounder[8]; /* random 8-byte nonce */
-} RPC_AUTH_NETSEC_CHK;
-
-struct netsec_auth_struct {
- uchar sess_key[16];
- uint32 seq_num;
- int auth_flags;
-};
+} RPC_AUTH_SCHANNEL_CHK;
typedef struct rpc_context {
uint16 context_id; /* presentation context identifier. */
@@ -268,60 +259,4 @@ typedef struct rpc_auth_verif_info {
uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) and 5 for schannel */
} RPC_AUTH_VERIFIER;
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind request */
-/* RPC_AUTH_NTLMSSP_NEG */
-
-typedef struct rpc_auth_ntlmssp_neg_info {
- uint32 neg_flgs; /* 0x0000 b2b3 */
-
- STRHDR hdr_myname; /* offset is against START of this structure */
- STRHDR hdr_domain; /* offset is against START of this structure */
-
- fstring myname; /* calling workstation's name */
- fstring domain; /* calling workstations's domain */
-} RPC_AUTH_NTLMSSP_NEG;
-
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind acknowledgement */
-/* RPC_AUTH_NTLMSSP_CHAL */
-typedef struct rpc_auth_ntlmssp_chal_info {
- uint32 unknown_1; /* 0x0000 0000 */
- uint32 unknown_2; /* 0x0000 0028 */
- uint32 neg_flags; /* 0x0000 82b1 */
-
- uint8 challenge[8]; /* ntlm challenge */
- uint8 reserved [8]; /* zeros */
-} RPC_AUTH_NTLMSSP_CHAL;
-
-
-/* RPC_AUTH_NTLMSSP_RESP */
-typedef struct rpc_auth_ntlmssp_resp_info {
- STRHDR hdr_lm_resp; /* 24 byte response */
- STRHDR hdr_nt_resp; /* 24 byte response */
- STRHDR hdr_domain;
- STRHDR hdr_usr;
- STRHDR hdr_wks;
- STRHDR hdr_sess_key; /* NULL unless negotiated */
- uint32 neg_flags; /* 0x0000 82b1 */
-
- fstring sess_key;
- fstring wks;
- fstring user;
- fstring domain;
- fstring nt_resp;
- fstring lm_resp;
-} RPC_AUTH_NTLMSSP_RESP;
-
-/* attached to the end of encrypted rpc requests and responses */
-/* RPC_AUTH_NTLMSSP_CHK */
-typedef struct rpc_auth_ntlmssp_chk_info {
- uint32 ver; /* 0x0000 0001 */
- uint32 reserved;
- uint32 crc32; /* checksum using 0xEDB8 8320 as a polynomial */
- uint32 seq_num;
-} RPC_AUTH_NTLMSSP_CHK;
-
-#define RPC_AUTH_NTLMSSP_CHK_LEN 16
-
#endif /* _DCE_RPC_H */
diff --git a/source3/include/rpc_dfs.h b/source3/include/rpc_dfs.h
index 39316a5d54..7aee208c14 100644
--- a/source3/include/rpc_dfs.h
+++ b/source3/include/rpc_dfs.h
@@ -34,164 +34,131 @@
#define DFSFLAG_ADD_VOLUME 0x00000001
#define DFSFLAG_RESTORE_VOLUME 0x00000002
-typedef struct dfs_q_dfs_exist
-{
- uint32 dummy;
-}
-DFS_Q_DFS_EXIST;
+typedef struct dfs_q_dfs_exist {
+ uint32 dummy;
+} DFS_Q_DFS_EXIST;
/* status == 1 if dfs exists. */
-typedef struct dfs_r_dfs_exist
-{
+typedef struct dfs_r_dfs_exist {
uint32 status; /* Not a WERROR or NTSTATUS code */
-}
-DFS_R_DFS_EXIST;
-
-typedef struct dfs_q_dfs_add
-{
- uint32 ptr_DfsEntryPath;
- UNISTR2 DfsEntryPath;
- uint32 ptr_ServerName;
- UNISTR2 ServerName;
- uint32 ptr_ShareName;
- UNISTR2 ShareName;
- uint32 ptr_Comment;
- UNISTR2 Comment;
- uint32 Flags;
-}
-DFS_Q_DFS_ADD;
-
-typedef struct dfs_r_dfs_add
-{
- WERROR status;
-}
-DFS_R_DFS_ADD;
+} DFS_R_DFS_EXIST;
+
+typedef struct dfs_q_dfs_add {
+ uint32 ptr_DfsEntryPath;
+ UNISTR2 DfsEntryPath;
+ uint32 ptr_ServerName;
+ UNISTR2 ServerName;
+ uint32 ptr_ShareName;
+ UNISTR2 ShareName;
+ uint32 ptr_Comment;
+ UNISTR2 Comment;
+ uint32 Flags;
+} DFS_Q_DFS_ADD;
+
+typedef struct dfs_r_dfs_add {
+ WERROR status;
+} DFS_R_DFS_ADD;
/********************************************/
-typedef struct dfs_q_dfs_remove
-{
- UNISTR2 DfsEntryPath;
- uint32 ptr_ServerName;
- UNISTR2 ServerName;
- uint32 ptr_ShareName;
- UNISTR2 ShareName;
-}
-DFS_Q_DFS_REMOVE;
-
-typedef struct dfs_r_dfs_remove
-{
- WERROR status;
-}
-DFS_R_DFS_REMOVE;
+typedef struct dfs_q_dfs_remove {
+ UNISTR2 DfsEntryPath;
+ uint32 ptr_ServerName;
+ UNISTR2 ServerName;
+ uint32 ptr_ShareName;
+ UNISTR2 ShareName;
+} DFS_Q_DFS_REMOVE;
+
+typedef struct dfs_r_dfs_remove {
+ WERROR status;
+} DFS_R_DFS_REMOVE;
/********************************************/
-typedef struct dfs_info_1
-{
- uint32 ptr_entrypath;
- UNISTR2 entrypath;
-}
-DFS_INFO_1;
-
-typedef struct dfs_info_2
-{
- uint32 ptr_entrypath;
- UNISTR2 entrypath;
- uint32 ptr_comment;
- UNISTR2 comment;
- uint32 state;
- uint32 num_storages;
-}
-DFS_INFO_2;
-
-typedef struct dfs_storage_info
-{
- uint32 state;
- uint32 ptr_servername;
- UNISTR2 servername;
- uint32 ptr_sharename;
- UNISTR2 sharename;
-}
-DFS_STORAGE_INFO;
-
-typedef struct dfs_info_3
-{
- uint32 ptr_entrypath;
- UNISTR2 entrypath;
- uint32 ptr_comment;
- UNISTR2 comment;
- uint32 state;
- uint32 num_storages;
- uint32 ptr_storages;
- uint32 num_storage_infos;
- DFS_STORAGE_INFO* storages;
-}
-DFS_INFO_3;
-
-typedef struct dfs_info_ctr
-{
+typedef struct dfs_info_1 {
+ uint32 ptr_entrypath;
+ UNISTR2 entrypath;
+} DFS_INFO_1;
+
+typedef struct dfs_info_2 {
+ uint32 ptr_entrypath;
+ UNISTR2 entrypath;
+ uint32 ptr_comment;
+ UNISTR2 comment;
+ uint32 state;
+ uint32 num_storages;
+} DFS_INFO_2;
+
+typedef struct dfs_storage_info {
+ uint32 state;
+ uint32 ptr_servername;
+ UNISTR2 servername;
+ uint32 ptr_sharename;
+ UNISTR2 sharename;
+} DFS_STORAGE_INFO;
+
+typedef struct dfs_info_3 {
+ uint32 ptr_entrypath;
+ UNISTR2 entrypath;
+ uint32 ptr_comment;
+ UNISTR2 comment;
+ uint32 state;
+ uint32 num_storages;
+ uint32 ptr_storages;
+ uint32 num_storage_infos;
+ DFS_STORAGE_INFO* storages;
+} DFS_INFO_3;
+
+typedef struct dfs_info_ctr {
+ uint32 switch_value;
+ uint32 num_entries;
+ uint32 ptr_dfs_ctr; /* pointer to dfs info union */
+ union {
+ DFS_INFO_1 *info1;
+ DFS_INFO_2 *info2;
+ DFS_INFO_3 *info3;
+ } dfs;
+} DFS_INFO_CTR;
+
+typedef struct dfs_q_dfs_get_info {
+ UNISTR2 uni_path;
- uint32 switch_value;
- uint32 num_entries;
- uint32 ptr_dfs_ctr; /* pointer to dfs info union */
- union
- {
- DFS_INFO_1 *info1;
- DFS_INFO_2 *info2;
- DFS_INFO_3 *info3;
- } dfs;
-}
-DFS_INFO_CTR;
-
-typedef struct dfs_q_dfs_get_info
-{
- UNISTR2 uni_path;
-
- uint32 ptr_server;
- UNISTR2 uni_server;
+ uint32 ptr_server;
+ UNISTR2 uni_server;
- uint32 ptr_share;
- UNISTR2 uni_share;
+ uint32 ptr_share;
+ UNISTR2 uni_share;
- uint32 level;
-}
-DFS_Q_DFS_GET_INFO;
-
-typedef struct dfs_r_dfs_get_info
-{
- uint32 level;
- uint32 ptr_ctr;
- DFS_INFO_CTR ctr;
- WERROR status;
-}
-DFS_R_DFS_GET_INFO;
-
-typedef struct dfs_q_dfs_enum
-{
- uint32 level;
- uint32 maxpreflen;
- uint32 ptr_buffer;
- uint32 level2;
- uint32 ptr_num_entries;
- uint32 num_entries;
- uint32 ptr_num_entries2;
- uint32 num_entries2;
- ENUM_HND reshnd;
-}
-DFS_Q_DFS_ENUM;
-
-typedef struct dfs_r_dfs_enum
-{
- DFS_INFO_CTR *ctr;
- uint32 ptr_buffer;
- uint32 level;
- uint32 level2;
- uint32 ptr_num_entries;
- uint32 num_entries;
- uint32 ptr_num_entries2;
- uint32 num_entries2;
- ENUM_HND reshnd;
- WERROR status;
-}
-DFS_R_DFS_ENUM;
-
+ uint32 level;
+} DFS_Q_DFS_GET_INFO;
+
+typedef struct dfs_r_dfs_get_info {
+ uint32 level;
+ uint32 ptr_ctr;
+ DFS_INFO_CTR ctr;
+ WERROR status;
+} DFS_R_DFS_GET_INFO;
+
+typedef struct dfs_q_dfs_enum {
+ uint32 level;
+ uint32 maxpreflen;
+ uint32 ptr_buffer;
+ uint32 level2;
+ uint32 ptr_num_entries;
+ uint32 num_entries;
+ uint32 ptr_num_entries2;
+ uint32 num_entries2;
+ ENUM_HND reshnd;
+} DFS_Q_DFS_ENUM;
+
+typedef struct dfs_r_dfs_enum {
+ DFS_INFO_CTR *ctr;
+ uint32 ptr_buffer;
+ uint32 level;
+ uint32 level2;
+ uint32 ptr_num_entries;
+ uint32 num_entries;
+ uint32 ptr_num_entries2;
+ uint32 num_entries2;
+ ENUM_HND reshnd;
+ WERROR status;
+} DFS_R_DFS_ENUM;
#endif
diff --git a/source3/include/rpc_ds.h b/source3/include/rpc_ds.h
index e06918730a..24bf1e948a 100644
--- a/source3/include/rpc_ds.h
+++ b/source3/include/rpc_ds.h
@@ -21,9 +21,6 @@
#ifndef _RPC_DS_H /* _RPC_LSA_H */
#define _RPC_DS_H
-#include "rpc_misc.h"
-
-
/* Opcodes available on PIPE_LSARPC_DS */
#define DS_GETPRIMDOMINFO 0x00
diff --git a/source3/include/rpc_eventlog.h b/source3/include/rpc_eventlog.h
index b692a76225..7ce1199b21 100644
--- a/source3/include/rpc_eventlog.h
+++ b/source3/include/rpc_eventlog.h
@@ -47,77 +47,74 @@
#define EVENTLOG_AUDIT_FAILURE 0x0010
-typedef struct eventlog_q_open_eventlog
-{
- uint32 unknown1;
+/***********************************/
+
+typedef struct {
+ uint16 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
-{
+} EVENTLOG_OPEN_UNKNOWN0;
+
+typedef struct {
+ EVENTLOG_OPEN_UNKNOWN0 *unknown0;
+ UNISTR4 logname;
+ UNISTR4 servername;
+ uint32 unknown1;
+ uint32 unknown2;
+} EVENTLOG_Q_OPEN_EVENTLOG;
+
+typedef struct {
POLICY_HND handle;
WERROR status;
-}
-EVENTLOG_R_OPEN_EVENTLOG;
+} EVENTLOG_R_OPEN_EVENTLOG;
-typedef struct eventlog_q_close_eventlog
-{
+
+/***********************************/
+
+typedef struct {
POLICY_HND handle;
-}
-EVENTLOG_Q_CLOSE_EVENTLOG;
+} EVENTLOG_Q_CLOSE_EVENTLOG;
-typedef struct eventlog_r_close_eventlog
-{
+typedef struct {
POLICY_HND handle;
WERROR status;
-}
-EVENTLOG_R_CLOSE_EVENTLOG;
+} EVENTLOG_R_CLOSE_EVENTLOG;
-typedef struct eventlog_q_get_num_records
-{
+
+/***********************************/
+
+typedef struct {
POLICY_HND handle;
-}
-EVENTLOG_Q_GET_NUM_RECORDS;
+} EVENTLOG_Q_GET_NUM_RECORDS;
-typedef struct eventlog_r_get_num_records
-{
+typedef struct {
uint32 num_records;
WERROR status;
-}
-EVENTLOG_R_GET_NUM_RECORDS;
+} EVENTLOG_R_GET_NUM_RECORDS;
-typedef struct eventlog_q_get_oldest_entry
-{
+
+/***********************************/
+
+typedef struct {
POLICY_HND handle;
-}
-EVENTLOG_Q_GET_OLDEST_ENTRY;
+} EVENTLOG_Q_GET_OLDEST_ENTRY;
-typedef struct eventlog_r_get_oldest_entry
-{
+typedef struct {
uint32 oldest_entry;
WERROR status;
-}
-EVENTLOG_R_GET_OLDEST_ENTRY;
+} EVENTLOG_R_GET_OLDEST_ENTRY;
+
-typedef struct eventlog_q_read_eventlog
+/***********************************/
+
+typedef struct
{
POLICY_HND handle;
uint32 flags;
uint32 offset;
uint32 max_read_size;
-}
-EVENTLOG_Q_READ_EVENTLOG;
+} EVENTLOG_Q_READ_EVENTLOG;
-typedef struct eventlog_record
-{
+typedef struct {
uint32 length;
uint32 reserved1;
uint32 record_number;
@@ -136,8 +133,7 @@ typedef struct eventlog_record
uint32 data_offset;
} Eventlog_record;
-typedef struct eventlog_data_record
-{
+typedef struct {
uint32 source_name_len;
wpstring source_name;
uint32 computer_name_len;
@@ -151,8 +147,7 @@ typedef struct eventlog_data_record
uint32 data_padding;
} Eventlog_data_record;
-typedef struct eventlog_entry
-{
+typedef struct eventlog_entry {
Eventlog_record record;
Eventlog_data_record data_record;
uint8 *data;
@@ -160,8 +155,7 @@ typedef struct eventlog_entry
struct eventlog_entry *next;
} Eventlog_entry;
-typedef struct eventlog_r_read_eventlog
-{
+typedef struct {
uint32 num_bytes_in_resp;
uint32 bytes_in_next_record;
uint32 num_records;
@@ -170,24 +164,18 @@ typedef struct eventlog_r_read_eventlog
uint32 sent_size;
uint32 real_size;
WERROR status;
-}
-EVENTLOG_R_READ_EVENTLOG;
+} EVENTLOG_R_READ_EVENTLOG;
-typedef struct eventlog_q_clear_eventlog
-{
+
+/***********************************/
+
+typedef struct {
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
-{
+ UNISTR4 backupfile;
+} EVENTLOG_Q_CLEAR_EVENTLOG;
+
+typedef struct {
WERROR status;
-}
-EVENTLOG_R_CLEAR_EVENTLOG;
+} EVENTLOG_R_CLEAR_EVENTLOG;
#endif /* _RPC_EVENTLOG_H */
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
index 053a23b218..dd255c28d5 100644
--- a/source3/include/rpc_lsa.h
+++ b/source3/include/rpc_lsa.h
@@ -24,8 +24,6 @@
#ifndef _RPC_LSA_H /* _RPC_LSA_H */
#define _RPC_LSA_H
-#include "rpc_misc.h"
-
/* Opcodes available on PIPE_LSARPC */
#if 0 /* UNIMPLEMENTED */
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
index 9f35450d95..e5d91c1b63 100644
--- a/source3/include/rpc_misc.h
+++ b/source3/include/rpc_misc.h
@@ -21,9 +21,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "ntdomain.h"
-#include "rpc_dce.h"
-
#ifndef _RPC_MISC_H /* _RPC_MISC_H */
#define _RPC_MISC_H
@@ -302,8 +299,7 @@ typedef struct {
**********************************************************************/
/* DOM_CLNT_SRV - client / server names */
-typedef struct clnt_srv_info
-{
+typedef struct clnt_srv_info {
uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
UNISTR2 uni_logon_srv; /* logon server name */
uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
@@ -311,8 +307,7 @@ typedef struct clnt_srv_info
} DOM_CLNT_SRV;
/* DOM_LOG_INFO - login info */
-typedef struct log_info
-{
+typedef struct log_info {
uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
UNISTR2 uni_logon_srv; /* logon server name */
UNISTR2 uni_acct_name; /* account name */
@@ -321,89 +316,44 @@ typedef struct log_info
} DOM_LOG_INFO;
/* DOM_CHAL - challenge info */
-typedef struct chal_info
-{
+typedef struct chal_info {
uchar data[8]; /* credentials */
} DOM_CHAL;
/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info
-{
+typedef struct cred_info {
DOM_CHAL challenge; /* credentials */
UTIME timestamp; /* credential time-stamp */
} DOM_CRED;
/* DOM_CLNT_INFO - client info */
-typedef struct clnt_info
-{
+typedef struct clnt_info {
DOM_LOG_INFO login;
DOM_CRED cred;
} DOM_CLNT_INFO;
/* DOM_CLNT_INFO2 - client info */
-typedef struct clnt_info2
-{
+typedef struct clnt_info2 {
DOM_CLNT_SRV login;
uint32 ptr_cred;
DOM_CRED cred;
} DOM_CLNT_INFO2;
/* DOM_LOGON_ID - logon id */
-typedef struct logon_info
-{
+typedef struct logon_info {
uint32 low;
uint32 high;
} DOM_LOGON_ID;
/* OWF INFO */
-typedef struct owf_info
-{
+typedef struct owf_info {
uint8 data[16];
} OWF_INFO;
-
-
-
-
-/*
- * A client connection's state, pipe name,
- * user credentials, etc...
- */
-typedef struct _cli_auth_fns cli_auth_fns;
-struct user_creds;
-struct cli_connection {
-
- char *srv_name;
- char *pipe_name;
- struct user_creds usr_creds;
-
- struct cli_state *pCli_state;
-
- cli_auth_fns *auth;
-
- void *auth_info;
- void *auth_creds;
-};
-
-
-/*
- * Associate a POLICY_HND with a cli_connection
- */
-typedef struct rpc_hnd_node {
-
- POLICY_HND hnd;
- struct cli_connection *cli;
-
-} RPC_HND_NODE;
-
typedef struct uint64_s
{
uint32 low;
uint32 high;
} UINT64_S;
-
-
-
-
#endif /* _RPC_MISC_H */
diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h
index b3fe16ba2b..b004e26397 100644
--- a/source3/include/rpc_netlogon.h
+++ b/source3/include/rpc_netlogon.h
@@ -84,11 +84,22 @@
#define NL_CTRL_REPL_IN_PROGRESS 0x0002
#define NL_CTRL_FULL_SYNC 0x0004
+#define LOGON_EXTRA_SIDS 0x0020
+#define LOGON_RESOURCE_GROUPS 0x0200
+
+#define SE_GROUP_MANDATORY 0x00000001
+#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002
+#define SE_GROUP_ENABLED 0x00000004
+#define SE_GROUP_OWNER 0x00000008
+#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010
+#define SE_GROUP_LOGON_ID 0xC0000000
+#define SE_GROUP_RESOURCE 0x20000000
+
+
#if 0
/* I think this is correct - it's what gets parsed on the wire. JRA. */
/* NET_USER_INFO_2 */
-typedef struct net_user_info_2
-{
+typedef struct net_user_info_2 {
uint32 ptr_user_info;
NTTIME logon_time; /* logon time */
@@ -145,8 +156,7 @@ typedef struct net_user_info_2
#endif
/* NET_USER_INFO_3 */
-typedef struct net_user_info_3
-{
+typedef struct net_user_info_3 {
uint32 ptr_user_info;
NTTIME logon_time; /* logon time */
@@ -186,6 +196,13 @@ typedef struct net_user_info_3
uint32 num_other_sids; /* number of foreign/trusted domain sids */
uint32 buffer_other_sids;
+ /* The next three uint32 are not really part of user_info_3 but here
+ * for parsing convenience. They are only valid in Kerberos PAC
+ * parsing - Guenther */
+ uint32 ptr_res_group_dom_sid;
+ uint32 res_group_count;
+ uint32 ptr_res_groups;
+
UNISTR2 uni_user_name; /* username unicode string */
UNISTR2 uni_full_name; /* user's full name unicode string */
UNISTR2 uni_logon_script; /* logon script unicode string */
@@ -203,32 +220,26 @@ typedef struct net_user_info_3
DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */
uint32 *other_sids_attrib;
-
} NET_USER_INFO_3;
/* NETLOGON_INFO_1 - pdc status info, i presume */
-typedef struct netlogon_1_info
-{
+typedef struct netlogon_1_info {
uint32 flags; /* 0x0 - undocumented */
uint32 pdc_status; /* 0x0 - undocumented */
-
} NETLOGON_INFO_1;
/* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */
-typedef struct netlogon_2_info
-{
+typedef struct netlogon_2_info {
uint32 flags; /* 0x0 - undocumented */
uint32 pdc_status; /* 0x0 - undocumented */
uint32 ptr_trusted_dc_name; /* pointer to trusted domain controller name */
uint32 tc_status;
UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */
-
} NETLOGON_INFO_2;
/* NETLOGON_INFO_3 - logon status info, i presume */
-typedef struct netlogon_3_info
-{
+typedef struct netlogon_3_info {
uint32 flags; /* 0x0 - undocumented */
uint32 logon_attempts; /* number of logon attempts */
uint32 reserved_1; /* 0x0 - undocumented */
@@ -236,7 +247,6 @@ typedef struct netlogon_3_info
uint32 reserved_3; /* 0x0 - undocumented */
uint32 reserved_4; /* 0x0 - undocumented */
uint32 reserved_5; /* 0x0 - undocumented */
-
} NETLOGON_INFO_3;
/********************************************************
@@ -250,8 +260,7 @@ typedef struct netlogon_3_info
/* NET_Q_LOGON_CTRL - LSA Netr Logon Control */
-typedef struct net_q_logon_ctrl_info
-{
+typedef struct net_q_logon_ctrl_info {
uint32 ptr;
UNISTR2 uni_server_name;
uint32 function_code;
@@ -260,8 +269,7 @@ typedef struct net_q_logon_ctrl_info
/* NET_R_LOGON_CTRL - LSA Netr Logon Control */
-typedef struct net_r_logon_ctrl_info
-{
+typedef struct net_r_logon_ctrl_info {
uint32 switch_value;
uint32 ptr;
@@ -273,22 +281,18 @@ typedef struct net_r_logon_ctrl_info
} NET_R_LOGON_CTRL;
-typedef struct ctrl_data_info_5
-{
+typedef struct ctrl_data_info_5 {
uint32 function_code;
uint32 ptr_domain;
UNISTR2 domain;
-
} CTRL_DATA_INFO_5;
-typedef struct ctrl_data_info_6
-{
+typedef struct ctrl_data_info_6 {
uint32 function_code;
uint32 ptr_domain;
UNISTR2 domain;
-
} CTRL_DATA_INFO_6;
@@ -301,8 +305,7 @@ typedef struct ctrl_data_info_6
********************************************************/
/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */
-typedef struct net_q_logon_ctrl2_info
-{
+typedef struct net_q_logon_ctrl2_info {
uint32 ptr; /* undocumented buffer pointer */
UNISTR2 uni_server_name; /* server name, starting with two '\'s */
@@ -312,7 +315,6 @@ typedef struct net_q_logon_ctrl2_info
CTRL_DATA_INFO_5 info5;
CTRL_DATA_INFO_6 info6;
} info;
-
} NET_Q_LOGON_CTRL2;
/*******************************************************
@@ -322,8 +324,7 @@ typedef struct net_q_logon_ctrl2_info
*******************************************************/
/* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */
-typedef struct net_r_logon_ctrl2_info
-{
+typedef struct net_r_logon_ctrl2_info {
uint32 switch_value; /* 0x1, 0x3 */
uint32 ptr;
@@ -336,13 +337,11 @@ typedef struct net_r_logon_ctrl2_info
} logon;
NTSTATUS status; /* return code */
-
} NET_R_LOGON_CTRL2;
/* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */
-typedef struct net_q_getdcname
-{
+typedef struct net_q_getdcname {
uint32 ptr_logon_server;
UNISTR2 uni_logon_server;
uint32 ptr_domainname;
@@ -351,103 +350,86 @@ typedef struct net_q_getdcname
/* NET_R_GETDCNAME - Ask a DC for a trusted DC name */
-typedef struct net_r_getdcname
-{
+typedef struct net_r_getdcname {
uint32 ptr_dcname;
UNISTR2 uni_dcname;
NTSTATUS status;
} NET_R_GETDCNAME;
/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
-typedef struct net_q_trust_dom_info
-{
+typedef struct net_q_trust_dom_info {
uint32 ptr; /* undocumented buffer pointer */
UNISTR2 uni_server_name; /* server name, starting with two '\'s */
-
} NET_Q_TRUST_DOM_LIST;
#define MAX_TRUST_DOMS 1
/* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
-typedef struct net_r_trust_dom_info
-{
+typedef struct net_r_trust_dom_info {
UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
NTSTATUS status; /* return code */
-
} NET_R_TRUST_DOM_LIST;
/* NEG_FLAGS */
-typedef struct neg_flags_info
-{
- uint32 neg_flags; /* negotiated flags */
-
+typedef struct neg_flags_info {
+ uint32 neg_flags; /* negotiated flags */
} NEG_FLAGS;
/* NET_Q_REQ_CHAL */
-typedef struct net_q_req_chal_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server unicode string */
- UNISTR2 uni_logon_clnt; /* logon client unicode string */
- DOM_CHAL clnt_chal; /* client challenge */
-
+typedef struct net_q_req_chal_info {
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server unicode string */
+ UNISTR2 uni_logon_clnt; /* logon client unicode string */
+ DOM_CHAL clnt_chal; /* client challenge */
} NET_Q_REQ_CHAL;
/* NET_R_REQ_CHAL */
-typedef struct net_r_req_chal_info
-{
+typedef struct net_r_req_chal_info {
DOM_CHAL srv_chal; /* server challenge */
NTSTATUS status; /* return code */
} NET_R_REQ_CHAL;
/* NET_Q_AUTH */
-typedef struct net_q_auth_info
-{
+typedef struct net_q_auth_info {
DOM_LOG_INFO clnt_id; /* client identification info */
DOM_CHAL clnt_chal; /* client-calculated credentials */
} NET_Q_AUTH;
/* NET_R_AUTH */
-typedef struct net_r_auth_info
-{
+typedef struct net_r_auth_info {
DOM_CHAL srv_chal; /* server-calculated credentials */
NTSTATUS status; /* return code */
} NET_R_AUTH;
/* NET_Q_AUTH_2 */
-typedef struct net_q_auth2_info
-{
- DOM_LOG_INFO clnt_id; /* client identification info */
- DOM_CHAL clnt_chal; /* client-calculated credentials */
-
- NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
+typedef struct net_q_auth2_info {
+ DOM_LOG_INFO clnt_id; /* client identification info */
+ DOM_CHAL clnt_chal; /* client-calculated credentials */
+ NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
} NET_Q_AUTH_2;
/* NET_R_AUTH_2 */
-typedef struct net_r_auth2_info
-{
+typedef struct net_r_auth2_info {
DOM_CHAL srv_chal; /* server-calculated credentials */
NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
NTSTATUS status; /* return code */
} NET_R_AUTH_2;
/* NET_Q_AUTH_3 */
-typedef struct net_q_auth3_info
-{
- DOM_LOG_INFO clnt_id; /* client identification info */
- DOM_CHAL clnt_chal; /* client-calculated credentials */
- NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */
+typedef struct net_q_auth3_info {
+ DOM_LOG_INFO clnt_id; /* client identification info */
+ DOM_CHAL clnt_chal; /* client-calculated credentials */
+ NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */
} NET_Q_AUTH_3;
/* NET_R_AUTH_3 */
-typedef struct net_r_auth3_info
-{
+typedef struct net_r_auth3_info {
DOM_CHAL srv_chal; /* server-calculated credentials */
NEG_FLAGS srv_flgs; /* usually 0x6007 ffff */
uint32 unknown; /* 0x0000045b */
@@ -456,25 +438,20 @@ typedef struct net_r_auth3_info
/* NET_Q_SRV_PWSET */
-typedef struct net_q_srv_pwset_info
-{
- DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
- uint8 pwd[16]; /* new password - undocumented. */
-
+typedef struct net_q_srv_pwset_info {
+ DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
+ uint8 pwd[16]; /* new password - undocumented. */
} NET_Q_SRV_PWSET;
/* NET_R_SRV_PWSET */
-typedef struct net_r_srv_pwset_info
-{
- DOM_CRED srv_cred; /* server-calculated credentials */
-
- NTSTATUS status; /* return code */
+typedef struct net_r_srv_pwset_info {
+ DOM_CRED srv_cred; /* server-calculated credentials */
+ NTSTATUS status; /* return code */
} NET_R_SRV_PWSET;
/* NET_ID_INFO_2 */
-typedef struct net_network_info_2
-{
+typedef struct net_network_info_2 {
uint32 ptr_id_info2; /* pointer to id_info_2 */
UNIHDR hdr_domain_name; /* domain name unicode header */
uint32 param_ctrl; /* param control (0x2) */
@@ -490,12 +467,10 @@ typedef struct net_network_info_2
UNISTR2 uni_wksta_name; /* workgroup name unicode string */
STRING2 nt_chal_resp; /* nt challenge response */
STRING2 lm_chal_resp; /* lm challenge response */
-
} NET_ID_INFO_2;
/* NET_ID_INFO_1 */
-typedef struct id_info_1
-{
+typedef struct id_info_1 {
uint32 ptr_id_info1; /* pointer to id_info_1 */
UNIHDR hdr_domain_name; /* domain name unicode header */
uint32 param_ctrl; /* param control */
@@ -507,81 +482,64 @@ typedef struct id_info_1
UNISTR2 uni_domain_name; /* domain name unicode string */
UNISTR2 uni_user_name; /* user name unicode string */
UNISTR2 uni_wksta_name; /* workgroup name unicode string */
-
} NET_ID_INFO_1;
#define INTERACTIVE_LOGON_TYPE 1
#define NET_LOGON_TYPE 2
/* NET_ID_INFO_CTR */
-typedef struct net_id_info_ctr_info
-{
- uint16 switch_value;
-
- union
- {
- NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
- NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
-
- } auth;
+typedef struct net_id_info_ctr_info {
+ uint16 switch_value;
+ union {
+ NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
+ NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
+ } auth;
} NET_ID_INFO_CTR;
/* SAM_INFO - sam logon/off id structure */
-typedef struct sam_info
-{
- DOM_CLNT_INFO2 client;
- uint32 ptr_rtn_cred; /* pointer to return credentials */
- DOM_CRED rtn_cred; /* return credentials */
- uint16 logon_level;
- NET_ID_INFO_CTR *ctr;
-
+typedef struct sam_info {
+ DOM_CLNT_INFO2 client;
+ uint32 ptr_rtn_cred; /* pointer to return credentials */
+ DOM_CRED rtn_cred; /* return credentials */
+ uint16 logon_level;
+ NET_ID_INFO_CTR *ctr;
} DOM_SAM_INFO;
/* NET_Q_SAM_LOGON */
-typedef struct net_q_sam_logon_info
-{
- DOM_SAM_INFO sam_id;
+typedef struct net_q_sam_logon_info {
+ DOM_SAM_INFO sam_id;
uint16 validation_level;
-
} NET_Q_SAM_LOGON;
/* NET_R_SAM_LOGON */
-typedef struct net_r_sam_logon_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
+typedef struct net_r_sam_logon_info {
+ uint32 buffer_creds; /* undocumented buffer pointer */
+ DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
uint16 switch_value; /* 3 - indicates type of USER INFO */
- NET_USER_INFO_3 *user;
-
- uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
+ NET_USER_INFO_3 *user;
- NTSTATUS status; /* return code */
+ uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
+ NTSTATUS status; /* return code */
} NET_R_SAM_LOGON;
/* NET_Q_SAM_LOGOFF */
-typedef struct net_q_sam_logoff_info
-{
- DOM_SAM_INFO sam_id;
-
+typedef struct net_q_sam_logoff_info {
+ DOM_SAM_INFO sam_id;
} NET_Q_SAM_LOGOFF;
/* NET_R_SAM_LOGOFF */
-typedef struct net_r_sam_logoff_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
-
- NTSTATUS status; /* return code */
-
+typedef struct net_r_sam_logoff_info {
+ uint32 buffer_creds; /* undocumented buffer pointer */
+ DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
+ NTSTATUS status; /* return code */
} NET_R_SAM_LOGOFF;
/* NET_Q_SAM_SYNC */
-typedef struct net_q_sam_sync_info
-{
+typedef struct net_q_sam_sync_info {
UNISTR2 uni_srv_name; /* \\PDC */
UNISTR2 uni_cli_name; /* BDC */
DOM_CRED cli_creds;
@@ -592,19 +550,16 @@ typedef struct net_q_sam_sync_info
uint32 sync_context;
uint32 max_size; /* preferred maximum length */
-
} NET_Q_SAM_SYNC;
/* SAM_DELTA_HDR */
-typedef struct sam_delta_hdr_info
-{
+typedef struct sam_delta_hdr_info {
uint16 type; /* type of structure attached */
uint16 type2;
uint32 target_rid;
uint32 type3;
uint32 ptr_delta;
-
} SAM_DELTA_HDR;
/* LOCKOUT_STRING */
@@ -617,7 +572,6 @@ typedef struct account_lockout_string {
UINT64_S reset_count;
uint32 bad_attempt_lockout;
uint32 dummy;
-
} LOCKOUT_STRING;
/* HDR_LOCKOUT_STRING */
@@ -625,12 +579,10 @@ typedef struct hdr_account_lockout_string {
uint16 size;
uint16 length;
uint32 buffer;
-
} HDR_LOCKOUT_STRING;
/* SAM_DOMAIN_INFO (0x1) */
-typedef struct sam_domain_info_info
-{
+typedef struct sam_domain_info_info {
UNIHDR hdr_dom_name;
UNIHDR hdr_oem_info;
@@ -666,13 +618,10 @@ typedef struct sam_domain_info_info
uint32 unknown6;
uint32 unknown7;
uint32 unknown8;
-
-
} SAM_DOMAIN_INFO;
/* SAM_GROUP_INFO (0x2) */
-typedef struct sam_group_info_info
-{
+typedef struct sam_group_info_info {
UNIHDR hdr_grp_name;
DOM_GID gid;
UNIHDR hdr_grp_desc;
@@ -682,12 +631,10 @@ typedef struct sam_group_info_info
UNISTR2 uni_grp_name;
UNISTR2 uni_grp_desc;
RPC_DATA_BLOB buf_sec_desc;
-
} SAM_GROUP_INFO;
/* SAM_PWD */
-typedef struct sam_passwd_info
-{
+typedef struct sam_passwd_info {
/* this structure probably contains password history */
/* this is probably a count of lm/nt pairs */
uint32 unk_0; /* 0x0000 0002 */
@@ -700,12 +647,10 @@ typedef struct sam_passwd_info
UNIHDR hdr_empty_lm;
UNIHDR hdr_empty_nt;
-
} SAM_PWD;
/* SAM_ACCOUNT_INFO (0x5) */
-typedef struct sam_account_info_info
-{
+typedef struct sam_account_info_info {
UNIHDR hdr_acct_name;
UNIHDR hdr_full_name;
@@ -765,12 +710,10 @@ typedef struct sam_account_info_info
SAM_PWD pass;
RPC_DATA_BLOB buf_sec_desc;
UNISTR2 uni_profile;
-
} SAM_ACCOUNT_INFO;
/* SAM_GROUP_MEM_INFO (0x8) */
-typedef struct sam_group_mem_info_info
-{
+typedef struct sam_group_mem_info_info {
uint32 ptr_rids;
uint32 ptr_attribs;
uint32 num_members;
@@ -785,8 +728,7 @@ typedef struct sam_group_mem_info_info
} SAM_GROUP_MEM_INFO;
/* SAM_ALIAS_INFO (0x9) */
-typedef struct sam_alias_info_info
-{
+typedef struct sam_alias_info_info {
UNIHDR hdr_als_name;
uint32 als_rid;
BUFHDR2 hdr_sec_desc; /* security descriptor */
@@ -796,12 +738,10 @@ typedef struct sam_alias_info_info
UNISTR2 uni_als_name;
RPC_DATA_BLOB buf_sec_desc;
UNISTR2 uni_als_desc;
-
} SAM_ALIAS_INFO;
/* SAM_ALIAS_MEM_INFO (0xC) */
-typedef struct sam_alias_mem_info_info
-{
+typedef struct sam_alias_mem_info_info {
uint32 num_members;
uint32 ptr_members;
uint8 unknown[16];
@@ -809,13 +749,11 @@ typedef struct sam_alias_mem_info_info
uint32 num_sids;
uint32 *ptr_sids;
DOM_SID2 *sids;
-
} SAM_ALIAS_MEM_INFO;
/* SAM_DELTA_POLICY (0x0D) */
-typedef struct
-{
+typedef struct {
uint32 max_log_size; /* 0x5000 */
UINT64_S audit_retention_period; /* 0 */
uint32 auditing_mode; /* 0 */
@@ -844,8 +782,7 @@ typedef struct
} SAM_DELTA_POLICY;
/* SAM_DELTA_TRUST_DOMS */
-typedef struct
-{
+typedef struct {
uint32 buf_size;
SEC_DESC *sec_desc;
DOM_SID2 sid;
@@ -860,12 +797,10 @@ typedef struct
uint32 unknown3;
UNISTR2 domain;
-
} SAM_DELTA_TRUSTDOMS;
/* SAM_DELTA_PRIVS (0x10) */
-typedef struct
-{
+typedef struct {
DOM_SID2 sid;
uint32 priv_count;
@@ -896,8 +831,7 @@ typedef struct
} SAM_DELTA_PRIVS;
/* SAM_DELTA_SECRET */
-typedef struct
-{
+typedef struct {
uint32 buf_size;
SEC_DESC *sec_desc;
UNISTR2 secret;
@@ -928,19 +862,16 @@ typedef struct
uint32 buf_size3;
SEC_DESC *sec_desc2;
-
} SAM_DELTA_SECRET;
/* SAM_DELTA_MOD_COUNT (0x16) */
-typedef struct
-{
+typedef struct {
uint32 seqnum;
uint32 dom_mod_count_ptr;
UINT64_S dom_mod_count; /* domain mod count at last sync */
} SAM_DELTA_MOD_COUNT;
-typedef union sam_delta_ctr_info
-{
+typedef union sam_delta_ctr_info {
SAM_DOMAIN_INFO domain_info ;
SAM_GROUP_INFO group_info ;
SAM_ACCOUNT_INFO account_info;
@@ -955,8 +886,7 @@ typedef union sam_delta_ctr_info
} SAM_DELTA_CTR;
/* NET_R_SAM_SYNC */
-typedef struct net_r_sam_sync_info
-{
+typedef struct net_r_sam_sync_info {
DOM_CRED srv_creds;
uint32 sync_context;
@@ -973,8 +903,7 @@ typedef struct net_r_sam_sync_info
} NET_R_SAM_SYNC;
/* NET_Q_SAM_DELTAS */
-typedef struct net_q_sam_deltas_info
-{
+typedef struct net_q_sam_deltas_info {
UNISTR2 uni_srv_name;
UNISTR2 uni_cli_name;
DOM_CRED cli_creds;
@@ -984,12 +913,10 @@ typedef struct net_q_sam_deltas_info
UINT64_S dom_mod_count; /* domain mod count at last sync */
uint32 max_size; /* preferred maximum length */
-
} NET_Q_SAM_DELTAS;
/* NET_R_SAM_DELTAS */
-typedef struct net_r_sam_deltas_info
-{
+typedef struct net_r_sam_deltas_info {
DOM_CRED srv_creds;
UINT64_S dom_mod_count; /* new domain mod count */
diff --git a/source3/include/rpc_ntsvcs.h b/source3/include/rpc_ntsvcs.h
new file mode 100644
index 0000000000..947794bba1
--- /dev/null
+++ b/source3/include/rpc_ntsvcs.h
@@ -0,0 +1,147 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB parameters and setup
+ 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_NTSVCS_H /* _RPC_NTSVCS_H */
+#define _RPC_NTSVCS_H
+
+/* ntsvcs pipe */
+
+#define NTSVCS_GET_VERSION 0x02
+#define NTSVCS_VALIDATE_DEVICE_INSTANCE 0x06
+#define NTSVCS_GET_ROOT_DEVICE_INSTANCE 0x07
+#define NTSVCS_GET_DEVICE_LIST 0x0a
+#define NTSVCS_GET_DEVICE_LIST_SIZE 0x0b
+#define NTSVCS_GET_DEVICE_REG_PROPERTY 0x0d
+#define NTSVCS_HW_PROFILE_FLAGS 0x28
+#define NTSVCS_GET_HW_PROFILE_INFO 0x29
+#define NTSVCS_GET_VERSION_INTERNAL 0x3e
+
+
+/**************************/
+
+typedef struct {
+ /* nothing in the request */
+ uint32 dummy;
+} NTSVCS_Q_GET_VERSION;
+
+typedef struct {
+ uint32 version;
+ WERROR status;
+} NTSVCS_R_GET_VERSION;
+
+
+/**************************/
+
+typedef struct {
+ UNISTR2 *devicename;
+ uint32 flags;
+} NTSVCS_Q_GET_DEVICE_LIST_SIZE;
+
+typedef struct {
+ uint32 size;
+ WERROR status;
+} NTSVCS_R_GET_DEVICE_LIST_SIZE;
+
+
+/**************************/
+
+typedef struct {
+ UNISTR2 *devicename;
+ uint32 buffer_size;
+ uint32 flags;
+} NTSVCS_Q_GET_DEVICE_LIST;
+
+typedef struct {
+ UNISTR2 devicepath;
+ uint32 needed;
+ WERROR status;
+} NTSVCS_R_GET_DEVICE_LIST;
+
+/**************************/
+
+typedef struct {
+ UNISTR2 devicepath;
+ uint32 flags;
+} NTSVCS_Q_VALIDATE_DEVICE_INSTANCE;
+
+typedef struct {
+ WERROR status;
+} NTSVCS_R_VALIDATE_DEVICE_INSTANCE;
+
+/**************************/
+
+#define DEV_REGPROP_DESC 1
+
+typedef struct {
+ UNISTR2 devicepath;
+ uint32 property;
+ uint32 unknown2;
+ uint32 buffer_size1;
+ uint32 buffer_size2;
+ uint32 unknown5;
+} NTSVCS_Q_GET_DEVICE_REG_PROPERTY;
+
+typedef struct {
+ uint32 unknown1;
+ REGVAL_BUFFER value;
+ uint32 size;
+ uint32 needed;
+ WERROR status;
+} NTSVCS_R_GET_DEVICE_REG_PROPERTY;
+
+
+/**************************/
+
+typedef struct {
+ uint32 index;
+ uint8 *buffer;
+ uint32 buffer_size;
+ uint32 unknown1;
+} NTSVCS_Q_GET_HW_PROFILE_INFO;
+
+typedef struct {
+ uint32 buffer_size; /* the size (not included in the reply)
+ if just matched from the request */
+ uint8 *buffer;
+ WERROR status;
+} NTSVCS_R_GET_HW_PROFILE_INFO;
+
+
+/**************************/
+
+typedef struct {
+ uint32 unknown1;
+ UNISTR2 devicepath;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+} NTSVCS_Q_HW_PROFILE_FLAGS;
+
+typedef struct {
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ WERROR status;
+} NTSVCS_R_HW_PROFILE_FLAGS;
+
+#endif /* _RPC_NTSVCS_H */
diff --git a/source3/include/rpc_perfcount.h b/source3/include/rpc_perfcount.h
new file mode 100644
index 0000000000..0e3a6eb018
--- /dev/null
+++ b/source3/include/rpc_perfcount.h
@@ -0,0 +1,106 @@
+#ifndef _RPC_PERFCOUNT_H
+#define _RPC_PERFCOUNT_H
+
+typedef struct perf_counter_definition
+{
+ /* sizeof(PERF_COUNTER_DEFINITION) */
+ uint32 ByteLength;
+ uint32 CounterNameTitleIndex;
+ uint32 CounterNameTitlePointer;
+ uint32 CounterHelpTitleIndex;
+ uint32 CounterHelpTitlePointer;
+ uint32 DefaultScale;
+ uint32 DetailLevel;
+ uint32 CounterType;
+ uint32 CounterSize;
+ uint32 CounterOffset;
+}
+PERF_COUNTER_DEFINITION;
+
+typedef struct perf_counter_block
+{
+ /* Total size of the data block, including all data plus this header */
+ uint32 ByteLength;
+ uint8 *data;
+}
+PERF_COUNTER_BLOCK;
+
+typedef struct perf_instance_definition
+{
+ /* Total size of the instance definition, including the length of the terminated Name string */
+ uint32 ByteLength;
+ uint32 ParentObjectTitleIndex;
+ uint32 ParentObjectTitlePointer;
+ uint32 UniqueID;
+ /* From the start of the PERF_INSTANCE_DEFINITION, the byte offset to the start of the Name string */
+ uint32 NameOffset;
+ uint32 NameLength;
+ /* Unicode string containing the name for the instance */
+ uint8 *data;
+ PERF_COUNTER_BLOCK counter_data;
+}
+PERF_INSTANCE_DEFINITION;
+
+typedef struct perf_object_type
+{
+ /* Total size of the object block, including all PERF_INSTANCE_DEFINITIONs,
+ PERF_COUNTER_DEFINITIONs and PERF_COUNTER_BLOCKs in bytes */
+ uint32 TotalByteLength;
+ /* Size of this PERF_OBJECT_TYPE plus all PERF_COUNTER_DEFINITIONs in bytes */
+ uint32 DefinitionLength;
+ /* Size of this PERF_OBJECT_TYPE */
+ uint32 HeaderLength;
+ uint32 ObjectNameTitleIndex;
+ uint32 ObjectNameTitlePointer;
+ uint32 ObjectHelpTitleIndex;
+ uint32 ObjectHelpTitlePointer;
+ uint32 DetailLevel;
+ uint32 NumCounters;
+ uint32 DefaultCounter;
+ uint32 NumInstances;
+ uint32 CodePage;
+ UINT64_S PerfTime;
+ UINT64_S PerfFreq;
+ PERF_COUNTER_DEFINITION *counters;
+ PERF_INSTANCE_DEFINITION *instances;
+ PERF_COUNTER_BLOCK counter_data;
+}
+PERF_OBJECT_TYPE;
+
+/* PerfCounter Inner Buffer structs */
+typedef struct perf_data_block
+{
+ /* hardcoded to read "P.E.R.F" */
+ uint16 Signature[4];
+ uint32 LittleEndian;
+ /* both currently hardcoded to 1 */
+ uint32 Version;
+ uint32 Revision;
+ /* bytes of PERF_OBJECT_TYPE data, does NOT include the PERF_DATA_BLOCK */
+ uint32 TotalByteLength;
+ /* size of PERF_DATA_BLOCK including the uint8 *data */
+ uint32 HeaderLength;
+ /* number of PERF_OBJECT_TYPE structures encoded */
+ uint32 NumObjectTypes;
+ uint32 DefaultObject;
+ SYSTEMTIME SystemTime;
+ /* This will guarantee that we're on a 64-bit boundary before we encode
+ PerfTime, and having it there will make my offset math much easier. */
+ uint32 Padding;
+ /* Now when I'm marshalling this, I'll need to call prs_align_uint64()
+ before I start encodint the UINT64_S structs */
+ /* clock rate * seconds uptime */
+ UINT64_S PerfTime;
+ /* The clock rate of the CPU */
+ UINT64_S PerfFreq;
+ /* used for high-res timers -- for now PerfTime * 10e7 */
+ UINT64_S PerfTime100nSec;
+ uint32 SystemNameLength;
+ uint32 SystemNameOffset;
+ /* The SystemName, in unicode, terminated */
+ uint8* data;
+ PERF_OBJECT_TYPE *objects;
+}
+PERF_DATA_BLOCK;
+
+#endif /* _RPC_PERFCOUNT_H */
diff --git a/source3/include/rpc_perfcount_defs.h b/source3/include/rpc_perfcount_defs.h
new file mode 100644
index 0000000000..3999a6864d
--- /dev/null
+++ b/source3/include/rpc_perfcount_defs.h
@@ -0,0 +1,73 @@
+#ifndef _RPC_PERFCOUNT_DEFS_H
+#define _RPC_PERFCOUNT_DEFS_H
+
+/*
+ * The following #defines match what is in winperf.h.
+ * See that include file for more details, or look up
+ * "Performance Data Format" on MSDN
+ *
+ * Rather than including them in rpc_perfcount.h, they
+ * were broken out into a separate .h file so that they
+ * can be included by other programs that need this info
+ * without pulling in everything else samba-related.
+ */
+
+#define PERF_NO_INSTANCES -1
+#define PERF_NO_UNIQUE_ID -1
+
+/* These determine the data size */
+#define PERF_SIZE_DWORD 0x00000000
+#define PERF_SIZE_LARGE 0x00000100
+#define PERF_SIZE_ZERO 0x00000200
+#define PERF_SIZE_VARIABLE_LEN 0x00000300
+
+/* These determine the usage of the counter */
+#define PERF_TYPE_NUMBER 0x00000000
+#define PERF_TYPE_COUNTER 0x00000400
+#define PERF_TYPE_TEXT 0x00000800
+#define PERF_TYPE_ZERO 0x00000C00
+
+/* If PERF_TYPE_NUMBER was selected, these provide display information */
+#define PERF_NUMBER_HEX 0x00000000
+#define PERF_NUMBER_DECIMAL 0x00010000
+#define PERF_NUMBER_DEC_1000 0x00020000
+
+/* If PERF_TYPE_COUNTER was selected, these provide display information */
+#define PERF_COUNTER_VALUE 0x00000000
+#define PERF_COUNTER_RATE 0x00010000
+#define PERF_COUNTER_FRACTION 0x00020000
+#define PERF_COUNTER_BASE 0x00030000
+#define PERF_COUNTER_ELAPSED 0x00040000
+#define PERF_COUNTER_QUEUELEN 0x00050000
+#define PERF_COUNTER_HISTOGRAM 0x00060000
+#define PERF_COUNTER_PRECISION 0x00070000
+
+/* If PERF_TYPE_TEXT was selected, these provide display information */
+#define PERF_TEXT_UNICODE 0x00000000
+#define PERF_TEXT_ASCII 0x00010000
+
+/* These provide information for which tick count to use when computing elapsed interval */
+#define PERF_TIMER_TICK 0x00000000
+#define PERF_TIMER_100NS 0x00100000
+#define PERF_OBJECT_TIMER 0x00200000
+
+/* These affect how the data is manipulated prior to being displayed */
+#define PERF_DELTA_COUNTER 0x00400000
+#define PERF_DELTA_BASE 0x00800000
+#define PERF_INVERSE_COUNTER 0x01000000
+#define PERF_MULTI_COUNTER 0x02000000
+
+/* These determine if any text gets added when the value is displayed */
+#define PERF_DISPLAY_NO_SUFFIX 0x00000000
+#define PERF_DISPLAY_PER_SEC 0x10000000
+#define PERF_DISPLAY_PERCENT 0x20000000
+#define PERF_DISPLAY_SECONDS 0x30000000
+#define PERF_DISPLAY_NOSHOW 0x40000000
+
+/* These determine the DetailLevel of the counter */
+#define PERF_DETAIL_NOVICE 100
+#define PERF_DETAIL_ADVANCED 200
+#define PERF_DETAIL_EXPERT 300
+#define PERF_DETAIL_WIZARD 400
+
+#endif /* _RPC_PERFCOUNT_DEFS_H */
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index f6ddf5b9ad..b24b640237 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/include/rpc_reg.h
@@ -25,8 +25,6 @@
#ifndef _RPC_REG_H /* _RPC_REG_H */
#define _RPC_REG_H
-#include "reg_objects.h"
-
/* RPC opnum */
#define REG_OPEN_HKCR 0x00
@@ -50,6 +48,7 @@
#define REG_SET_VALUE 0x16
#define REG_SHUTDOWN 0x18
#define REG_ABORT_SHUTDOWN 0x19
+#define REG_OPEN_HKPT 0x20
#define REG_GETVERSION 0x1a
#define REG_SHUTDOWN_EX 0x1e
@@ -63,6 +62,9 @@
#define KEY_HKLM "HKLM"
#define KEY_HKU "HKU"
#define KEY_HKCR "HKCR"
+#define KEY_HKPD "HKPD"
+#define KEY_HKPT "HKPT"
+#define KEY_SERVICES "HKLM\\SYSTEM\\CurrentControlSet\\Services"
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"
#define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports"
@@ -85,6 +87,16 @@
#define REG_FULL_RESOURCE_DESCRIPTOR 9
#define REG_RESOURCE_REQUIREMENTS_LIST 10
+/*
+ * Registry key types
+ * Most keys are going to be GENERIC -- may need a better name?
+ * HKPD and HKPT are used by reg_perfcount.c
+ * they are special keys that congtain performance data
+ */
+#define REG_KEY_GENERIC 0
+#define REG_KEY_HKPD 1
+#define REG_KEY_HKPT 2
+
/*
* container for function pointers to enumeration routines
* for vitural registry view
@@ -108,9 +120,8 @@ typedef struct {
/* structure to store the registry handles */
typedef struct _RegistryKey {
- struct _RegistryKey *prev, *next;
-
- pstring name; /* full name of registry key */
+ uint32 type;
+ char *name; /* full name of registry key */
uint32 access_granted;
REGISTRY_HOOK *hook;
} REGISTRY_KEY;
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index fb829558d4..6067587654 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -26,8 +26,6 @@
#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
#define _RPC_SAMR_H
-#include "rpc_misc.h"
-
/*******************************************************************
the following information comes from a QuickView on samsrv.dll,
and gives an idea of exactly what is needed:
diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h
index b2b97e391e..c385e41fd3 100644
--- a/source3/include/rpc_secdes.h
+++ b/source3/include/rpc_secdes.h
@@ -481,13 +481,16 @@ typedef struct standard_mapping {
SC_RIGHT_MGR_ENUMERATE_SERVICE | \
SC_RIGHT_MGR_QUERY_LOCK_STATUS )
-#define SC_MANAGER_ALL_ACCESS \
+#define SC_MANAGER_EXECUTE_ACCESS SC_MANAGER_READ_ACCESS
+
+#define SC_MANAGER_WRITE_ACCESS \
( STANDARD_RIGHTS_REQUIRED_ACCESS | \
SC_MANAGER_READ_ACCESS | \
SC_RIGHT_MGR_CREATE_SERVICE | \
SC_RIGHT_MGR_LOCK | \
SC_RIGHT_MGR_MODIFY_BOOT_CONFIG )
+#define SC_MANAGER_ALL_ACCESS SC_MANAGER_WRITE_ACCESS
/* Service Object Bits */
@@ -515,12 +518,14 @@ typedef struct standard_mapping {
SC_RIGHT_SVC_STOP | \
SC_RIGHT_SVC_PAUSE_CONTINUE )
-#define SERVICE_ALL_ACCESS \
+#define SERVICE_WRITE_ACCESS \
( STANDARD_RIGHTS_REQUIRED_ACCESS | \
SERVICE_READ_ACCESS | \
SERVICE_EXECUTE_ACCESS | \
SC_RIGHT_SVC_CHANGE_CONFIG )
+#define SERVICE_ALL_ACCESS SERVICE_WRITE_ACCESS
+
/*
diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h
index 77dd004fed..443a6588a6 100644
--- a/source3/include/rpc_svcctl.h
+++ b/source3/include/rpc_svcctl.h
@@ -22,12 +22,15 @@
#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_LOCK_SERVICE_DB 0x03
+#define SVCCTL_QUERY_SERVICE_SEC 0x04 /* not impmenented */
+#define SVCCTL_SET_SEVICE_SEC 0x05 /* not implemented */
#define SVCCTL_QUERY_STATUS 0x06
+#define SVCCTL_UNLOCK_SERVICE_DB 0x08
#define SVCCTL_ENUM_DEPENDENT_SERVICES_W 0x0d
#define SVCCTL_ENUM_SERVICES_STATUS_W 0x0e
#define SVCCTL_OPEN_SCMANAGER_W 0x0f
@@ -105,14 +108,17 @@
#define SVCCTL_CONTROL_STOP 0x00000001
#define SVCCTL_CONTROL_PAUSE 0x00000002
#define SVCCTL_CONTROL_CONTINUE 0x00000003
-#define SVCCTL_CONTROL_SHUTDOWN 0x00000004
+#define SVCCTL_CONTROL_INTERROGATE 0x00000004
+#define SVCCTL_CONTROL_SHUTDOWN 0x00000005
#define SVC_HANDLE_IS_SCM 0x0000001
#define SVC_HANDLE_IS_SERVICE 0x0000002
+#define SVC_HANDLE_IS_DBLOCK 0x0000003
-#define SVC_STATUS_PROCESS_INFO 0x00000001
+#define SVC_STATUS_PROCESS_INFO 0x00000000
-#define SVCCTL_SCRIPT_DIR "/svcctl/"
+/* where we assume the location of the service control scripts */
+#define SVCCTL_SCRIPT_DIR "svcctl"
/* utility structures for RPCs */
@@ -127,13 +133,7 @@ typedef struct {
} SERVICE_STATUS;
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 status;
uint32 process_id;
uint32 service_flags;
} SERVICE_STATUS_PROCESS;
@@ -158,7 +158,8 @@ typedef struct {
} SERVICE_CONFIG;
typedef struct {
- UNISTR2 *description;
+ uint32 unknown;
+ UNISTR description;
} SERVICE_DESCRIPTION;
typedef struct {
@@ -168,20 +169,12 @@ typedef struct {
typedef struct {
uint32 reset_period;
- UNISTR2 *rebootmsg;
+ UNISTR2 *rebootmsg; /* i have no idea if these are UNISTR2's. I can't get a good trace */
UNISTR2 *command;
- uint32 nActions;
- SC_ACTION *saActions;
- UNISTR2 *description;
+ uint32 num_actions;
+ SC_ACTION *actions;
} SERVICE_FAILURE_ACTIONS;
-
-typedef struct SCM_info_struct {
- uint32 type; /* should be SVC_HANDLE_IS_SCM */
- pstring target_server_name; /* name of the server on which the operation is taking place */
- pstring target_db_name; /* name of the database that we're opening */
-} SCM_info;
-
typedef struct Service_info_struct {
uint32 type; /* should be SVC_HANDLE_IS_SERVICE */
pstring servicename; /* the name of the service */
@@ -205,9 +198,9 @@ typedef struct Service_info_struct {
typedef struct {
/* functions for enumerating subkeys and values */
- WERROR (*stop_service)( SERVICE_STATUS *status );
- WERROR (*start_service) ( void );
- WERROR (*service_status)( SERVICE_STATUS *status );
+ WERROR (*stop_service)( const char *service, SERVICE_STATUS *status );
+ WERROR (*start_service) ( const char *service );
+ WERROR (*service_status)( const char *service, SERVICE_STATUS *status );
} SERVICE_CONTROL_OPS;
/* structure to store the service handle information */
@@ -341,6 +334,7 @@ typedef struct {
WERROR status;
} SVCCTL_R_ENUM_DEPENDENT_SERVICES;
+
/**************************/
typedef struct {
@@ -354,32 +348,58 @@ typedef struct {
WERROR status;
} SVCCTL_R_QUERY_SERVICE_CONFIG;
+
+/**************************/
+
typedef struct {
POLICY_HND handle;
- uint32 info_level;
+ uint32 level;
uint32 buffer_size;
} SVCCTL_Q_QUERY_SERVICE_CONFIG2;
typedef struct {
- UNISTR2 *description;
- uint32 returned;
+ RPC_BUFFER buffer;
uint32 needed;
- uint32 offset;
WERROR status;
} SVCCTL_R_QUERY_SERVICE_CONFIG2;
+
+/**************************/
+
typedef struct {
POLICY_HND handle;
- uint32 info_level;
+ uint32 level;
uint32 buffer_size;
} SVCCTL_Q_QUERY_SERVICE_STATUSEX;
typedef struct {
RPC_BUFFER buffer;
- uint32 returned;
uint32 needed;
WERROR status;
} SVCCTL_R_QUERY_SERVICE_STATUSEX;
+
+/**************************/
+
+typedef struct {
+ POLICY_HND handle;
+} SVCCTL_Q_LOCK_SERVICE_DB;
+
+typedef struct {
+ POLICY_HND h_lock;
+ WERROR status;
+} SVCCTL_R_LOCK_SERVICE_DB;
+
+
+/**************************/
+
+typedef struct {
+ POLICY_HND h_lock;
+} SVCCTL_Q_UNLOCK_SERVICE_DB;
+
+typedef struct {
+ WERROR status;
+} SVCCTL_R_UNLOCK_SERVICE_DB;
+
#endif /* _RPC_SVCCTL_H */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index c0778383c6..61d2237b2d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -206,13 +206,13 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
#define PI_SHUTDOWN 10
#define PI_SVCCTL 11
#define PI_EVENTLOG 12
-#define PI_MAX_PIPES 13
+#define PI_NTSVCS 13
+#define PI_MAX_PIPES 14
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
-typedef struct nttime_info
-{
- uint32 low;
- uint32 high;
+typedef struct nttime_info {
+ uint32 low;
+ uint32 high;
} NTTIME;
@@ -414,6 +414,10 @@ struct fd_handle {
*/
};
+struct timed_event;
+struct idle_event;
+struct share_mode_entry;
+
typedef struct files_struct {
struct files_struct *next, *prev;
int fnum;
@@ -437,6 +441,11 @@ typedef struct files_struct {
time_t last_write_time;
int oplock_type;
int sent_oplock_break;
+ struct timed_event *oplock_timeout;
+
+ struct share_mode_entry *pending_break_messages;
+ int num_pending_break_messages;
+
unsigned long file_id;
BOOL can_lock;
BOOL can_read;
@@ -564,6 +573,7 @@ struct current_user
#define NO_BREAK_SENT 0
#define BREAK_TO_NONE_SENT 1
#define LEVEL_II_BREAK_SENT 2
+#define ASYNC_LEVEL_II_BREAK_SENT 3
typedef struct {
fstring smb_name; /* user name from the client */
@@ -619,28 +629,19 @@ struct interface
struct in_addr nmask;
};
-/* struct used by share mode violation error processing */
-typedef struct {
- pid_t pid;
- uint16 mid;
- struct timeval time;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- uint16 port;
-} deferred_open_entry;
-
/* Internal message queue for deferred opens. */
struct pending_message_list {
struct pending_message_list *next, *prev;
- struct timeval msg_time; /* The timeout time */
+ struct timeval request_time; /* When was this first issued? */
+ struct timeval end_time; /* When does this time out? */
DATA_BLOB buf;
DATA_BLOB private_data;
};
/* struct returned by get_share_modes */
-typedef struct {
- pid_t pid;
- uint16 op_port;
+struct share_mode_entry {
+ struct process_id pid;
+ uint16 op_mid;
uint16 op_type;
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
@@ -652,14 +653,18 @@ typedef struct {
SMB_DEV_T dev;
SMB_INO_T inode;
unsigned long share_file_id;
-} share_mode_entry;
-
-
-#define SHAREMODE_FN_CAST() \
- void (*)(share_mode_entry *, char*)
+};
-#define SHAREMODE_FN(fn) \
- void (*fn)(share_mode_entry *, char*)
+struct share_mode_lock {
+ const char *filename;
+ SMB_DEV_T dev;
+ SMB_INO_T ino;
+ int num_share_modes;
+ struct share_mode_entry *share_modes;
+ BOOL delete_on_close;
+ BOOL fresh;
+ BOOL modified;
+};
#define NT_HASH_LEN 16
#define LM_HASH_LEN 16
@@ -700,14 +705,14 @@ typedef struct {
/* key and data in the connections database - used in smbstatus and smbd */
struct connections_key {
- pid_t pid;
+ struct process_id pid;
int cnum;
fstring name;
};
struct connections_data {
int magic;
- pid_t pid;
+ struct process_id pid;
int cnum;
uid_t uid;
gid_t gid;
@@ -719,12 +724,6 @@ struct connections_data {
};
-/* key and data records in the tdb locking database */
-struct locking_key {
- SMB_DEV_T dev;
- SMB_INO_T inode;
-};
-
/* the following are used by loadparm for option lists */
typedef enum {
P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
@@ -744,11 +743,11 @@ struct enum_list {
};
#define BRLOCK_FN_CAST() \
- void (*)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+ void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
enum brl_type lock_type, \
br_off start, br_off size)
#define BRLOCK_FN(fn) \
- void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
+ void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
enum brl_type lock_type, \
br_off start, br_off size)
struct parm_struct
@@ -1462,10 +1461,29 @@ extern int chain_size;
#define BATCH_OPLOCK 2
#define LEVEL_II_OPLOCK 4
#define INTERNAL_OPEN_ONLY 8
+#define FAKE_LEVEL_II_OPLOCK 16 /* Client requested no_oplock, but we have to
+ * inform potential level2 holders on
+ * write. */
+#define DEFERRED_OPEN_ENTRY 32
+#define UNUSED_SHARE_MODE_ENTRY 64
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
-#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & (unsigned int)LEVEL_II_OPLOCK)
+#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)LEVEL_II_OPLOCK|(unsigned int)FAKE_LEVEL_II_OPLOCK))
+
+struct inform_level2_message {
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ uint16 mid;
+ unsigned long target_file_id;
+ unsigned long source_file_id;
+};
+
+struct kernel_oplock_message {
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ unsigned long file_id;
+};
/*
* On the wire return values for oplock types.
@@ -1484,94 +1502,22 @@ extern int chain_size;
#define OPLOCKLEVEL_II 1
/*
- * Loopback command offsets.
- */
-
-#define OPBRK_CMD_LEN_OFFSET 0
-#define OPBRK_CMD_PORT_OFFSET 4
-#define OPBRK_CMD_HEADER_LEN 6
-
-#define OPBRK_MESSAGE_CMD_OFFSET 0
-
-/*
- * Oplock break command code to send over the udp socket.
- * The same message is sent for both exlusive and level II breaks.
- *
- * The form of this is :
- *
- * 0 2 2+pid 2+pid+dev 2+pid+dev+ino
- * +----+--------+-------+--------+---------+
- * | cmd| pid | dev | inode | fileid |
- * +----+--------+-------+--------+---------+
- */
-
-#define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
-#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
-#define OPLOCK_BREAK_FILEID_OFFSET (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
-#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
-
-/* Message types */
-#define OPLOCK_BREAK_CMD 0x1
-#define KERNEL_OPLOCK_BREAK_CMD 0x2
-#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
-#define ASYNC_LEVEL_II_OPLOCK_BREAK_CMD 0x4
-
-/* Add the "deferred open" message. */
-#define RETRY_DEFERRED_OPEN_CMD 0x5
-
-/*
- * And the message format for it. Keep the same message length.
- *
- * 0 2 2+pid 2+pid+dev 2+pid+dev+ino
- * +----+--------+-------+--------+---------+
- * | cmd| pid | dev | inode | mid |
- * +----+--------+-------+--------+---------+
- */
-
-#define DEFERRED_OPEN_CMD_OFFSET 0
-#define DEFERRED_OPEN_PID_OFFSET 2 /* pid we're *sending* from. */
-#define DEFERRED_OPEN_DEV_OFFSET (DEFERRED_OPEN_PID_OFFSET + sizeof(pid_t))
-#define DEFERRED_OPEN_INODE_OFFSET (DEFERRED_OPEN_DEV_OFFSET + sizeof(SMB_DEV_T))
-#define DEFERRED_OPEN_MID_OFFSET (DEFERRED_OPEN_INODE_OFFSET + sizeof(SMB_INO_T))
-#define DEFERRED_OPEN_MSG_LEN OPLOCK_BREAK_MSG_LEN
-
-/*
* Capabilities abstracted for different systems.
*/
#define KERNEL_OPLOCK_CAPABILITY 0x1
-/*
- * Oplock break command code sent via the kernel interface (if it exists).
- *
- * Form of this is :
- *
- * 0 2 2+devsize 2+devsize+inodesize
- * +----+--------+--------+----------+
- * | cmd| dev | inode | fileid |
- * +----+--------+--------+----------+
- */
-#define KERNEL_OPLOCK_BREAK_DEV_OFFSET 2
-#define KERNEL_OPLOCK_BREAK_INODE_OFFSET (KERNEL_OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
-#define KERNEL_OPLOCK_BREAK_FILEID_OFFSET (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
-#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
-
-
/* if a kernel does support oplocks then a structure of the following
typee is used to describe how to interact with the kernel */
struct kernel_oplocks {
- BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len);
+ files_struct * (*receive_message)(fd_set *fds);
BOOL (*set_oplock)(files_struct *fsp, int oplock_type);
void (*release_oplock)(files_struct *fsp);
- BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id);
BOOL (*msg_waiting)(fd_set *fds);
int notification_fd;
};
-#define CMD_REPLY 0x8000
-
/* this structure defines the functions for doing change notify in
various implementations */
struct cnotify_fns {
@@ -1759,4 +1705,18 @@ struct ea_list {
/* EA to use for DOS attributes */
#define SAMBA_XATTR_DOS_ATTRIB "user.DOSATTRIB"
+struct uuid {
+ uint32 time_low;
+ uint16 time_mid;
+ uint16 time_hi_and_version;
+ uint8 clock_seq[2];
+ uint8 node[6];
+};
+#define UUID_SIZE 16
+
+#define UUID_FLAT_SIZE 16
+typedef struct uuid_flat {
+ uint8 info[UUID_FLAT_SIZE];
+} UUID_FLAT;
+
#endif /* _SMB_H */
diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h
new file mode 100644
index 0000000000..144317cc1e
--- /dev/null
+++ b/source3/include/smb_ldap.h
@@ -0,0 +1,256 @@
+/*
+ Unix SMB/CIFS Implementation.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Volker Lendecke 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
+ 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 _SMB_LDAP_H
+#define _SMB_LDAP_H
+
+enum ldap_request_tag {
+ LDAP_TAG_BindRequest = 0,
+ LDAP_TAG_BindResponse = 1,
+ LDAP_TAG_UnbindRequest = 2,
+ LDAP_TAG_SearchRequest = 3,
+ LDAP_TAG_SearchResultEntry = 4,
+ LDAP_TAG_SearchResultDone = 5,
+ LDAP_TAG_ModifyRequest = 6,
+ LDAP_TAG_ModifyResponse = 7,
+ LDAP_TAG_AddRequest = 8,
+ LDAP_TAG_AddResponse = 9,
+ LDAP_TAG_DelRequest = 10,
+ LDAP_TAG_DelResponse = 11,
+ LDAP_TAG_ModifyDNRequest = 12,
+ LDAP_TAG_ModifyDNResponse = 13,
+ LDAP_TAG_CompareRequest = 14,
+ LDAP_TAG_CompareResponse = 15,
+ LDAP_TAG_AbandonRequest = 16,
+ LDAP_TAG_SearchResultReference = 19,
+ LDAP_TAG_ExtendedRequest = 23,
+ LDAP_TAG_ExtendedResponse = 24
+};
+
+enum ldap_auth_mechanism {
+ LDAP_AUTH_MECH_SIMPLE = 0,
+ LDAP_AUTH_MECH_SASL = 3
+};
+
+#ifndef LDAP_SUCCESS
+enum ldap_result_code {
+ LDAP_SUCCESS = 0,
+ LDAP_SASL_BIND_IN_PROGRESS = 0x0e,
+ LDAP_INVALID_CREDENTIALS = 0x31,
+ LDAP_OTHER = 0x50
+};
+#endif /* LDAP_SUCCESS */
+
+struct ldap_Result {
+ int resultcode;
+ const char *dn;
+ const char *errormessage;
+ const char *referral;
+};
+
+struct ldap_attribute {
+ const char *name;
+ int num_values;
+ DATA_BLOB *values;
+};
+
+struct ldap_BindRequest {
+ int version;
+ const char *dn;
+ enum ldap_auth_mechanism mechanism;
+ union {
+ const char *password;
+ struct {
+ const char *mechanism;
+ DATA_BLOB secblob;
+ } SASL;
+ } creds;
+};
+
+struct ldap_BindResponse {
+ struct ldap_Result response;
+ union {
+ DATA_BLOB secblob;
+ } SASL;
+};
+
+struct ldap_UnbindRequest {
+ uint8 __dummy;
+};
+
+enum ldap_scope {
+ LDAP_SEARCH_SCOPE_BASE = 0,
+ LDAP_SEARCH_SCOPE_SINGLE = 1,
+ LDAP_SEARCH_SCOPE_SUB = 2
+};
+
+enum ldap_deref {
+ LDAP_DEREFERENCE_NEVER = 0,
+ LDAP_DEREFERENCE_IN_SEARCHING = 1,
+ LDAP_DEREFERENCE_FINDING_BASE = 2,
+ LDAP_DEREFERENCE_ALWAYS
+};
+
+struct ldap_SearchRequest {
+ const char *basedn;
+ enum ldap_scope scope;
+ enum ldap_deref deref;
+ uint32 timelimit;
+ uint32 sizelimit;
+ BOOL attributesonly;
+ char *filter;
+ int num_attributes;
+ const char **attributes;
+};
+
+struct ldap_SearchResEntry {
+ const char *dn;
+ int num_attributes;
+ struct ldap_attribute *attributes;
+};
+
+struct ldap_SearchResRef {
+ int num_referrals;
+ const char **referrals;
+};
+
+enum ldap_modify_type {
+ LDAP_MODIFY_NONE = -1,
+ LDAP_MODIFY_ADD = 0,
+ LDAP_MODIFY_DELETE = 1,
+ LDAP_MODIFY_REPLACE = 2
+};
+
+struct ldap_mod {
+ enum ldap_modify_type type;
+ struct ldap_attribute attrib;
+};
+
+struct ldap_ModifyRequest {
+ const char *dn;
+ int num_mods;
+ struct ldap_mod *mods;
+};
+
+struct ldap_AddRequest {
+ const char *dn;
+ int num_attributes;
+ struct ldap_attribute *attributes;
+};
+
+struct ldap_DelRequest {
+ const char *dn;
+};
+
+struct ldap_ModifyDNRequest {
+ const char *dn;
+ const char *newrdn;
+ BOOL deleteolddn;
+ const char *newsuperior;
+};
+
+struct ldap_CompareRequest {
+ const char *dn;
+ const char *attribute;
+ const char *value;
+};
+
+struct ldap_AbandonRequest {
+ uint32 messageid;
+};
+
+struct ldap_ExtendedRequest {
+ const char *oid;
+ DATA_BLOB value;
+};
+
+struct ldap_ExtendedResponse {
+ struct ldap_Result response;
+ const char *name;
+ DATA_BLOB value;
+};
+
+union ldap_Request {
+ struct ldap_BindRequest BindRequest;
+ struct ldap_BindResponse BindResponse;
+ struct ldap_UnbindRequest UnbindRequest;
+ struct ldap_SearchRequest SearchRequest;
+ struct ldap_SearchResEntry SearchResultEntry;
+ struct ldap_Result SearchResultDone;
+ struct ldap_SearchResRef SearchResultReference;
+ struct ldap_ModifyRequest ModifyRequest;
+ struct ldap_Result ModifyResponse;
+ struct ldap_AddRequest AddRequest;
+ struct ldap_Result AddResponse;
+ struct ldap_DelRequest DelRequest;
+ struct ldap_Result DelResponse;
+ struct ldap_ModifyDNRequest ModifyDNRequest;
+ struct ldap_Result ModifyDNResponse;
+ struct ldap_CompareRequest CompareRequest;
+ struct ldap_Result CompareResponse;
+ struct ldap_AbandonRequest AbandonRequest;
+ struct ldap_ExtendedRequest ExtendedRequest;
+ struct ldap_ExtendedResponse ExtendedResponse;
+};
+
+struct ldap_Control {
+ const char *oid;
+ BOOL critical;
+ DATA_BLOB value;
+};
+
+struct ldap_message {
+ TALLOC_CTX *mem_ctx;
+ uint32 messageid;
+ uint8 type;
+ union ldap_Request r;
+ int num_controls;
+ struct ldap_Control *controls;
+};
+
+struct ldap_queue_entry {
+ struct ldap_queue_entry *next, *prev;
+ int msgid;
+ struct ldap_message *msg;
+};
+
+struct ldap_connection {
+ TALLOC_CTX *mem_ctx;
+ int sock;
+ int next_msgid;
+ char *host;
+ uint16 port;
+ BOOL ldaps;
+
+ const char *auth_dn;
+ const char *simple_pw;
+
+ /* Current outstanding search entry */
+ int searchid;
+
+ /* List for incoming search entries */
+ struct ldap_queue_entry *search_entries;
+
+ /* Outstanding LDAP requests that have not yet been replied to */
+ struct ldap_queue_entry *outstanding;
+};
+
+#endif
diff --git a/source3/include/smb_share_modes.h b/source3/include/smb_share_modes.h
index f61ba624c6..1e04ea496d 100644
--- a/source3/include/smb_share_modes.h
+++ b/source3/include/smb_share_modes.h
@@ -55,7 +55,7 @@ struct smb_share_mode_entry {
uint32_t access_mask;
struct timeval open_time;
uint32_t file_id;
- pid_t pid;
+ struct process_id pid;
};
/*
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h
index df56f60bf3..bea1a6d84a 100644
--- a/source3/include/smbldap.h
+++ b/source3/include/smbldap.h
@@ -1,5 +1,5 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/CIFS mplementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Gerald Carter 2001-2003
@@ -40,6 +40,7 @@ struct smbldap_state;
#define LDAP_OBJ_IDPOOL "sambaUnixIdPool"
#define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry"
#define LDAP_OBJ_SID_ENTRY "sambaSidEntry"
+#define LDAP_OBJ_TRUST_PASSWORD "sambaTrustPassword"
#define LDAP_OBJ_ACCOUNT "account"
#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
@@ -95,10 +96,12 @@ struct smbldap_state;
#define LDAP_ATTR_LOGON_COUNT 36
#define LDAP_ATTR_MUNGED_DIAL 37
#define LDAP_ATTR_BAD_PASSWORD_TIME 38
-#define LDAP_ATTR_PWD_HISTORY 39
+#define LDAP_ATTR_PWD_HISTORY 39
#define LDAP_ATTR_SID_LIST 40
-#define LDAP_ATTR_MOD_TIMESTAMP 41
-#define LDAP_ATTR_LOGON_HOURS 42
+#define LDAP_ATTR_MOD_TIMESTAMP 41
+#define LDAP_ATTR_LOGON_HOURS 42
+#define LDAP_ATTR_TRUST_PASSWD_FLAGS 43
+
typedef struct _attrib_map_entry {
int attrib;
@@ -117,6 +120,8 @@ extern ATTRIB_MAP_ENTRY groupmap_attr_list[];
extern ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[];
extern ATTRIB_MAP_ENTRY idpool_attr_list[];
extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
+extern ATTRIB_MAP_ENTRY trustpw_attr_list[];
+
/* Function declarations -- not included in proto.h so we don't
have to worry about LDAP structure types */
diff --git a/source3/include/spnego.h b/source3/include/spnego.h
index 8bb13bd354..66abe31705 100644
--- a/source3/include/spnego.h
+++ b/source3/include/spnego.h
@@ -43,7 +43,7 @@ typedef enum _spnego_negResult {
} negResult_t;
typedef struct spnego_negTokenInit {
- char **mechTypes;
+ const char **mechTypes;
int reqFlags;
DATA_BLOB mechToken;
DATA_BLOB mechListMIC;
diff --git a/source3/include/srvstr.h b/source3/include/srvstr.h
index 04db59cf01..1029df53ae 100644
--- a/source3/include/srvstr.h
+++ b/source3/include/srvstr.h
@@ -18,8 +18,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-
#define srvstr_pull(base_ptr, dest, src, dest_len, src_len, flags) \
pull_string(base_ptr, dest, src, dest_len, src_len, flags)
diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c
index 423dc1675a..b02edc5b40 100644
--- a/source3/lib/account_pol.c
+++ b/source3/lib/account_pol.c
@@ -3,6 +3,7 @@
* account policy storage
* Copyright (C) Jean François Micouleau 1998-2001.
* Copyright (C) Andrew Bartlett 2002
+ * Copyright (C) Guenther Deschner 2004-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,102 +23,65 @@
#include "includes.h"
static TDB_CONTEXT *tdb;
-#define DATABASE_VERSION 2
+/* cache all entries for 60 seconds for to save ldap-queries (cache is updated
+ * after this period if admins do not use pdbedit or usermanager but manipulate
+ * ldap directly) - gd */
-/****************************************************************************
- Set default for a field if it is empty
-****************************************************************************/
-
-static void set_default_on_empty(int field, uint32 value)
-{
- if (account_policy_get(field, NULL))
- return;
- account_policy_set(field, value);
- return;
-}
+#define DATABASE_VERSION 3
+#define AP_LASTSET "LAST_CACHE_UPDATE"
+#define AP_TTL 60
-/****************************************************************************
- Open the account policy tdb.
-****************************************************************************/
-BOOL init_account_policy(void)
-{
- const char *vstring = "INFO/version";
- uint32 version;
+struct ap_table {
+ int field;
+ const char *string;
+ uint32 default_val;
+ const char *description;
+ const char *ldap_attr;
+};
- if (tdb)
- return True;
- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open account policy database\n"));
- return False;
- }
+static const struct ap_table account_policy_names[] = {
+ {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
+ "Minimal password length (default: 5)",
+ "sambaMinPwdLength" },
- /* handle a Samba upgrade */
- tdb_lock_bystring(tdb, vstring,0);
- if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
- tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
+ {AP_PASSWORD_HISTORY, "password history", 0,
+ "Length of Password History Entries (default: 0 => off)",
+ "sambaPwdHistoryLength" },
- set_default_on_empty(
- AP_MIN_PASSWORD_LEN,
- MINPASSWDLENGTH);/* 5 chars minimum */
- set_default_on_empty(
- AP_PASSWORD_HISTORY,
- 0); /* don't keep any old password */
- set_default_on_empty(
- AP_USER_MUST_LOGON_TO_CHG_PASS,
- 0); /* don't force user to logon */
- set_default_on_empty(
- AP_MAX_PASSWORD_AGE,
- (uint32)-1); /* don't expire */
- set_default_on_empty(
- AP_MIN_PASSWORD_AGE,
- 0); /* 0 days */
- set_default_on_empty(
- AP_LOCK_ACCOUNT_DURATION,
- 30); /* lockout for 30 minutes */
- set_default_on_empty(
- AP_RESET_COUNT_TIME,
- 30); /* reset after 30 minutes */
- set_default_on_empty(
- AP_BAD_ATTEMPT_LOCKOUT,
- 0); /* don't lockout */
- set_default_on_empty(
- AP_TIME_TO_LOGOUT,
- -1); /* don't force logout */
- set_default_on_empty(
- AP_REFUSE_MACHINE_PW_CHANGE,
- 0); /* allow machine pw changes */
- }
- tdb_unlock_bystring(tdb, vstring);
-
- /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
-
- privilege_create_account( &global_sid_World );
- privilege_create_account( &global_sid_Builtin_Administrators );
- privilege_create_account( &global_sid_Builtin_Account_Operators );
- privilege_create_account( &global_sid_Builtin_Server_Operators );
- privilege_create_account( &global_sid_Builtin_Print_Operators );
- privilege_create_account( &global_sid_Builtin_Backup_Operators );
+ {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
+ "Force Users to logon for password change (default: 0 => off, 2 => on)",
+ "sambaLogonToChgPwd" },
- return True;
-}
-
-static const struct {
- int field;
- const char *string;
-} account_policy_names[] = {
- {AP_MIN_PASSWORD_LEN, "min password length"},
- {AP_PASSWORD_HISTORY, "password history"},
- {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
- {AP_MAX_PASSWORD_AGE, "maximum password age"},
- {AP_MIN_PASSWORD_AGE,"minimum password age"},
- {AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
- {AP_RESET_COUNT_TIME, "reset count minutes"},
- {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
- {AP_TIME_TO_LOGOUT, "disconnect time"},
- {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change"},
- {0, NULL}
+ {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
+ "Maximum password age, in seconds (default: -1 => never expire passwords)",
+ "sambaMaxPwdAge" },
+
+ {AP_MIN_PASSWORD_AGE,"minimum password age", 0,
+ "Minimal password age, in seconds (default: 0 => allow immediate password change)",
+ "sambaMinPwdAge" },
+
+ {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
+ "Lockout duration in minutes (default: 30, -1 => forever)",
+ "sambaLockoutDuration" },
+
+ {AP_RESET_COUNT_TIME, "reset count minutes", 30,
+ "Reset time after lockout in minutes (default: 30)",
+ "sambaLockoutObservationWindow" },
+
+ {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
+ "Lockout users after bad logon attempts (default: 0 => off)",
+ "sambaLockoutThreshold" },
+
+ {AP_TIME_TO_LOGOUT, "disconnect time", -1,
+ "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
+ "sambaForceLogoff" },
+
+ {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
+ "Allow Machine Password changes (default: 0 => off)",
+ "sambaRefuseMachinePwdChange" },
+
+ {0, NULL, 0, "", NULL}
};
char *account_policy_names_list(void)
@@ -148,7 +112,7 @@ char *account_policy_names_list(void)
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-static const char *decode_account_policy_name(int field)
+const char *decode_account_policy_name(int field)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
@@ -156,7 +120,34 @@ static const char *decode_account_policy_name(int field)
return account_policy_names[i].string;
}
return NULL;
+}
+
+/****************************************************************************
+Get the account policy LDAP attribute as a string from its #define'ed number
+****************************************************************************/
+const char *get_account_policy_attr(int field)
+{
+ int i;
+ for (i=0; account_policy_names[i].field; i++) {
+ if (field == account_policy_names[i].field)
+ return account_policy_names[i].ldap_attr;
+ }
+ return NULL;
+}
+
+/****************************************************************************
+Get the account policy description as a string from its #define'ed number
+****************************************************************************/
+
+const char *account_policy_get_desc(int field)
+{
+ int i;
+ for (i=0; account_policy_names[i].string; i++) {
+ if (field == account_policy_names[i].field)
+ return account_policy_names[i].description;
+ }
+ return NULL;
}
/****************************************************************************
@@ -171,18 +162,146 @@ int account_policy_name_to_fieldnum(const char *name)
return account_policy_names[i].field;
}
return 0;
+}
+
+/*****************************************************************************
+Update LAST-Set counter inside the cache
+*****************************************************************************/
+
+static BOOL account_policy_cache_timestamp(uint32 *value, BOOL update,
+ const char *ap_name)
+{
+ pstring key;
+ uint32 val = 0;
+ time_t now;
+
+ if (ap_name == NULL)
+ return False;
+
+ slprintf(key, sizeof(key)-1, "%s/%s", ap_name, AP_LASTSET);
+
+ if (!init_account_policy())
+ return False;
+
+ if (!tdb_fetch_uint32(tdb, key, &val) && !update) {
+ DEBUG(10,("failed to get last set timestamp of cache\n"));
+ return False;
+ }
+
+ *value = val;
+
+ DEBUG(10, ("account policy cache lastset was: %s\n", http_timestring(val)));
+
+ if (update) {
+
+ now = time(NULL);
+ if (!tdb_store_uint32(tdb, key, (uint32)now)) {
+ DEBUG(1, ("tdb_store_uint32 failed for %s\n", key));
+ return False;
+ }
+ DEBUG(10, ("account policy cache lastset now: %s\n", http_timestring(now)));
+ *value = now;
+ }
+
+ return True;
}
-/****************************************************************************
-****************************************************************************/
+/*****************************************************************************
+Get default value for account policy
+*****************************************************************************/
+
+BOOL account_policy_get_default(int account_policy, uint32 *val)
+{
+ int i;
+ for (i=0; account_policy_names[i].field; i++) {
+ if (account_policy_names[i].field == account_policy) {
+ *val = account_policy_names[i].default_val;
+ return True;
+ }
+ }
+ DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
+ account_policy));
+ return False;
+}
+
+/*****************************************************************************
+ Set default for a field if it is empty
+*****************************************************************************/
+
+static BOOL account_policy_set_default_on_empty(int account_policy)
+{
+
+ uint32 value;
+
+ if (!account_policy_get(account_policy, &value) &&
+ !account_policy_get_default(account_policy, &value)) {
+ return False;
+ }
+
+ return account_policy_set(account_policy, value);
+}
+
+/*****************************************************************************
+ Open the account policy tdb.
+***`*************************************************************************/
+
+BOOL init_account_policy(void)
+{
+
+ const char *vstring = "INFO/version";
+ uint32 version;
+ int i;
+
+ if (tdb)
+ return True;
+
+ tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb) {
+ DEBUG(0,("Failed to open account policy database\n"));
+ return False;
+ }
+
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(tdb, vstring,0);
+ if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
+
+ tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
+
+ for (i=0; account_policy_names[i].field; i++) {
+
+ if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
+ DEBUG(0,("failed to set default value in account policy tdb\n"));
+ return False;
+ }
+ }
+ }
+
+ tdb_unlock_bystring(tdb, vstring);
+
+ /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
+
+ privilege_create_account( &global_sid_World );
+ privilege_create_account( &global_sid_Builtin_Administrators );
+ privilege_create_account( &global_sid_Builtin_Account_Operators );
+ privilege_create_account( &global_sid_Builtin_Server_Operators );
+ privilege_create_account( &global_sid_Builtin_Print_Operators );
+ privilege_create_account( &global_sid_Builtin_Backup_Operators );
+
+ return True;
+}
+
+/*****************************************************************************
+Get an account policy (from tdb)
+*****************************************************************************/
BOOL account_policy_get(int field, uint32 *value)
{
fstring name;
uint32 regval;
- if(!init_account_policy())return False;
+ if (!init_account_policy())
+ return False;
if (value)
*value = 0;
@@ -199,18 +318,21 @@ BOOL account_policy_get(int field, uint32 *value)
if (value)
*value = regval;
- DEBUG(10,("account_policy_get: %s:%d\n", name, regval));
+ DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval));
return True;
}
/****************************************************************************
+Set an account policy (in tdb)
****************************************************************************/
+
BOOL account_policy_set(int field, uint32 value)
{
fstring name;
- if(!init_account_policy())return False;
+ if (!init_account_policy())
+ return False;
fstrcpy(name, decode_account_policy_name(field));
if (!*name) {
@@ -219,16 +341,72 @@ BOOL account_policy_set(int field, uint32 value)
}
if (!tdb_store_uint32(tdb, name, value)) {
- DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u", field, name, value));
+ DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u\n", field, name, value));
return False;
}
- DEBUG(10,("account_policy_set: %s:%d\n", name, value));
+ DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
return True;
}
/****************************************************************************
+Set an account policy in the cache
+****************************************************************************/
+
+BOOL cache_account_policy_set(int field, uint32 value)
+{
+ uint32 lastset;
+ const char *policy_name = NULL;
+
+ policy_name = decode_account_policy_name(field);
+ if (policy_name == NULL) {
+ DEBUG(0,("cache_account_policy_set: no policy found\n"));
+ return False;
+ }
+
+ DEBUG(10,("cache_account_policy_set: updating account pol cache\n"));
+
+ if (!account_policy_set(field, value)) {
+ return False;
+ }
+
+ if (!account_policy_cache_timestamp(&lastset, True, policy_name))
+ {
+ DEBUG(10,("cache_account_policy_set: failed to get lastest cache update timestamp\n"));
+ return False;
+ }
+
+ DEBUG(10,("cache_account_policy_set: cache valid until: %s\n", http_timestring(lastset+AP_TTL)));
+
+ return True;
+}
+
+/*****************************************************************************
+Get an account policy from the cache
+*****************************************************************************/
+
+BOOL cache_account_policy_get(int field, uint32 *value)
+{
+ uint32 lastset;
+
+ if (!account_policy_cache_timestamp(&lastset, False,
+ decode_account_policy_name(field)))
+ {
+ DEBUG(10,("cache_account_policy_get: failed to get latest cache update timestamp\n"));
+ return False;
+ }
+
+ if ((lastset + AP_TTL) < (uint32)time(NULL) ) {
+ DEBUG(10,("cache_account_policy_get: no valid cache entry (cache expired)\n"));
+ return False;
+ }
+
+ return account_policy_get(field, value);
+}
+
+
+/****************************************************************************
****************************************************************************/
TDB_CONTEXT *get_account_pol_tdb( void )
diff --git a/source3/lib/arc4.c b/source3/lib/arc4.c
new file mode 100644
index 0000000000..03ca54c324
--- /dev/null
+++ b/source3/lib/arc4.c
@@ -0,0 +1,80 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ An implementation of arc4.
+
+ Copyright (C) Jeremy Allison 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"
+
+/*****************************************************************
+ Initialize state for an arc4 crypt/decrpyt.
+ arc4 state is 258 bytes - last 2 bytes are the index bytes.
+*****************************************************************/
+
+void smb_arc4_init(unsigned char arc4_state_out[258], const unsigned char *key, size_t keylen)
+{
+ size_t ind;
+ unsigned char j = 0;
+
+ for (ind = 0; ind < 256; ind++) {
+ arc4_state_out[ind] = (unsigned char)ind;
+ }
+
+ for( ind = 0; ind < 256; ind++) {
+ unsigned char tc;
+
+ j += (arc4_state_out[ind] + key[ind%keylen]);
+
+ tc = arc4_state_out[ind];
+ arc4_state_out[ind] = arc4_state_out[j];
+ arc4_state_out[j] = tc;
+ }
+ arc4_state_out[256] = 0;
+ arc4_state_out[257] = 0;
+}
+
+/*****************************************************************
+ Do the arc4 crypt/decrpyt.
+ arc4 state is 258 bytes - last 2 bytes are the index bytes.
+*****************************************************************/
+
+void smb_arc4_crypt(unsigned char arc4_state_inout[258], unsigned char *data, size_t len)
+{
+ unsigned char index_i = arc4_state_inout[256];
+ unsigned char index_j = arc4_state_inout[257];
+ size_t ind;
+
+ for( ind = 0; ind < len; ind++) {
+ unsigned char tc;
+ unsigned char t;
+
+ index_i++;
+ index_j += arc4_state_inout[index_i];
+
+ tc = arc4_state_inout[index_i];
+ arc4_state_inout[index_i] = arc4_state_inout[index_j];
+ arc4_state_inout[index_j] = tc;
+
+ t = arc4_state_inout[index_i] + arc4_state_inout[index_j];
+ data[ind] = data[ind] ^ arc4_state_inout[t];
+ }
+
+ arc4_state_inout[256] = index_i;
+ arc4_state_inout[257] = index_j;
+}
diff --git a/source3/lib/data_blob.c b/source3/lib/data_blob.c
index 161f46a941..ccd0d27f47 100644
--- a/source3/lib/data_blob.c
+++ b/source3/lib/data_blob.c
@@ -22,8 +22,9 @@
#include "includes.h"
/*******************************************************************
- free() a data blob
+ Free() a data blob.
*******************************************************************/
+
static void free_data_blob(DATA_BLOB *d)
{
if ((d) && (d->free)) {
@@ -32,8 +33,8 @@ static void free_data_blob(DATA_BLOB *d)
}
/*******************************************************************
- construct a data blob, must be freed with data_blob_free()
- you can pass NULL for p and get a blank data blob
+ Construct a data blob, must be freed with data_blob_free().
+ You can pass NULL for p and get a blank data blob
*******************************************************************/
DATA_BLOB data_blob(const void *p, size_t length)
@@ -56,8 +57,9 @@ DATA_BLOB data_blob(const void *p, size_t length)
}
/*******************************************************************
- construct a data blob, using supplied TALLOC_CTX
+ Construct a data blob, using supplied TALLOC_CTX.
*******************************************************************/
+
DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
{
DATA_BLOB ret;
@@ -83,8 +85,9 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
}
/*******************************************************************
-free a data blob
+ Free a data blob.
*******************************************************************/
+
void data_blob_free(DATA_BLOB *d)
{
if (d) {
@@ -96,8 +99,9 @@ void data_blob_free(DATA_BLOB *d)
}
/*******************************************************************
-clear a DATA_BLOB's contents
+ Clear a DATA_BLOB's contents
*******************************************************************/
+
static void data_blob_clear(DATA_BLOB *d)
{
if (d->data) {
@@ -106,11 +110,11 @@ static void data_blob_clear(DATA_BLOB *d)
}
/*******************************************************************
-free a data blob and clear its contents
+ Free a data blob and clear its contents
*******************************************************************/
+
void data_blob_clear_free(DATA_BLOB *d)
{
data_blob_clear(d);
data_blob_free(d);
}
-
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index f877d540fb..f3676070dc 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -448,19 +448,22 @@ BOOL debug_parse_levels(const char *params_str)
Receive a "set debug level" message.
****************************************************************************/
-static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
+static void debug_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
const char *params_str = buf;
/* Check, it's a proper string! */
if (params_str[len-1] != '\0') {
DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
- (unsigned int)src, (unsigned int)getpid()));
+ (unsigned int)procid_to_pid(&src),
+ (unsigned int)getpid()));
return;
}
DEBUG(3, ("INFO: Remote set of debug to `%s' (pid %u from pid %u)\n",
- params_str, (unsigned int)getpid(), (unsigned int)src));
+ params_str, (unsigned int)getpid(),
+ (unsigned int)procid_to_pid(&src)));
debug_parse_levels(params_str);
}
@@ -473,7 +476,8 @@ void debug_message_send(pid_t pid, const char *params_str)
{
if (!params_str)
return;
- message_send_pid(pid, MSG_DEBUG, params_str, strlen(params_str) + 1,
+ message_send_pid(pid_to_procid(pid), MSG_DEBUG,
+ params_str, strlen(params_str) + 1,
False);
}
@@ -481,11 +485,13 @@ void debug_message_send(pid_t pid, const char *params_str)
Return current debug level.
****************************************************************************/
-static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
+static void debuglevel_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
char *message = debug_list_class_names_and_levels();
- DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
+ DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",
+ (unsigned int)procid_to_pid(&src)));
message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
SAFE_FREE(message);
diff --git a/source3/lib/dmallocmsg.c b/source3/lib/dmallocmsg.c
index a83ed518d7..1b2308ecba 100644
--- a/source3/lib/dmallocmsg.c
+++ b/source3/lib/dmallocmsg.c
@@ -35,7 +35,7 @@ static unsigned long our_dm_mark = 0;
* Respond to a POOL_USAGE message by sending back string form of memory
* usage stats.
**/
-static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
+static void msg_req_dmalloc_mark(int UNUSED(msg_type), struct process_id UNUSED(src_pid),
void *UNUSED(buf), size_t UNUSED(len))
{
#ifdef ENABLE_DMALLOC
@@ -49,7 +49,7 @@ static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
static void msg_req_dmalloc_log_changed(int UNUSED(msg_type),
- pid_t UNUSED(src_pid),
+ struct process_id UNUSED(src_pid),
void *UNUSED(buf), size_t UNUSED(len))
{
#ifdef ENABLE_DMALLOC
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index f2e267c9d4..85599c92d3 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -251,11 +251,17 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
char* entry_buf = SMB_STRNDUP(databuf.dptr, databuf.dsize);
char *v;
time_t t;
+ unsigned u;
+ int status;
v = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
SAFE_FREE(databuf.dptr);
- sscanf(entry_buf, CACHE_DATA_FMT, (int*)&t, v);
+ status = sscanf(entry_buf, CACHE_DATA_FMT, &u, v);
+ if ( status != 2 ) {
+ DEBUG(0, ("gencache_get: Invalid return %d from sscanf\n", status ));
+ }
+ t = u;
SAFE_FREE(entry_buf);
DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
@@ -307,6 +313,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
TDB_DATA databuf;
char *keystr = NULL, *valstr = NULL, *entry = NULL;
time_t timeout = 0;
+ int status;
+ unsigned u;
/* fail completely if get null pointers passed */
SMB_ASSERT(fn && keystr_pattern);
@@ -335,7 +343,11 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
entry = SMB_STRNDUP(databuf.dptr, databuf.dsize);
SAFE_FREE(databuf.dptr);
valstr = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
- sscanf(entry, CACHE_DATA_FMT, (int*)(&timeout), valstr);
+ status = sscanf(entry, CACHE_DATA_FMT, &u, valstr);
+ if ( status != 2 ) {
+ DEBUG(0,("gencache_iterate: invalid return from sscanf %d\n",status));
+ }
+ timeout = u;
DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
keystr, valstr, ctime(&timeout)));
diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c
index 9ccddfa4c5..f37bbc9c2f 100644
--- a/source3/lib/genrand.c
+++ b/source3/lib/genrand.c
@@ -22,7 +22,7 @@
#include "includes.h"
-static unsigned char hash[258];
+static unsigned char smb_arc4_state[258];
static uint32 counter;
static BOOL done_reseed = False;
@@ -52,61 +52,6 @@ static void get_rand_reseed_data(int *reseed_data)
}
}
-/****************************************************************
- Setup the seed.
-*****************************************************************/
-
-static void seed_random_stream(unsigned char *seedval, size_t seedlen)
-{
- unsigned char j = 0;
- size_t ind;
-
- for (ind = 0; ind < 256; ind++)
- hash[ind] = (unsigned char)ind;
-
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
-
- j += (hash[ind] + seedval[ind%seedlen]);
-
- tc = hash[ind];
- hash[ind] = hash[j];
- hash[j] = tc;
- }
-
- hash[256] = 0;
- hash[257] = 0;
-}
-
-/****************************************************************
- Get datasize bytes worth of random data.
-*****************************************************************/
-
-static void get_random_stream(unsigned char *data, size_t datasize)
-{
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- size_t ind;
-
- for( ind = 0; ind < datasize; ind++) {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = hash[t];
- }
-
- hash[256] = index_i;
- hash[257] = index_j;
-}
-
/****************************************************************
Get a 16 byte hash from the contents of a file.
Note that the hash is not initialised.
@@ -202,7 +147,7 @@ static int do_reseed(BOOL use_fd, int fd)
seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)];
}
- seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
+ smb_arc4_init(smb_arc4_state, seed_inbuf, sizeof(seed_inbuf));
return -1;
}
@@ -246,7 +191,7 @@ void generate_random_buffer( unsigned char *out, int len)
while(len > 0) {
int copy_len = len > 16 ? 16 : len;
- get_random_stream(md4_buf, sizeof(md4_buf));
+ smb_arc4_crypt(smb_arc4_state, md4_buf, sizeof(md4_buf));
mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
memcpy(p, tmp_buf, copy_len);
p += copy_len;
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 7d3addd86a..058bbc99b0 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -57,8 +57,8 @@ static int received_signal;
struct message_rec {
int msg_version;
int msg_type;
- pid_t dest;
- pid_t src;
+ struct process_id dest;
+ struct process_id src;
size_t len;
};
@@ -66,7 +66,7 @@ struct message_rec {
static struct dispatch_fns {
struct dispatch_fns *next, *prev;
int msg_type;
- void (*fn)(int msg_type, pid_t pid, void *buf, size_t len);
+ void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);
} *dispatch_fns;
/****************************************************************************
@@ -83,10 +83,12 @@ static void sig_usr1(void)
A useful function for testing the message system.
****************************************************************************/
-static void ping_message(int msg_type, pid_t src, void *buf, size_t len)
+static void ping_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
const char *msg = buf ? buf : "none";
- DEBUG(1,("INFO: Received PING message from PID %u [%s]\n",(unsigned int)src, msg));
+ DEBUG(1,("INFO: Received PING message from PID %s [%s]\n",
+ procid_str_static(&src), msg));
message_send_pid(src, MSG_PONG, buf, len, True);
}
@@ -123,12 +125,12 @@ BOOL message_init(void)
Form a static tdb key from a pid.
******************************************************************/
-static TDB_DATA message_key_pid(pid_t pid)
+static TDB_DATA message_key_pid(struct process_id pid)
{
static char key[20];
TDB_DATA kbuf;
- slprintf(key, sizeof(key)-1, "PID/%d", (int)pid);
+ slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid));
kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key)+1;
@@ -140,8 +142,9 @@ static TDB_DATA message_key_pid(pid_t pid)
then delete its record in the database.
****************************************************************************/
-static BOOL message_notify(pid_t pid)
+static BOOL message_notify(struct process_id procid)
{
+ pid_t pid = procid.pid;
/*
* Doing kill with a non-positive pid causes messages to be
* sent to places we don't want.
@@ -152,7 +155,7 @@ static BOOL message_notify(pid_t pid)
if (kill(pid, SIGUSR1) == -1) {
if (errno == ESRCH) {
DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
- tdb_delete(tdb, message_key_pid(pid));
+ tdb_delete(tdb, message_key_pid(procid));
} else {
DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));
}
@@ -165,8 +168,10 @@ static BOOL message_notify(pid_t pid)
Send a message to a particular pid.
****************************************************************************/
-static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
- BOOL duplicates_allowed, unsigned int timeout)
+static BOOL message_send_pid_internal(struct process_id pid, int msg_type,
+ const void *buf, size_t len,
+ BOOL duplicates_allowed,
+ unsigned int timeout)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
@@ -180,12 +185,12 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
* sent to places we don't want.
*/
- SMB_ASSERT(pid > 0);
+ SMB_ASSERT(procid_to_pid(&pid) > 0);
rec.msg_version = MESSAGE_VERSION;
rec.msg_type = msg_type;
rec.dest = pid;
- rec.src = sys_getpid();
+ rec.src = procid_self();
rec.len = len;
kbuf = message_key_pid(pid);
@@ -288,7 +293,7 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
Send a message to a particular pid - no timeout.
****************************************************************************/
-BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
+BOOL message_send_pid(struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
{
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);
}
@@ -297,7 +302,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL
Send a message to a particular pid, with timeout in seconds.
****************************************************************************/
-BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, size_t len,
+BOOL message_send_pid_with_timeout(struct process_id pid, int msg_type, const void *buf, size_t len,
BOOL duplicates_allowed, unsigned int timeout)
{
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout);
@@ -307,7 +312,7 @@ BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, siz
Count the messages pending for a particular pid. Expensive....
****************************************************************************/
-unsigned int messages_pending_for_pid(pid_t pid)
+unsigned int messages_pending_for_pid(struct process_id pid)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
@@ -349,7 +354,7 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
*msgs_buf = NULL;
*total_len = 0;
- kbuf = message_key_pid(sys_getpid());
+ kbuf = message_key_pid(pid_to_procid(sys_getpid()));
if (tdb_chainlock(tdb, kbuf) == -1)
return False;
@@ -377,7 +382,8 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
Parse out the next message for the current process.
****************************************************************************/
-static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t *src, char **buf, size_t *len)
+static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type,
+ struct process_id *src, char **buf, size_t *len)
{
struct message_rec rec;
char *ret_buf = *buf;
@@ -420,7 +426,7 @@ static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t
void message_dispatch(void)
{
int msg_type;
- pid_t src;
+ struct process_id src;
char *buf;
char *msgs_buf;
size_t len, total_len;
@@ -438,8 +444,9 @@ void message_dispatch(void)
return;
for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
- DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%u\n",
- msg_type, (unsigned int) src));
+ DEBUG(10,("message_dispatch: received msg_type=%d "
+ "src_pid=%u\n", msg_type,
+ (unsigned int) procid_to_pid(&src)));
n_handled = 0;
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
@@ -464,7 +471,8 @@ void message_dispatch(void)
****************************************************************************/
void message_register(int msg_type,
- void (*fn)(int msg_type, pid_t pid, void *buf, size_t len))
+ void (*fn)(int msg_type, struct process_id pid,
+ void *buf, size_t len))
{
struct dispatch_fns *dfn;
@@ -543,8 +551,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
/* If the pid was not found delete the entry from connections.tdb */
if (errno == ESRCH) {
- DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
- (unsigned int)crec.pid, crec.cnum, crec.name));
+ DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
+ procid_str_static(&crec.pid),
+ crec.cnum, crec.name));
tdb_delete(the_tdb, kbuf);
}
}
diff --git a/source3/lib/module.c b/source3/lib/module.c
index 49121d12ca..885faf8d80 100644
--- a/source3/lib/module.c
+++ b/source3/lib/module.c
@@ -231,77 +231,3 @@ void smb_run_idle_events(time_t now)
return;
}
-
-/***************************************************************************
- * This Function registers a exit event
- *
- * the registered functions are run on exit()
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-
-struct smb_exit_list_ent {
- struct smb_exit_list_ent *prev,*next;
- smb_event_id_t id;
- smb_exit_event_fn *fn;
- void *data;
-};
-
-static struct smb_exit_list_ent *smb_exit_event_list = NULL;
-
-smb_event_id_t smb_register_exit_event(smb_exit_event_fn *fn, void *data)
-{
- struct smb_exit_list_ent *event;
- static smb_event_id_t smb_exit_event_id = 1;
-
- if (!fn) {
- return SMB_EVENT_ID_INVALID;
- }
-
- event = SMB_MALLOC_P(struct smb_exit_list_ent);
- if (!event) {
- DEBUG(0,("malloc() failed!\n"));
- return SMB_EVENT_ID_INVALID;
- }
- event->fn = fn;
- event->data = data;
- event->id = smb_exit_event_id++;
-
- DLIST_ADD(smb_exit_event_list,event);
-
- return event->id;
-}
-
-BOOL smb_unregister_exit_event(smb_event_id_t id)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
-
- while(event) {
- if (event->id == id) {
- DLIST_REMOVE(smb_exit_event_list,event);
- SAFE_FREE(event);
- return True;
- }
- event = event->next;
- }
-
- return False;
-}
-
-void smb_run_exit_events(void)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
- struct smb_exit_list_ent *tmp = NULL;
-
- while (event) {
- event->fn(&event->data);
- tmp = event;
- event = event->next;
- /* exit event should only run one time :-)*/
- SAFE_FREE(tmp);
- }
-
- /* the list is empty now...*/
- smb_exit_event_list = NULL;
-
- return;
-}
diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c
index 20a8e82ce2..b041eb7f1b 100644
--- a/source3/lib/pidfile.c
+++ b/source3/lib/pidfile.c
@@ -57,7 +57,7 @@ pid_t pidfile_pid(const char *name)
goto noproc;
}
- if (!process_exists((pid_t)ret)) {
+ if (!process_exists_by_pid(ret)) {
goto noproc;
}
diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c
index d95c1ba4c1..ff0631b82f 100644
--- a/source3/lib/privileges.c
+++ b/source3/lib/privileges.c
@@ -397,6 +397,8 @@ static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set)
/*********************************************************************
Generate the LUID_ATTR structure based on a bitmask
+ The assumption here is that the privilege has already been validated
+ so we are guaranteed to find it in the list.
*********************************************************************/
LUID_ATTR get_privilege_luid( SE_PRIV *mask )
@@ -404,8 +406,7 @@ LUID_ATTR get_privilege_luid( SE_PRIV *mask )
LUID_ATTR priv_luid;
int i;
- priv_luid.attr = 0;
- priv_luid.luid.high = 0;
+ ZERO_STRUCT( priv_luid );
for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index cf7c8fc87f..f08a67a22c 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -267,7 +267,11 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return;
while ( list[i] ) {
- SAFE_FREE( list[i] );
+ /* SAFE_FREE generates a warning here that can't be gotten rid
+ * of with CONST_DISCARD */
+ if (list[i] != NULL) {
+ free(CONST_DISCARD(char *, list[i]));
+ }
i+=1;
}
diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c
index 798cb3fff7..4679b86487 100644
--- a/source3/lib/smbldap_util.c
+++ b/source3/lib/smbldap_util.c
@@ -27,6 +27,65 @@
#include "smbldap.h"
/**********************************************************************
+ Add the account-policies below the sambaDomain object to LDAP,
+*********************************************************************/
+static NTSTATUS add_new_domain_account_policies(struct smbldap_state *ldap_state,
+ const char *domain_name)
+{
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+ int i, rc;
+ uint32 policy_default;
+ const char *policy_attr = NULL;
+ pstring dn;
+ LDAPMod **mods = NULL;
+
+ DEBUG(3,("Adding new account policies for domain\n"));
+
+ pstr_sprintf(dn, "%s=%s,%s",
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ domain_name, lp_ldap_suffix());
+
+ for (i=1; decode_account_policy_name(i) != NULL; i++) {
+
+ pstring val;
+
+ policy_attr = get_account_policy_attr(i);
+ if (!policy_attr) {
+ DEBUG(0,("add_new_domain_account_policies: ops. no policy!\n"));
+ continue;
+ }
+
+ if (!account_policy_get_default(i, &policy_default)) {
+ DEBUG(0,("add_new_domain_account_policies: failed to get default account policy\n"));
+ return ntstatus;
+ }
+
+ DEBUG(10,("add_new_domain_account_policies: adding \"%s\" with value: %d\n", policy_attr, policy_default));
+
+ pstr_sprintf(val, "%d", policy_default);
+
+ smbldap_set_mod( &mods, LDAP_MOD_REPLACE, policy_attr, val);
+
+ rc = smbldap_modify(ldap_state, dn, mods);
+
+ if (rc!=LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(1,("failed to add account policies to dn= %s with: %s\n\t%s\n",
+ dn, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ ldap_mods_free(mods, True);
+ return ntstatus;
+ }
+ }
+
+ ldap_mods_free(mods, True);
+
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
Add the sambaDomain to LDAP, so we don't have to search for this stuff
again. This is a once-add operation for now.
@@ -200,6 +259,13 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
goto failed;
}
+ status = add_new_domain_account_policies(ldap_state, domain_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Adding domain account policies for %s failed with %s\n",
+ domain_name, nt_errstr(status)));
+ goto failed;
+ }
+
return smbldap_search_domain_info(ldap_state, result, domain_name, False);
}
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index 13e330dd97..6d6d7817f1 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -225,10 +225,16 @@ int smbrunsecret(const char *cmd, const char *secret)
*/
int status = 0;
pid_t wpid;
+ size_t towrite;
+ ssize_t wrote;
close(ifd[0]);
/* send the secret */
- write(ifd[1], secret, strlen(secret));
+ towrite = strlen(secret);
+ wrote = write(ifd[1], secret, towrite);
+ if ( wrote != towrite ) {
+ DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
+ }
fsync(ifd[1]);
close(ifd[1]);
diff --git a/source3/lib/tallocmsg.c b/source3/lib/tallocmsg.c
index 8ee3c257f6..8f03fd66ff 100644
--- a/source3/lib/tallocmsg.c
+++ b/source3/lib/tallocmsg.c
@@ -30,7 +30,7 @@
* Respond to a POOL_USAGE message by sending back string form of memory
* usage stats.
**/
-void msg_pool_usage(int msg_type, pid_t src_pid,
+void msg_pool_usage(int msg_type, struct process_id src_pid,
void *UNUSED(buf), size_t UNUSED(len))
{
off_t reply;
@@ -41,7 +41,7 @@ void msg_pool_usage(int msg_type, pid_t src_pid,
DEBUG(2,("Got POOL_USAGE\n"));
reply = talloc_total_size(NULL);
- fstr_sprintf(reply_str, "%lld", reply);
+ fstr_sprintf(reply_str, "%ld", (long)reply);
message_send_pid(src_pid, MSG_POOL_USAGE,
reply_str, strlen(reply_str)+1, True);
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 5e0f5646fc..385762e82c 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -783,6 +783,15 @@ BOOL nt_time_is_zero(NTTIME *nt)
}
/****************************************************************************
+ Check if two NTTIMEs are the same.
+****************************************************************************/
+
+BOOL nt_time_equals(NTTIME *nt1, NTTIME *nt2)
+{
+ return (nt1->high == nt2->high && nt1->low == nt2->low);
+}
+
+/****************************************************************************
Return a timeval difference in usec.
****************************************************************************/
@@ -792,6 +801,135 @@ SMB_BIG_INT usec_time_diff(const struct timeval *larget, const struct timeval *s
return (sec_diff * 1000000) + (SMB_BIG_INT)(larget->tv_usec - smallt->tv_usec);
}
+/*
+ return a timeval struct with the given elements
+*/
+struct timeval timeval_set(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv;
+ tv.tv_sec = secs;
+ tv.tv_usec = usecs;
+ return tv;
+}
+
+/*
+ return a zero timeval
+*/
+struct timeval timeval_zero(void)
+{
+ return timeval_set(0,0);
+}
+
+/*
+ return True if a timeval is zero
+*/
+BOOL timeval_is_zero(const struct timeval *tv)
+{
+ return tv->tv_sec == 0 && tv->tv_usec == 0;
+}
+
+/*
+ return a timeval for the current time
+*/
+struct timeval timeval_current(void)
+{
+ struct timeval tv;
+ GetTimeOfDay(&tv);
+ return tv;
+}
+
+/*
+ return a timeval ofs microseconds after tv
+*/
+struct timeval timeval_add(const struct timeval *tv,
+ uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv2 = *tv;
+ tv2.tv_sec += secs;
+ tv2.tv_usec += usecs;
+ tv2.tv_sec += tv2.tv_usec / 1000000;
+ tv2.tv_usec = tv2.tv_usec % 1000000;
+ return tv2;
+}
+
+/*
+ return the sum of two timeval structures
+*/
+struct timeval timeval_sum(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec);
+}
+
+/*
+ return a timeval secs/usecs into the future
+*/
+struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv = timeval_current();
+ return timeval_add(&tv, secs, usecs);
+}
+
+/*
+ compare two timeval structures.
+ Return -1 if tv1 < tv2
+ Return 0 if tv1 == tv2
+ Return 1 if tv1 > tv2
+*/
+int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return 1;
+ if (tv1->tv_sec < tv2->tv_sec) return -1;
+ if (tv1->tv_usec > tv2->tv_usec) return 1;
+ if (tv1->tv_usec < tv2->tv_usec) return -1;
+ return 0;
+}
+
+/*
+ return the difference between two timevals as a timeval
+ if tv1 comes after tv2, then return a zero timeval
+ (this is *tv2 - *tv1)
+*/
+struct timeval timeval_until(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ struct timeval t;
+ if (timeval_compare(tv1, tv2) >= 0) {
+ return timeval_zero();
+ }
+ t.tv_sec = tv2->tv_sec - tv1->tv_sec;
+ if (tv1->tv_usec > tv2->tv_usec) {
+ t.tv_sec--;
+ t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
+ } else {
+ t.tv_usec = tv2->tv_usec - tv1->tv_usec;
+ }
+ return t;
+}
+
+/*
+ return the lesser of two timevals
+*/
+struct timeval timeval_min(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec < tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec > tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec < tv2->tv_usec) return *tv1;
+ return *tv2;
+}
+
+/*
+ return the greater of two timevals
+*/
+struct timeval timeval_max(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec < tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec > tv2->tv_usec) return *tv1;
+ return *tv2;
+}
/****************************************************************************
convert ASN.1 GeneralizedTime string to unix-time
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3993892196..a5cfe95b66 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1404,12 +1404,22 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
Check if a process exists. Does this work on all unixes?
****************************************************************************/
-BOOL process_exists(pid_t pid)
+BOOL process_exists(const struct process_id pid)
{
+ if (!procid_is_local(&pid)) {
+ /* This *SEVERELY* needs fixing. */
+ return True;
+ }
+
/* Doing kill with a non-positive pid causes messages to be
* sent to places we don't want. */
- SMB_ASSERT(pid > 0);
- return(kill(pid,0) == 0 || errno != ESRCH);
+ SMB_ASSERT(pid.pid > 0);
+ return(kill(pid.pid,0) == 0 || errno != ESRCH);
+}
+
+BOOL process_exists_by_pid(pid_t pid)
+{
+ return process_exists(pid_to_procid(pid));
}
/*******************************************************************
@@ -2756,3 +2766,57 @@ uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
return (uint32)-1;
}
+
+pid_t procid_to_pid(const struct process_id *proc)
+{
+ return proc->pid;
+}
+
+struct process_id pid_to_procid(pid_t pid)
+{
+ struct process_id result;
+ result.pid = pid;
+ return result;
+}
+
+struct process_id procid_self(void)
+{
+ return pid_to_procid(sys_getpid());
+}
+
+BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
+{
+ return (p1->pid == p2->pid);
+}
+
+BOOL procid_is_me(const struct process_id *pid)
+{
+ return (pid->pid == sys_getpid());
+}
+
+struct process_id interpret_pid(const char *pid_string)
+{
+ return pid_to_procid(atoi(pid_string));
+}
+
+char *procid_str_static(const struct process_id *pid)
+{
+ static fstring str;
+ fstr_sprintf(str, "%d", pid->pid);
+ return str;
+}
+
+char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
+{
+ return talloc_strdup(mem_ctx, procid_str_static(pid));
+}
+
+BOOL procid_valid(const struct process_id *pid)
+{
+ return (pid->pid != -1);
+}
+
+BOOL procid_is_local(const struct process_id *pid)
+{
+ return True;
+}
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index 2cc6c6ebae..2e7866c055 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -2,6 +2,11 @@
Unix SMB/CIFS implementation.
kerberos authorization data (PAC) utility library
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Luke Howard 2002-2003
+ Copyright (C) Stefan Metzmacher 2004-2005
+ Copyright (C) Guenther Deschner 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,27 +27,6 @@
#ifdef HAVE_KRB5
-static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
-{
- DATA_BLOB pac_contents;
- ASN1_DATA data;
- int data_type;
-
- asn1_load(&data, *auth_data);
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_CONTEXT(0));
- asn1_read_Integer(&data, &data_type);
- asn1_end_tag(&data);
- asn1_start_tag(&data, ASN1_CONTEXT(1));
- asn1_read_OctetString(&data, &pac_contents);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_free(&data);
- return pac_contents;
-}
-
static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name,
prs_struct *ps, int depth)
{
@@ -75,6 +59,8 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name,
}
+
+#if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */
static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
prs_struct *ps, int depth)
{
@@ -159,6 +145,7 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc,
return True;
}
+#endif
static BOOL pac_io_group_membership(const char *desc,
GROUP_MEMBERSHIP *membership,
@@ -216,27 +203,34 @@ static BOOL pac_io_group_membership_array(const char *desc,
}
+#if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */
static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
prs_struct *ps, int depth)
{
- uint32 garbage;
+ uint32 garbage, i;
+
if (NULL == info)
return False;
prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
depth++;
- if (!prs_uint32("unknown", ps, depth, &garbage))
+ if (!prs_align(ps))
return False;
- if (!prs_uint32("unknown", ps, depth, &garbage))
+ if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */
+ return False;
+ if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */
return False;
if (!prs_uint32("bufferlen", ps, depth, &garbage))
return False;
- if (!prs_uint32("bufferlenhi", ps, depth, &garbage))
+ if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */
return False;
+
if (!prs_uint32("pointer", ps, depth, &garbage))
return False;
+ if (!prs_align(ps))
+ return False;
if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
return False;
if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
@@ -270,7 +264,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
return False;
- if (!prs_uint16("reserved12", ps, depth, &info->reserved12))
+ if (!prs_uint16("bad_password_count", ps, depth, &info->bad_password_count))
return False;
if (!prs_uint32("user_rid", ps, depth, &info->user_rid))
return False;
@@ -287,13 +281,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
if (!prs_uint32("user_flags", ps, depth, &info->user_flags))
return False;
- if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0]))
- return False;
- if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1]))
- return False;
- if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2]))
- return False;
- if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3]))
+ if (!prs_uint8s(False, "session_key", ps, depth, info->session_key, 16))
return False;
if (!smb_io_unihdr("hdr_dom_controller",
@@ -306,30 +294,17 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid))
return False;
- if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0]))
- return False;
- if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1]))
+ if (!prs_uint8s(False, "lm_session_key", ps, depth, info->lm_session_key, 8))
return False;
- /* might be acb_info */
- if (!prs_uint32("reserved17", ps, depth, &info->reserved17))
+ if (!prs_uint32("acct_flags", ps, depth, &info->acct_flags))
return False;
-
- if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0]))
- return False;
- if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1]))
- return False;
- if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2]))
- return False;
- if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3]))
- return False;
- if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4]))
- return False;
- if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5]))
- return False;
- if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6]))
- return False;
+ for (i = 0; i < 7; i++)
+ {
+ if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */
+ return False;
+ }
if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
return False;
@@ -395,44 +370,109 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
&info->res_group_dom_sid, ps, depth))
return False;
- if (info->ptr_res_groups)
+ if (info->ptr_res_groups) {
+
+ if (!(info->user_flgs & LOGON_RESOURCE_GROUPS)) {
+ DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n"));
+ /* return False; */
+ }
+
if (!pac_io_group_membership_array("res group membership",
&info->res_groups,
info->res_group_count,
ps, depth))
return False;
+ }
+
+ return True;
+}
+#endif
+
+static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
+ prs_struct *ps, int depth)
+{
+ uint32 garbage;
+ BOOL kerb_validation_info = True;
+
+ if (NULL == info)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */
+ return False;
+ if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */
+ return False;
+ if (!prs_uint32("bufferlen", ps, depth, &garbage))
+ return False;
+ if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */
+ return False;
+
+ if(!net_io_user_info3("", &info->info3, ps, depth, 3, kerb_validation_info))
+ return False;
+
+ if (info->info3.ptr_res_group_dom_sid) {
+ if (!smb_io_dom_sid2("res_group_dom_sid",
+ &info->res_group_dom_sid, ps, depth))
+ return False;
+ }
+
+ if (info->info3.ptr_res_groups) {
+
+ if (!(info->info3.user_flgs & LOGON_RESOURCE_GROUPS)) {
+ DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n"));
+ /* return False; */
+ }
+
+ if (!pac_io_group_membership_array("res group membership",
+ &info->res_groups,
+ info->info3.res_group_count,
+ ps, depth))
+ return False;
+ }
return True;
}
+
static BOOL pac_io_pac_signature_data(const char *desc,
PAC_SIGNATURE_DATA *data, uint32 length,
prs_struct *ps, int depth)
{
uint32 siglen = length - sizeof(uint32);
- if (NULL == data)
- return False;
-
prs_debug(ps, depth, desc, "pac_io_pac_signature_data");
depth++;
+
+ if (data == NULL)
+ return False;
+ if (!prs_align(ps))
+ return False;
if (!prs_uint32("type", ps, depth, &data->type))
return False;
- if (UNMARSHALLING(ps)) {
- data->signature = PRS_ALLOC_MEM(ps, unsigned char, siglen);
- if (!data->signature) {
+
+ if (UNMARSHALLING(ps) && length) {
+ data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen);
+ if (!data->signature.buffer) {
DEBUG(3, ("No memory available\n"));
return False;
}
}
- if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen))
+
+ data->signature.buf_len = siglen;
+
+ if (!prs_uint8s(False, "signature", ps, depth, data->signature.buffer, data->signature.buf_len))
return False;
+
return True;
}
-static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
+static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr,
prs_struct *ps, int depth)
{
if (NULL == hdr)
@@ -445,8 +485,8 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
return False;
if (hdr->offset != prs_offset(ps)) {
- DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
- hdr->offset, prs_offset(ps)));
+ DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n",
+ hdr->offset, prs_offset(ps)));
prs_set_offset(ps, hdr->offset);
}
@@ -518,10 +558,15 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
prs_set_offset(ps, prs_offset(ps) + hdr->size);
}
+#if 0
+ /* obscure pad */
+ if (!prs_uint32("pad", ps, depth, &hdr->pad))
+ return False;
+#endif
return True;
}
-static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr,
+static BOOL pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr,
prs_struct *ps, int depth)
{
if (NULL == hdr)
@@ -563,19 +608,19 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
return False;
if (UNMARSHALLING(ps) && data->num_buffers > 0) {
- if ((data->pac_info_hdr_ptr = PRS_ALLOC_MEM(ps, PAC_INFO_HDR, data->num_buffers)) == NULL) {
+ if ((data->pac_buffer = PRS_ALLOC_MEM(ps, PAC_BUFFER, data->num_buffers)) == NULL) {
return False;
}
}
for (i=0; i<data->num_buffers; i++) {
- if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps,
+ if (!pac_io_pac_info_hdr(desc, &data->pac_buffer[i], ps,
depth))
return False;
}
for (i=0; i<data->num_buffers; i++) {
- if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i],
+ if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_buffer[i],
ps, depth))
return False;
}
@@ -583,25 +628,300 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
return True;
}
-PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
+static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
+ DATA_BLOB pac_data,
+ PAC_SIGNATURE_DATA *sig,
+ krb5_context context,
+ krb5_keyblock *keyblock)
+{
+ krb5_error_code ret;
+ krb5_checksum cksum;
+ krb5_keyusage usage = 0;
+
+ smb_krb5_checksum_from_pac_sig(&cksum, sig);
+
+#ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */
+ usage = KRB5_KU_OTHER_CKSUM;
+#elif defined(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM) /* MIT */
+ usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;
+#else
+#error UNKNOWN_KRB5_KEYUSAGE
+#endif
+
+ ret = smb_krb5_verify_checksum(context,
+ keyblock,
+ usage,
+ &cksum,
+ pac_data.data,
+ pac_data.length);
+
+ if (ret) {
+ DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n",
+ error_message(ret), ret));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS parse_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, PAC_DATA *pac_data)
{
- DATA_BLOB pac_data_blob = unwrap_pac(auth_data);
prs_struct ps;
- PAC_DATA *pac_data;
+ PAC_DATA *my_pac;
- DEBUG(5,("dump_pac_data\n"));
- prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
- prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
- prs_set_offset(&ps, 0);
+ if (!prs_init(&ps, pac_data_blob->length, mem_ctx, UNMARSHALL))
+ return NT_STATUS_NO_MEMORY;
- data_blob_free(&pac_data_blob);
+ if (!prs_copy_data_in(&ps, (char *)pac_data_blob->data, pac_data_blob->length))
+ return NT_STATUS_INVALID_PARAMETER;
+
+ prs_set_offset(&ps, 0);
- pac_data = TALLOC_ZERO_P(ctx, PAC_DATA);
- pac_io_pac_data("pac data", pac_data, &ps, 0);
+ my_pac = TALLOC_ZERO_P(mem_ctx, PAC_DATA);
+ if (!pac_io_pac_data("pac data", my_pac, &ps, 0))
+ return NT_STATUS_INVALID_PARAMETER;
prs_mem_free(&ps);
- return pac_data;
+ *pac_data = *my_pac;
+
+ return NT_STATUS_OK;
+}
+
+/* just for debugging, will be removed later - Guenther */
+char *pac_group_attr_string(uint32 attr)
+{
+ fstring name = "";
+
+ if (!attr)
+ return NULL;
+
+ if (attr & SE_GROUP_MANDATORY) fstrcat(name, "SE_GROUP_MANDATORY ");
+ if (attr & SE_GROUP_ENABLED_BY_DEFAULT) fstrcat(name, "SE_GROUP_ENABLED_BY_DEFAULT ");
+ if (attr & SE_GROUP_ENABLED) fstrcat(name, "SE_GROUP_ENABLED ");
+ if (attr & SE_GROUP_OWNER) fstrcat(name, "SE_GROUP_OWNER ");
+ if (attr & SE_GROUP_USE_FOR_DENY_ONLY) fstrcat(name, "SE_GROUP_USE_FOR_DENY_ONLY ");
+ if (attr & SE_GROUP_LOGON_ID) fstrcat(name, "SE_GROUP_LOGON_ID ");
+ if (attr & SE_GROUP_RESOURCE) fstrcat(name, "SE_GROUP_RESOURCE ");
+
+ return SMB_STRDUP(name);
+}
+
+/* just for debugging, will be removed later - Guenther */
+static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) {
+
+ DOM_SID dom_sid, res_group_dom_sid;
+ int i;
+ char *attr_string;
+ uint32 user_flgs = logon_info->info3.user_flgs;
+
+ if (logon_info->info3.ptr_res_group_dom_sid) {
+ sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid);
+ }
+ sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid);
+
+ DEBUG(10,("The PAC:\n"));
+
+ DEBUGADD(10,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs));
+ if (user_flgs & LOGON_EXTRA_SIDS)
+ DEBUGADD(10,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS));
+ if (user_flgs & LOGON_RESOURCE_GROUPS)
+ DEBUGADD(10,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS));
+ DEBUGADD(10,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid));
+ DEBUGADD(10,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid));
+
+ DEBUGADD(10,("\tGroup Membership (Global and Universal Groups of own domain):\n"));
+ for (i = 0; i < logon_info->info3.num_groups; i++) {
+ attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr);
+ DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n",
+ i, sid_string_static(&dom_sid),
+ logon_info->info3.gids[i].g_rid,
+ logon_info->info3.gids[i].attr,
+ attr_string));
+ SAFE_FREE(attr_string);
+ }
+
+ DEBUGADD(10,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n"));
+ for (i = 0; i < logon_info->info3.num_other_sids; i++) {
+ attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]);
+ DEBUGADD(10,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n",
+ i, sid_string_static(&logon_info->info3.other_sids[i].sid),
+ logon_info->info3.other_sids_attrib[i],
+ attr_string));
+ SAFE_FREE(attr_string);
+ }
+
+ DEBUGADD(10,("\tGroup Membership (Ressource Groups (SID History ?)):\n"));
+ for (i = 0; i < logon_info->info3.res_group_count; i++) {
+ attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs);
+ DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n",
+ i, sid_string_static(&res_group_dom_sid),
+ logon_info->res_groups.group_membership[i].rid,
+ logon_info->res_groups.group_membership[i].attrs,
+ attr_string));
+ SAFE_FREE(attr_string);
+ }
+}
+
+NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
+ DATA_BLOB *pac_data_blob,
+ krb5_context context,
+ krb5_keyblock *service_keyblock,
+ krb5_const_principal client_principal,
+ time_t tgs_authtime,
+ PAC_DATA **pac_data)
+
+{
+ DATA_BLOB modified_pac_blob;
+ PAC_DATA *my_pac;
+ NTSTATUS nt_status;
+ krb5_error_code ret;
+ PAC_SIGNATURE_DATA *srv_sig = NULL;
+ PAC_SIGNATURE_DATA *kdc_sig = NULL;
+ PAC_LOGON_NAME *logon_name = NULL;
+ PAC_LOGON_INFO *logon_info = NULL;
+ krb5_principal client_principal_pac;
+ NTTIME tgs_authtime_nttime;
+ int i, srv_sig_pos = 0, kdc_sig_pos = 0;
+ fstring username;
+
+ *pac_data = NULL;
+
+ my_pac = talloc(mem_ctx, PAC_DATA);
+ if (!my_pac) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nt_status = parse_pac_data(mem_ctx, pac_data_blob, my_pac);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("decode_pac_data: failed to parse PAC\n"));
+ return nt_status;
+ }
+
+ modified_pac_blob = data_blob_talloc(mem_ctx, pac_data_blob->data, pac_data_blob->length);
+
+ if (my_pac->num_buffers < 4) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* store signatures */
+ for (i=0; i < my_pac->num_buffers; i++) {
+
+ switch (my_pac->pac_buffer[i].type) {
+
+ case PAC_TYPE_SERVER_CHECKSUM:
+ if (!my_pac->pac_buffer[i].ctr->pac.srv_cksum) {
+ break;
+ }
+
+ srv_sig = my_pac->pac_buffer[i].ctr->pac.srv_cksum;
+
+ /* get position of signature buffer */
+ srv_sig_pos = my_pac->pac_buffer[i].offset;
+ srv_sig_pos += sizeof(uint32);
+
+ break;
+
+ case PAC_TYPE_PRIVSVR_CHECKSUM:
+ if (!my_pac->pac_buffer[i].ctr->pac.privsrv_cksum) {
+ break;
+ }
+
+ kdc_sig = my_pac->pac_buffer[i].ctr->pac.privsrv_cksum;
+
+ /* get position of signature buffer */
+ kdc_sig_pos = my_pac->pac_buffer[i].offset;
+ kdc_sig_pos += sizeof(uint32);
+
+ break;
+
+ case PAC_TYPE_LOGON_NAME:
+ if (!my_pac->pac_buffer[i].ctr->pac.logon_name) {
+ break;
+ }
+
+ logon_name = my_pac->pac_buffer[i].ctr->pac.logon_name;
+ break;
+
+ case PAC_TYPE_LOGON_INFO:
+ if (!my_pac->pac_buffer[i].ctr->pac.logon_info) {
+ break;
+ }
+
+ logon_info = my_pac->pac_buffer[i].ctr->pac.logon_info;
+ break;
+ }
+
+ }
+
+ if (!srv_sig || !kdc_sig || !logon_name || !logon_info) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* zero PAC_SIGNATURE_DATA signature buffer */
+ memset(&modified_pac_blob.data[srv_sig_pos], '\0', srv_sig->signature.buf_len);
+ memset(&modified_pac_blob.data[kdc_sig_pos], '\0', kdc_sig->signature.buf_len);
+
+ /* check server signature */
+ nt_status = check_pac_checksum(mem_ctx, modified_pac_blob, srv_sig, context, service_keyblock);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("decode_pac_data: failed to verify PAC server signature\n"));
+ goto out;
+ }
+
+ /* Convert to NT time, so as not to loose accuracy in comparison */
+ unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
+
+ if (!nt_time_equals(&tgs_authtime_nttime, &logon_name->logon_time)) {
+
+ DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n"));
+ DEBUGADD(2, ("decode_pac_data: PAC: %s\n",
+ http_timestring(nt_time_to_unix(&logon_name->logon_time))));
+ DEBUGADD(2, ("decode_pac_data: Ticket: %s\n",
+ http_timestring(nt_time_to_unix(&tgs_authtime_nttime))));
+
+ nt_status = NT_STATUS_ACCESS_DENIED;
+ goto out;
+ }
+
+ if (!logon_name->len) {
+ DEBUG(2,("decode_pac_data: No Logon Name available\n"));
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE);
+
+ ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac);
+ if (ret) {
+ DEBUG(2,("decode_pac_data: Could not parse name from incoming PAC: [%s]: %s\n",
+ username, error_message(ret)));
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) {
+ DEBUG(2,("decode_pac_data: Name in PAC [%s] does not match principal name in ticket\n",
+ username));
+ nt_status = NT_STATUS_ACCESS_DENIED;
+ goto out;
+ }
+
+ DEBUG(10,("Successfully validated Kerberos PAC\n"));
+
+ dump_pac_logon_info(logon_info);
+
+ *pac_data = my_pac;
+
+ nt_status = NT_STATUS_OK;
+
+out:
+ if (client_principal_pac) {
+ krb5_free_principal(context, client_principal_pac);
+ }
+
+ return nt_status;
}
#endif
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index 770d129e5d..6a5c6b6a49 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -4,8 +4,9 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Remus Koos 2001
Copyright (C) Luke Howard 2003
- Copyright (C) Guenther Deschner 2003
+ Copyright (C) Guenther Deschner 2003, 2005
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-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
@@ -37,7 +38,8 @@ const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int );
***********************************************************************************/
static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context,
- const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt)
+ const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt,
+ krb5_keyblock **keyblock)
{
krb5_error_code ret = 0;
BOOL auth_ok = False;
@@ -100,12 +102,18 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
p_packet->length = ticket->length;
p_packet->data = (krb5_pointer)ticket->data;
*pp_tkt = NULL;
- ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt);
+
+ ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet,
+ kt_entry.principal, keytab,
+ NULL, pp_tkt, keyblock);
+
if (ret) {
- DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n",
+ DEBUG(10,("ads_keytab_verify_ticket: "
+ "krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n",
entry_princ_s, error_message(ret)));
} else {
- DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n",
+ DEBUG(3,("ads_keytab_verify_ticket: "
+ "krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n",
entry_princ_s));
auth_ok = True;
break;
@@ -172,8 +180,9 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
***********************************************************************************/
static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context,
- krb5_principal host_princ,
- const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt)
+ krb5_principal host_princ,
+ const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt,
+ krb5_keyblock **keyblock)
{
krb5_error_code ret = 0;
BOOL auth_ok = False;
@@ -182,6 +191,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
krb5_enctype *enctypes = NULL;
int i;
+ ZERO_STRUCTP(keyblock);
+
if (!secrets_init()) {
DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n"));
return False;
@@ -222,20 +233,23 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
krb5_auth_con_setuseruserkey(context, auth_context, key);
- krb5_free_keyblock(context, key);
-
if (!(ret = krb5_rd_req(context, &auth_context, p_packet,
NULL,
NULL, NULL, pp_tkt))) {
DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n",
(unsigned int)enctypes[i] ));
auth_ok = True;
+ krb5_copy_keyblock(context, key, keyblock);
+ krb5_free_keyblock(context, key);
break;
}
DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
(unsigned int)enctypes[i], error_message(ret)));
+
+ krb5_free_keyblock(context, key);
+
}
out:
@@ -251,27 +265,33 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
authorization_data if available.
***********************************************************************************/
-NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
- char **principal, DATA_BLOB *auth_data,
+NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
+ const char *realm, const DATA_BLOB *ticket,
+ char **principal, PAC_DATA **pac_data,
DATA_BLOB *ap_rep,
DATA_BLOB *session_key)
{
NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
+ DATA_BLOB auth_data;
krb5_context context = NULL;
krb5_auth_context auth_context = NULL;
krb5_data packet;
krb5_ticket *tkt = NULL;
krb5_rcache rcache = NULL;
+ krb5_keyblock *keyblock = NULL;
+ time_t authtime;
int ret;
krb5_principal host_princ = NULL;
+ krb5_const_principal client_principal = NULL;
char *host_princ_s = NULL;
BOOL got_replay_mutex = False;
BOOL auth_ok = False;
+ BOOL got_auth_data = False;
ZERO_STRUCT(packet);
- ZERO_STRUCTP(auth_data);
+ ZERO_STRUCT(auth_data);
ZERO_STRUCTP(ap_rep);
ZERO_STRUCTP(session_key);
@@ -335,20 +355,30 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
}
if (lp_use_kerberos_keytab()) {
- auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt);
+ auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock);
}
if (!auth_ok) {
auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ,
- ticket, &packet, &tkt);
+ ticket, &packet, &tkt, &keyblock);
}
release_server_mutex();
got_replay_mutex = False;
+#if 0
+ /* Heimdal leaks here, if we fix the leak, MIT crashes */
+ if (rcache) {
+ krb5_rc_close(context, rcache);
+ }
+#endif
+
if (!auth_ok) {
DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
error_message(ret)));
goto out;
+ } else {
+ authtime = get_authtime_from_tkt(tkt);
+ client_principal = get_principal_from_tkt(tkt);
}
ret = krb5_mk_rep(context, auth_context, &packet);
@@ -369,20 +399,40 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
#endif
- get_auth_data_from_tkt(auth_data, tkt);
+ /* continue when no PAC is retrieved
+ (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set) */
- {
- TALLOC_CTX *ctx = talloc_init("pac data");
- decode_pac_data(auth_data, ctx);
- talloc_destroy(ctx);
+ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt);
+ if (!got_auth_data) {
+ DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n"));
+ }
+
+ if (got_auth_data && pac_data != NULL) {
+
+ sret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data);
+ if (!NT_STATUS_IS_OK(sret)) {
+ DEBUG(0,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(sret)));
+ goto out;
+ }
+ data_blob_free(&auth_data);
}
#if 0
+#if defined(HAVE_KRB5_TKT_ENC_PART2)
+ /* MIT */
if (tkt->enc_part2) {
file_save("/tmp/authdata.dat",
tkt->enc_part2->authorization_data[0]->contents,
tkt->enc_part2->authorization_data[0]->length);
}
+#else
+ /* Heimdal */
+ if (tkt->ticket.authorization_data) {
+ file_save("/tmp/authdata.dat",
+ tkt->ticket.authorization_data->val->ad_data.data,
+ tkt->ticket.authorization_data->val->ad_data.length);
+ }
+#endif
#endif
if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
@@ -402,7 +452,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
}
if (!NT_STATUS_IS_OK(sret)) {
- data_blob_free(auth_data);
+ data_blob_free(&auth_data);
}
if (!NT_STATUS_IS_OK(sret)) {
@@ -413,6 +463,10 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
krb5_free_principal(context, host_princ);
}
+ if (keyblock) {
+ krb5_free_keyblock(context, keyblock);
+ }
+
if (tkt != NULL) {
krb5_free_ticket(context, tkt);
}
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 81afd7f49e..bf402b3499 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -2104,7 +2104,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
if ((*num_strings) != range_start) {
DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu"
" - aborting range retreival\n",
- range_attr, *num_strings + 1, range_start));
+ range_attr, (unsigned int)(*num_strings) + 1, range_start));
ldap_memfree(range_attr);
*more_strings = False;
return NULL;
@@ -2140,7 +2140,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
*next_attribute = talloc_asprintf(mem_ctx,
"%s;range=%d-*",
field,
- *num_strings);
+ (int)*num_strings);
if (!*next_attribute) {
DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c
index db544fe209..d6ac09d22b 100644
--- a/source3/libads/ldap_printer.c
+++ b/source3/libads/ldap_printer.c
@@ -258,7 +258,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
}
-WERROR get_remote_printer_publishing_data(struct cli_state *cli,
+WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
ADS_MODLIST *mods,
const char *printer)
@@ -269,16 +269,16 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
uint32 i;
POLICY_HND pol;
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
asprintf(&printername, "%s\\%s", servername, printer);
if (!servername || !printername) {
DEBUG(3, ("Insufficient memory\n"));
return WERR_NOMEM;
}
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
- servername, cli->user_name, &pol);
+ servername, cli->cli->user_name, &pol);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Unable to open printer %s, error is %s.\n",
printername, dos_errstr(result)));
@@ -288,7 +288,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
+ result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
@@ -305,7 +305,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
+ result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
if (!W_ERROR_IS_OK(result)) {
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
@@ -323,7 +323,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
TALLOC_FREE( dsdriver_ctr );
TALLOC_FREE( dsspooler_ctr );
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 8fa62a5ade..72cbf7264e 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -142,7 +142,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
DATA_BLOB session_key = data_blob(NULL, 0);
int rc;
- rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key);
+ rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0);
if (rc) {
return ADS_ERROR_KRB5(rc);
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 3d8e36c493..7ecc769517 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -532,7 +532,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
DEBUG(2,("Doing kerberos session setup\n"));
/* generate the encapsulated kerberos5 ticket */
- rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5);
+ rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0);
if (rc) {
DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc)));
@@ -600,7 +600,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
nt_status = ntlmssp_update(ntlmssp_state,
blob_in, &blob_out);
data_blob_free(&blob_in);
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
if (turn == 1) {
/* and wrap it in a SPNEGO wrapper */
msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
@@ -1337,25 +1337,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
return True;
}
-/****************************************************************************
- Initialise client credentials for authenticated pipe access.
-****************************************************************************/
-
-void init_creds(struct ntuser_creds *creds, const char* username,
- const char* domain, const char* password)
-{
- ZERO_STRUCTP(creds);
-
- pwd_set_cleartext(&creds->pwd, password);
-
- fstrcpy(creds->user_name, username);
- fstrcpy(creds->domain, domain);
-
- if (!*username) {
- creds->pwd.null_pwd = True;
- }
-}
-
/**
establishes a connection to after the negprot.
@param output_cli A fully initialised cli structure, non-null only on success
@@ -1474,7 +1455,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
int signing_state,
BOOL *retry)
{
- struct ntuser_creds creds;
NTSTATUS nt_status;
struct cli_state *cli = NULL;
@@ -1513,8 +1493,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
}
}
- init_creds(&creds, user, domain, password);
- cli_init_creds(cli, &creds);
+ cli_init_creds(cli, user, domain, password);
*output_cli = cli;
return NT_STATUS_OK;
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 819616105e..dfb613238f 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -101,7 +101,7 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot,
DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name),
inet_ntoa(dest_ip)));
- return message_send_pid(nmbd_pid, MSG_SEND_PACKET, &p, sizeof(p),
+ return message_send_pid(pid_to_procid(nmbd_pid), MSG_SEND_PACKET, &p, sizeof(p),
False);
}
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index f1794ab5dc..bc64cc919b 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -221,15 +221,16 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
Initialise credentials of a client structure.
****************************************************************************/
-void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
+void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
{
- /* copy_nt_creds(&cli->usr, usr); */
- fstrcpy(cli->domain , usr->domain);
- fstrcpy(cli->user_name, usr->user_name);
- memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd));
+ fstrcpy(cli->domain, domain);
+ fstrcpy(cli->user_name, username);
+ pwd_set_cleartext(&cli->pwd, password);
+ if (!*username) {
+ cli->pwd.null_pwd = True;
+ }
- DEBUG(10,("cli_init_creds: user %s domain %s\n",
- cli->user_name, cli->domain));
+ DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
}
/****************************************************************************
@@ -260,7 +261,6 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state)
struct cli_state *cli_initialise(struct cli_state *cli)
{
BOOL alloced_cli = False;
- int i;
/* Check the effective uid - make sure we are not setuid */
if (is_setuid_root()) {
@@ -332,16 +332,9 @@ struct cli_state *cli_initialise(struct cli_state *cli)
/* initialise signing */
cli_null_set_signing(cli);
- for (i=0; i<PI_MAX_PIPES; i++)
- cli->pipes[i].fnum = 0;
-
- cli->netlogon_pipe.fnum = 0;
-
cli->initialised = 1;
cli->allocated = alloced_cli;
- cli->pipe_idx = -1;
-
return cli;
/* Clean up after malloc() error */
@@ -358,34 +351,42 @@ struct cli_state *cli_initialise(struct cli_state *cli)
}
/****************************************************************************
-close the session
-****************************************************************************/
+ External interface.
+ Close an open named pipe over SMB. Free any authentication data.
+ ****************************************************************************/
-void cli_nt_session_close(struct cli_state *cli)
+void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
{
- int i;
-
- for (i=0; i<PI_MAX_PIPES; i++) {
- if (cli->pipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state);
- }
+ if (!cli_close(cli->cli, cli->fnum)) {
+ DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
+ "to machine %s. Error was %s\n",
+ cli->pipe_name,
+ cli->cli->desthost,
+ cli_errstr(cli->cli)));
+ }
- if (cli->pipes[i].fnum != 0)
- cli_close(cli, cli->pipes[i].fnum);
- cli->pipes[i].fnum = 0;
+ if (cli->auth.cli_auth_data_free_func) {
+ (*cli->auth.cli_auth_data_free_func)(&cli->auth);
}
- cli->pipe_idx = -1;
+
+ DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
+ cli->pipe_name, cli->cli->desthost ));
+
+ DLIST_REMOVE(cli->cli->pipe_list, cli);
+ talloc_destroy(cli->mem_ctx);
}
/****************************************************************************
-close the NETLOGON session holding the session key for NETSEC
+ Close all pipes open on this session.
****************************************************************************/
-void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
+void cli_nt_pipes_close(struct cli_state *cli)
{
- if (cli->netlogon_pipe.fnum != 0) {
- cli_close(cli, cli->netlogon_pipe.fnum);
- cli->netlogon_pipe.fnum = 0;
+ struct rpc_pipe_client *cp, *next;
+
+ for (cp = cli->pipe_list; cp; cp = next) {
+ next = cp->next;
+ cli_rpc_pipe_close(cp);
}
}
@@ -395,8 +396,7 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
void cli_close_connection(struct cli_state *cli)
{
- cli_nt_session_close(cli);
- cli_nt_netlogon_netsec_session_close(cli);
+ cli_nt_pipes_close(cli);
/*
* tell our peer to free his resources. Wihtout this, when an
@@ -410,8 +410,9 @@ void cli_close_connection(struct cli_state *cli)
* the only user for this so far is smbmount which passes opened connection
* down to kernel's smbfs module.
*/
- if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) )
+ if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) {
cli_tdis(cli);
+ }
SAFE_FREE(cli->outbuf);
SAFE_FREE(cli->inbuf);
@@ -420,19 +421,16 @@ void cli_close_connection(struct cli_state *cli)
data_blob_free(&cli->secblob);
data_blob_free(&cli->user_session_key);
- if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP)
- ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state);
-
if (cli->mem_ctx) {
talloc_destroy(cli->mem_ctx);
cli->mem_ctx = NULL;
}
- if (cli->fd != -1)
+ if (cli->fd != -1) {
close(cli->fd);
+ }
cli->fd = -1;
cli->smb_rw_error = 0;
-
}
/****************************************************************************
@@ -444,8 +442,9 @@ void cli_shutdown(struct cli_state *cli)
BOOL allocated = cli->allocated;
cli_close_connection(cli);
ZERO_STRUCTP(cli);
- if (allocated)
+ if (allocated) {
free(cli);
+ }
}
/****************************************************************************
diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c
index 355a2adf34..6938702e1e 100644
--- a/source3/libsmb/clierror.c
+++ b/source3/libsmb/clierror.c
@@ -404,3 +404,20 @@ BOOL cli_is_dos_error(struct cli_state *cli)
return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES);
}
+
+/* Return the last error always as an NTSTATUS. */
+
+NTSTATUS cli_get_nt_error(struct cli_state *cli)
+{
+ if (cli_is_nt_error(cli)) {
+ return cli_nt_error(cli);
+ } else if (cli_is_dos_error(cli)) {
+ uint32 ecode;
+ uint8 eclass;
+ cli_dos_error(cli, &eclass, &ecode);
+ return dos_to_ntstatus(eclass, ecode);
+ } else {
+ /* Something went wrong, we don't know what. */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+}
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index 1741c1db3c..e3ad5f17cb 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -3,6 +3,8 @@
simple kerberos5 routines for active directory
Copyright (C) Andrew Tridgell 2001
Copyright (C) Luke Howard 2002-2003
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
+ Copyright (C) Guenther Deschner 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
@@ -186,17 +188,107 @@
}
#endif
- void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt)
+BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data)
{
+ DATA_BLOB pac_contents;
+ ASN1_DATA data;
+ int data_type;
+
+ if (!auth_data->length) {
+ return False;
+ }
+
+ asn1_load(&data, *auth_data);
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_CONTEXT(0));
+ asn1_read_Integer(&data, &data_type);
+
+ if (data_type != KRB5_AUTHDATA_WIN2K_PAC ) {
+ DEBUG(10,("authorization data is not a Windows PAC (type: %d)\n", data_type));
+ asn1_free(&data);
+ return False;
+ }
+
+ asn1_end_tag(&data);
+ asn1_start_tag(&data, ASN1_CONTEXT(1));
+ asn1_read_OctetString(&data, &pac_contents);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_free(&data);
+
+ *unwrapped_pac_data = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length);
+
+ data_blob_free(&pac_contents);
+
+ return True;
+}
+
+ BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt)
+{
+ DATA_BLOB auth_data_wrapped;
+ BOOL got_auth_data_pac = False;
+ int i;
+
#if defined(HAVE_KRB5_TKT_ENC_PART2)
- if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length)
- *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
- tkt->enc_part2->authorization_data[0]->length);
+ if (tkt->enc_part2 && tkt->enc_part2->authorization_data &&
+ tkt->enc_part2->authorization_data[0] &&
+ tkt->enc_part2->authorization_data[0]->length)
+ {
+ for (i = 0; tkt->enc_part2->authorization_data[i] != NULL; i++) {
+
+ if (tkt->enc_part2->authorization_data[i]->ad_type !=
+ KRB5_AUTHDATA_IF_RELEVANT) {
+ DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
+ tkt->enc_part2->authorization_data[i]->ad_type));
+ continue;
+ }
+
+ auth_data_wrapped = data_blob(tkt->enc_part2->authorization_data[i]->contents,
+ tkt->enc_part2->authorization_data[i]->length);
+
+ /* check if it is a PAC */
+ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
+ data_blob_free(&auth_data_wrapped);
+
+ if (!got_auth_data_pac) {
+ continue;
+ }
+ }
+
+ return got_auth_data_pac;
+ }
+
#else
- if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len)
- *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data,
- tkt->ticket.authorization_data->val->ad_data.length);
+ if (tkt->ticket.authorization_data &&
+ tkt->ticket.authorization_data->len)
+ {
+ for (i = 0; i < tkt->ticket.authorization_data->len; i++) {
+
+ if (tkt->ticket.authorization_data->val[i].ad_type !=
+ KRB5_AUTHDATA_IF_RELEVANT) {
+ DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
+ tkt->ticket.authorization_data->val[i].ad_type));
+ continue;
+ }
+
+ auth_data_wrapped = data_blob(tkt->ticket.authorization_data->val[i].ad_data.data,
+ tkt->ticket.authorization_data->val[i].ad_data.length);
+
+ /* check if it is a PAC */
+ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
+ data_blob_free(&auth_data_wrapped);
+
+ if (!got_auth_data_pac) {
+ continue;
+ }
+ }
+
+ return got_auth_data_pac;
+ }
#endif
+ return False;
}
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt)
@@ -435,7 +527,7 @@ cleanup_princ:
get a kerberos5 ticket for the given service
*/
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
- DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
+ DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
{
krb5_error_code retval;
krb5_data packet;
@@ -475,7 +567,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset,
if ((retval = ads_krb5_mk_req(context,
&auth_context,
- AP_OPTS_USE_SUBKEY,
+ AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts,
principal,
ccdef, &packet))) {
goto failed;
@@ -550,10 +642,349 @@ failed:
#endif
}
+void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum,
+ PAC_SIGNATURE_DATA *sig)
+{
+#ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM
+ cksum->cksumtype = (krb5_cksumtype)sig->type;
+ cksum->checksum.length = sig->signature.buf_len;
+ cksum->checksum.data = sig->signature.buffer;
+#else
+ cksum->checksum_type = (krb5_cksumtype)sig->type;
+ cksum->length = sig->signature.buf_len;
+ cksum->contents = sig->signature.buffer;
+#endif
+}
+
+krb5_error_code smb_krb5_verify_checksum(krb5_context context,
+ krb5_keyblock *keyblock,
+ krb5_keyusage usage,
+ krb5_checksum *cksum,
+ uint8 *data,
+ size_t length)
+{
+ krb5_error_code ret;
+
+ /* verify the checksum */
+
+ /* welcome to the wonderful world of samba's kerberos abstraction layer:
+ *
+ * function heimdal 0.6.1rc3 heimdal 0.7 MIT krb 1.4.2
+ * -----------------------------------------------------------------------------
+ * krb5_c_verify_checksum - works works
+ * krb5_verify_checksum works (6 args) works (6 args) broken (7 args)
+ */
+
+#if defined(HAVE_KRB5_C_VERIFY_CHECKSUM)
+ {
+ krb5_boolean checksum_valid = False;
+ krb5_data input;
+
+ input.data = (char *)data;
+ input.length = length;
+
+ ret = krb5_c_verify_checksum(context,
+ keyblock,
+ usage,
+ &input,
+ cksum,
+ &checksum_valid);
+ if (!checksum_valid)
+ ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+ }
+
+#elif KRB5_VERIFY_CHECKSUM_ARGS == 6 && defined(HAVE_KRB5_CRYPTO_INIT) && defined(HAVE_KRB5_CRYPTO) && defined(HAVE_KRB5_CRYPTO_DESTROY)
+
+ /* Warning: MIT's krb5_verify_checksum cannot be used as it will use a key
+ * without enctype and it ignores any key_usage types - Guenther */
+
+ {
+
+ krb5_crypto crypto;
+ ret = krb5_crypto_init(context,
+ keyblock,
+ 0,
+ &crypto);
+ if (ret) {
+ DEBUG(0,("smb_krb5_verify_checksum: krb5_crypto_init() failed: %s\n",
+ error_message(ret)));
+ return ret;
+ }
+
+ ret = krb5_verify_checksum(context,
+ crypto,
+ usage,
+ data,
+ length,
+ cksum);
+
+ krb5_crypto_destroy(context, crypto);
+ }
+
+#else
+#error UNKNOWN_KRB5_VERIFY_CHECKSUM_FUNCTION
+#endif
+
+ return ret;
+}
+
+time_t get_authtime_from_tkt(krb5_ticket *tkt)
+{
+#if defined(HAVE_KRB5_TKT_ENC_PART2)
+ return tkt->enc_part2->times.authtime;
+#else
+ return tkt->ticket.authtime;
+#endif
+}
+
+static int get_kvno_from_ap_req(krb5_ap_req *ap_req)
+{
+#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */
+ if (ap_req->ticket->enc_part.kvno)
+ return ap_req->ticket->enc_part.kvno;
+#else /* Heimdal */
+ if (ap_req->ticket.enc_part.kvno)
+ return *ap_req->ticket.enc_part.kvno;
+#endif
+ return 0;
+}
+
+static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req)
+{
+#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */
+ return ap_req->ticket.enc_part.etype;
+#else /* MIT */
+ return ap_req->ticket->enc_part.enctype;
+#endif
+}
+
+static krb5_error_code
+get_key_from_keytab(krb5_context context,
+ krb5_keytab keytab,
+ krb5_const_principal server,
+ krb5_enctype enctype,
+ krb5_kvno kvno,
+ krb5_keyblock **out_key)
+{
+ krb5_keytab_entry entry;
+ krb5_error_code ret;
+ krb5_keytab real_keytab;
+ char *name = NULL;
+
+ if (keytab == NULL) {
+ krb5_kt_default(context, &real_keytab);
+ } else {
+ real_keytab = keytab;
+ }
+
+ if ( DEBUGLEVEL >= 10 ) {
+ krb5_unparse_name(context, server, &name);
+ DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n",
+ kvno, enctype, name));
+ krb5_free_unparsed_name(context, name);
+ }
+
+ ret = krb5_kt_get_entry(context,
+ real_keytab,
+ server,
+ kvno,
+ enctype,
+ &entry);
+
+ if (ret) {
+ DEBUG(0,("get_key_from_keytab: failed to retrieve key: %s\n", error_message(ret)));
+ goto out;
+ }
+
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
+ ret = krb5_copy_keyblock(context, &entry.keyblock, out_key);
+#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) /* MIT */
+ ret = krb5_copy_keyblock(context, &entry.key, out_key);
+#else
+#error UNKNOWN_KRB5_KEYTAB_ENTRY_FORMAT
+#endif
+
+ if (ret) {
+ DEBUG(0,("get_key_from_keytab: failed to copy key: %s\n", error_message(ret)));
+ goto out;
+ }
+
+ smb_krb5_kt_free_entry(context, &entry);
+
+out:
+ if (keytab == NULL) {
+ krb5_kt_close(context, real_keytab);
+ }
+
+ return ret;
+}
+
+void smb_krb5_free_ap_req(krb5_context context,
+ krb5_ap_req *ap_req)
+{
+#ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */
+ krb5_free_ap_req(context, ap_req);
+#elif defined(HAVE_FREE_AP_REQ) /* Heimdal */
+ free_AP_REQ(ap_req);
+#else
+#error UNKNOWN_KRB5_AP_REQ_FREE_FUNCTION
+#endif
+}
+
+/* Prototypes */
+#if defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */
+krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep);
+#endif
+
+krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context,
+ const krb5_data *inbuf,
+ krb5_kvno *kvno,
+ krb5_enctype *enctype)
+{
+ krb5_error_code ret;
+#ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */
+ {
+ krb5_ap_req ap_req;
+
+ ret = krb5_decode_ap_req(context, inbuf, &ap_req);
+ if (ret)
+ return ret;
+
+ *kvno = get_kvno_from_ap_req(&ap_req);
+ *enctype = get_enctype_from_ap_req(&ap_req);
+
+ smb_krb5_free_ap_req(context, &ap_req);
+ }
+#elif defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */
+ {
+ krb5_ap_req *ap_req = NULL;
+
+ ret = decode_krb5_ap_req(inbuf, &ap_req);
+ if (ret)
+ return ret;
+
+ *kvno = get_kvno_from_ap_req(ap_req);
+ *enctype = get_enctype_from_ap_req(ap_req);
+
+ smb_krb5_free_ap_req(context, ap_req);
+ }
+#else
+#error UNKOWN_KRB5_AP_REQ_DECODING_FUNCTION
+#endif
+ return ret;
+}
+
+krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context,
+ krb5_auth_context *auth_context,
+ const krb5_data *inbuf,
+ krb5_const_principal server,
+ krb5_keytab keytab,
+ krb5_flags *ap_req_options,
+ krb5_ticket **ticket,
+ krb5_keyblock **keyblock)
+{
+ krb5_error_code ret;
+ krb5_ap_req *ap_req = NULL;
+ krb5_kvno kvno;
+ krb5_enctype enctype;
+ krb5_keyblock *local_keyblock;
+
+ ret = krb5_rd_req(context,
+ auth_context,
+ inbuf,
+ server,
+ keytab,
+ ap_req_options,
+ ticket);
+ if (ret) {
+ return ret;
+ }
+
+ ret = smb_krb5_get_keyinfo_from_ap_req(context, inbuf, &kvno, &enctype);
+ if (ret) {
+ return ret;
+ }
+
+ ret = get_key_from_keytab(context,
+ keytab,
+ server,
+ enctype,
+ kvno,
+ &local_keyblock);
+ if (ret) {
+ DEBUG(0,("krb5_rd_req_return_keyblock_from_keytab: failed to call get_key_from_keytab\n"));
+ goto out;
+ }
+
+out:
+ if (ap_req) {
+ smb_krb5_free_ap_req(context, ap_req);
+ }
+
+ if (ret && local_keyblock != NULL) {
+ krb5_free_keyblock(context, local_keyblock);
+ } else {
+ *keyblock = local_keyblock;
+ }
+
+ return ret;
+}
+
+krb5_error_code smb_krb5_parse_name_norealm(krb5_context context,
+ const char *name,
+ krb5_principal *principal)
+{
+#ifdef HAVE_KRB5_PARSE_NAME_NOREALM
+ return krb5_parse_name_norealm(context, name, principal);
+#endif
+
+ /* we are cheating here because parse_name will in fact set the realm.
+ * We don't care as the only caller of smb_krb5_parse_name_norealm
+ * ignores the realm anyway when calling
+ * smb_krb5_principal_compare_any_realm later - Guenther */
+
+ return krb5_parse_name(context, name, principal);
+}
+
+BOOL smb_krb5_principal_compare_any_realm(krb5_context context,
+ krb5_const_principal princ1,
+ krb5_const_principal princ2)
+{
+#ifdef HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM
+
+ return krb5_principal_compare_any_realm(context, princ1, princ2);
+
+/* krb5_princ_size is a macro in MIT */
+#elif defined(HAVE_KRB5_PRINC_SIZE) || defined(krb5_princ_size)
+
+ int i, len1, len2;
+ const krb5_data *p1, *p2;
+
+ len1 = krb5_princ_size(context, princ1);
+ len2 = krb5_princ_size(context, princ2);
+
+ if (len1 != len2)
+ return False;
+
+ for (i = 0; i < len1; i++) {
+
+ p1 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ1), i);
+ p2 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ2), i);
+
+ if (p1->length != p2->length || memcmp(p1->data, p2->data, p1->length))
+ return False;
+ }
+
+ return True;
+#else
+#error NO_SUITABLE_PRINCIPAL_COMPARE_FUNCTION
+#endif
+}
+
#else /* HAVE_KRB5 */
/* this saves a few linking headaches */
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
- DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
+ DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
{
DEBUG(0,("NO KERBEROS SUPPORT\n"));
return 1;
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index 1220907629..55e36b646b 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -323,13 +323,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
0x0008 start of message mode named pipe protocol
****************************************************************************/
-size_t cli_write(struct cli_state *cli,
+ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
const char *buf, off_t offset, size_t size)
{
- int bwritten = 0;
- int issued = 0;
- int received = 0;
+ ssize_t bwritten = 0;
+ unsigned int issued = 0;
+ unsigned int received = 0;
int mpx = 1;
int block = cli->max_xmit - (smb_size+32);
int blocks = (size + (block-1)) / block;
@@ -343,8 +343,8 @@ size_t cli_write(struct cli_state *cli,
while (received < blocks) {
while ((issued - received < mpx) && (issued < blocks)) {
- int bsent = issued * block;
- int size1 = MIN(block, size - bsent);
+ ssize_t bsent = issued * block;
+ ssize_t size1 = MIN(block, size - bsent);
if (!cli_issue_write(cli, fnum, offset + bsent,
write_mode,
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index 85b7bd9e1e..33fc265f79 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -325,14 +325,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
*/
int spnego_gen_negTokenTarg(const char *principal, int time_offset,
DATA_BLOB *targ,
- DATA_BLOB *session_key_krb5)
+ DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
{
int retval;
DATA_BLOB tkt, tkt_wrapped;
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
/* get a kerberos ticket for the service and extract the session key */
- retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5);
+ retval = cli_krb5_get_ticket(principal, time_offset,
+ &tkt, session_key_krb5, extra_ap_opts);
if (retval)
return retval;
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index c6b1d465ff..5d3710b92e 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -464,8 +464,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
}
/****************************************************************************
- receive a SMB nttrans response allocating the necessary memory
- ****************************************************************************/
+ Receive a SMB nttrans response allocating the necessary memory.
+****************************************************************************/
BOOL cli_receive_nt_trans(struct cli_state *cli,
char **param, unsigned int *param_len,
@@ -503,7 +503,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*/
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if (cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ if (!(eclass == ERRDOS && ecode == ERRmoredata)) {
cli_signing_trans_stop(cli);
return(False);
}
@@ -637,11 +637,22 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
}
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if(cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ if(!(eclass == ERRDOS && ecode == ERRmoredata)) {
+ cli_signing_trans_stop(cli);
+ return(False);
+ }
+ }
+ /*
+ * Likewise for NT_STATUS_BUFFER_TOO_SMALL
+ */
+ if (cli_is_nt_error(cli)) {
+ if (!NT_STATUS_EQUAL(cli_nt_error(cli),
+ NT_STATUS_BUFFER_TOO_SMALL)) {
cli_signing_trans_stop(cli);
return(False);
}
}
+
/* parse out the total lengths again - they can shrink! */
if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount);
diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c
index 0d521bae8a..3f2dcd850b 100644
--- a/source3/libsmb/credentials.c
+++ b/source3/libsmb/credentials.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
code to manipulate domain credentials
Copyright (C) Andrew Tridgell 1997-1998
+ Largely rewritten by Jeremy Allison 2005.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,8 +22,9 @@
#include "includes.h"
/****************************************************************************
-represent a credential as a string
+ Represent a credential as a string.
****************************************************************************/
+
char *credstr(const uchar *cred)
{
static fstring buf;
@@ -34,182 +36,243 @@ char *credstr(const uchar *cred)
/****************************************************************************
- setup the session key.
-Input: 8 byte challenge block
+ Setup the session key.
+ Input: 8 byte challenge block
8 byte server challenge block
16 byte md4 encrypted password
-Output:
- 8 byte session key
+ Output:
+ 16 byte session key (last 8 bytes zero).
****************************************************************************/
-void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass,
- uchar session_key[8])
+
+static void cred_create_session_key(const DOM_CHAL *clnt_chal_in,
+ const DOM_CHAL *srv_chal_in,
+ const uchar *pass_in,
+ uchar session_key_out[16])
{
uint32 sum[2];
unsigned char sum2[8];
- sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
- sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
+ sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0);
+ sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
SIVAL(sum2,0,sum[0]);
SIVAL(sum2,4,sum[1]);
- cred_hash1(session_key, sum2, pass);
+ cred_hash1(session_key_out, sum2, pass_in);
+ memset(&session_key_out[8], '\0', 8);
/* debug output */
- DEBUG(4,("cred_session_key\n"));
+ DEBUG(4,("cred_create_session_key\n"));
- DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data)));
- DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data)));
+ DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
+ DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data)));
DEBUG(5,(" clnt+srv : %s\n", credstr(sum2)));
- DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
+ DEBUG(5,(" sess_key_out : %s\n", credstr(session_key_out)));
}
-
/****************************************************************************
-create a credential
-
-Input:
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
-
-Output:
- 8 byte credential
+ Utility function to step credential chain one forward.
+ Deliberately doesn't update the seed. See reseed comment below.
****************************************************************************/
-void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
- DOM_CHAL *cred)
+
+static void creds_step(struct dcinfo *dc)
{
- DOM_CHAL time_cred;
+ DOM_CHAL time_chal;
- SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time);
- SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4));
+ DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence ));
- cred_hash2(cred->data, time_cred.data, session_key);
+ DEBUG(5,("\tseed: %s\n", credstr(dc->seed_chal.data) ));
- /* debug output*/
- DEBUG(4,("cred_create\n"));
+ SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence);
+ SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
+
+ DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) ));
- DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
- DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data)));
- DEBUG(5,(" timestamp: %x\n" , timestamp.time));
- DEBUG(5,(" timecred : %s\n", credstr(time_cred.data)));
- DEBUG(5,(" calc_cred: %s\n", credstr(cred->data)));
-}
+ cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key);
+ DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) ));
-/****************************************************************************
- check a supplied credential
+ SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
+ SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
+
+ DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) ));
-Input:
- 8 byte received credential
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
+ cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key);
+
+ DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) ));
+}
-Output:
- returns 1 if computed credential matches received credential
- returns 0 otherwise
+
+/****************************************************************************
+ Create a server credential struct.
****************************************************************************/
-int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
- UTIME timestamp)
+
+void creds_server_init(struct dcinfo *dc,
+ DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal,
+ const char mach_pw[16],
+ DOM_CHAL *init_chal_out)
{
- DOM_CHAL cred2;
+ DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) ));
+ DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
+ dump_data_pw("creds_server_init: machine pass", mach_pw, 16);
- cred_create(session_key, stored_cred, timestamp, &cred2);
+ /* Just in case this isn't already there */
+ memcpy(dc->mach_pw, mach_pw, 16);
- /* debug output*/
- DEBUG(4,("cred_assert\n"));
+ /* Generate the session key. */
+ cred_create_session_key(clnt_chal, /* Stored client challenge. */
+ srv_chal, /* Stored server challenge. */
+ dc->mach_pw, /* input machine password. */
+ dc->sess_key); /* output session key. */
- DEBUG(5,(" challenge : %s\n", credstr(cred->data)));
- DEBUG(5,(" calculated: %s\n", credstr(cred2.data)));
+ dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
- if (memcmp(cred->data, cred2.data, 8) == 0)
- {
- DEBUG(5, ("credentials check ok\n"));
- return True;
- }
- else
- {
- DEBUG(5, ("credentials check wrong\n"));
+ /* Generate the next client and server creds. */
+ cred_hash2(dc->clnt_chal.data, /* output */
+ clnt_chal->data, /* input */
+ dc->sess_key); /* input */
+
+ cred_hash2(dc->srv_chal.data, /* output */
+ srv_chal->data, /* input */
+ dc->sess_key); /* input */
+
+ /* Seed is the client chal. */
+ memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
+
+ DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
+ DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) ));
+ DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) ));
+
+ memcpy(init_chal_out->data, dc->srv_chal.data, 8);
+}
+
+/****************************************************************************
+ Check a credential sent by the client.
+****************************************************************************/
+
+BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in)
+{
+ if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) {
+ DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data)));
+ DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data)));
+ DEBUG(0,("creds_server_check: credentials check failed.\n"));
return False;
}
+ DEBUG(10,("creds_server_check: credentials check OK.\n"));
+ return True;
}
-
/****************************************************************************
- checks credentials; generates next step in the credential chain
+ Replace current seed chal. Internal function - due to split server step below.
****************************************************************************/
-BOOL clnt_deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred)
+
+static void creds_reseed(struct dcinfo *dc)
{
- UTIME new_clnt_time;
- uint32 new_cred;
+ DOM_CHAL time_chal;
- DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__));
+ SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
+ SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
- /* increment client time by one second */
- new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
+ dc->seed_chal = time_chal;
- /* check that the received server credentials are valid */
- if (!cred_assert(&rcv_srv_cred->challenge, sess_key,
- &sto_clnt_cred->challenge, new_clnt_time))
- {
- return False;
- }
+ DEBUG(5,("cred_reseed: seed %s\n", credstr(dc->seed_chal.data) ));
+}
- /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
- new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
- new_cred += new_clnt_time.time;
+/****************************************************************************
+ Step the server credential chain one forward.
+****************************************************************************/
- /* store new seed in client credentials */
- SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
+BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out)
+{
+ dc->sequence = received_cred->timestamp.time;
- DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data)));
- return True;
-}
+ creds_step(dc);
+
+ /* Create the outgoing credentials */
+ cred_out->timestamp.time = dc->sequence + 1;
+ cred_out->challenge = dc->srv_chal;
+ creds_reseed(dc);
+
+ return creds_server_check(dc, &received_cred->challenge);
+}
/****************************************************************************
- checks credentials; generates next step in the credential chain
+ Create a client credential struct.
****************************************************************************/
-BOOL deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred,
- DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
+
+void creds_client_init(struct dcinfo *dc,
+ DOM_CHAL *clnt_chal,
+ DOM_CHAL *srv_chal,
+ const char mach_pw[16],
+ DOM_CHAL *init_chal_out)
{
- UTIME new_clnt_time;
- uint32 new_cred;
+ dc->sequence = time(NULL);
- DEBUG(5,("deal_with_creds: %d\n", __LINE__));
+ DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) ));
+ DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
+ dump_data_pw("creds_client_init: machine pass", mach_pw, 16);
- /* check that the received client credentials are valid */
- if (!cred_assert(&rcv_clnt_cred->challenge, sess_key,
- &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp))
- {
- return False;
- }
+ /* Just in case this isn't already there */
+ memcpy(dc->mach_pw, mach_pw, 16);
- /* increment client time by one second */
- new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
+ /* Generate the session key. */
+ cred_create_session_key(clnt_chal, /* Stored client challenge. */
+ srv_chal, /* Stored server challenge. */
+ dc->mach_pw, /* input machine password. */
+ dc->sess_key); /* output session key. */
- /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
- new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
- new_cred += new_clnt_time.time;
+ dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
- DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred));
+ /* Generate the next client and server creds. */
+ cred_hash2(dc->clnt_chal.data, /* output */
+ clnt_chal->data, /* input */
+ dc->sess_key); /* input */
- /* doesn't matter that server time is 0 */
- rtn_srv_cred->timestamp.time = 0;
+ cred_hash2(dc->srv_chal.data, /* output */
+ srv_chal->data, /* input */
+ dc->sess_key); /* input */
- DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time));
+ /* Seed is the client cred. */
+ memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
- /* create return credentials for inclusion in the reply */
- cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time,
- &rtn_srv_cred->challenge);
-
- DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
+ DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
+ DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) ));
+ DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
- /* store new seed in client credentials */
- SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
+ memcpy(init_chal_out->data, dc->clnt_chal.data, 8);
+}
+
+/****************************************************************************
+ Check a credential returned by the server.
+****************************************************************************/
+BOOL creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in)
+{
+ if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) {
+ DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data)));
+ DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data)));
+ DEBUG(0,("creds_client_check: credentials check failed.\n"));
+ return False;
+ }
+ DEBUG(10,("creds_client_check: credentials check OK.\n"));
return True;
}
+
+/****************************************************************************
+ Step the client credentials to the next element in the chain, updating the
+ current client and server credentials and the seed
+ produce the next authenticator in the sequence ready to send to
+ the server
+****************************************************************************/
+
+void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out)
+{
+ dc->sequence += 2;
+ creds_step(dc);
+ creds_reseed(dc);
+
+ next_cred_out->challenge = dc->clnt_chal;
+ next_cred_out->timestamp.time = dc->sequence;
+}
diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c
index 8462fbee87..3c0b13ad6f 100644
--- a/source3/libsmb/errormap.c
+++ b/source3/libsmb/errormap.c
@@ -62,7 +62,7 @@ static const struct {
{ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC},
{ERRDOS, 87, NT_STATUS_INVALID_CID},
{ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED},
- {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER},
+ {ERRDOS, ERRinvalidparam, NT_STATUS_INVALID_PARAMETER},
{ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE},
{ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE},
{ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST},
@@ -338,7 +338,7 @@ static const struct {
{ERRDOS, 203, NT_STATUS(0xc0000100)},
{ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY},
{ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR},
- {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY},
+ {ERRDOS, ERRbaddirectory, NT_STATUS_NOT_A_DIRECTORY},
{ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE},
{ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION},
{ERRDOS, 206, NT_STATUS_NAME_TOO_LONG},
diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c
index f9461f9368..5699e153bb 100644
--- a/source3/libsmb/libsmb_compat.c
+++ b/source3/libsmb/libsmb_compat.c
@@ -420,7 +420,7 @@ int smbc_open_print_job(const char *fname)
{
SMBCFILE * file = statcont->open_print_job(statcont, fname);
if (!file) return -1;
- return (int) file;
+ return file->cli_fd;
}
int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn)
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index fe8f878aa5..1e729abb22 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -80,6 +80,23 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
return False;
}
+/*
+ * Find an lsa pipe handle associated with a cli struct.
+ */
+
+static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli)
+{
+ struct rpc_pipe_client *pipe_hnd;
+
+ for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) {
+ if (pipe_hnd->pipe_idx == PI_LSARPC) {
+ return pipe_hnd;
+ }
+ }
+
+ return NULL;
+}
+
static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file);
static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence);
@@ -800,6 +817,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
{
struct in_addr ip;
struct cli_state *ipc_cli;
+ struct rpc_pipe_client *pipe_hnd;
NTSTATUS nt_status;
SMBCSRV *ipc_srv=NULL;
@@ -835,29 +853,27 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
return NULL;
}
- if(pol) {
+ pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, PI_LSARPC, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(1, ("cli_nt_session_open fail!\n"));
+ errno = ENOTSUP;
+ cli_shutdown(ipc_cli);
+ return NULL;
+ }
- if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) {
- DEBUG(1, ("cli_nt_session_open fail!\n"));
- errno = ENOTSUP;
- cli_shutdown(ipc_cli);
- return NULL;
- }
-
- /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
- but NT sends 0x2000000 so we might as well do it too. */
-
- nt_status = cli_lsa_open_policy(ipc_cli,
- ipc_cli->mem_ctx,
- True,
- GENERIC_EXECUTE_ACCESS,
- pol);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- errno = smbc_errno(context, ipc_cli);
- cli_shutdown(ipc_cli);
- return NULL;
- }
+ /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
+ but NT sends 0x2000000 so we might as well do it too. */
+
+ nt_status = rpccli_lsa_open_policy(pipe_hnd,
+ ipc_cli->mem_ctx,
+ True,
+ GENERIC_EXECUTE_ACCESS,
+ pol);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ errno = smbc_errno(context, ipc_cli);
+ cli_shutdown(ipc_cli);
+ return NULL;
}
ipc_srv = SMB_MALLOC_P(SMBCSRV);
@@ -1782,7 +1798,7 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int
if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL,
NULL, NULL, NULL))
{
- SMB_BIG_UINT b_size = size;
+ SMB_OFF_T b_size = size;
if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL,
NULL))
{
@@ -3041,7 +3057,7 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir)
/*
* We return the pointer here as the offset
*/
- ret_val = (int)dir->dir_next;
+ ret_val = (off_t)(long)dir->dir_next;
return ret_val;
}
@@ -3347,14 +3363,20 @@ static void convert_sid_to_string(struct cli_state *ipc_cli,
char **domains = NULL;
char **names = NULL;
uint32 *types = NULL;
-
+ struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
sid_to_string(str, sid);
- if (numeric) return; /* no lookup desired */
-
+ if (numeric) {
+ return; /* no lookup desired */
+ }
+
+ if (!pipe_hnd) {
+ return;
+ }
+
/* Ask LSA to convert the sid to a name */
- if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx,
+ if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx,
pol, 1, sid, &domains,
&names, &types)) ||
!domains || !domains[0] || !names || !names[0]) {
@@ -3378,6 +3400,11 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
uint32 *types = NULL;
DOM_SID *sids = NULL;
BOOL result = True;
+ struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
+
+ if (!pipe_hnd) {
+ return False;
+ }
if (numeric) {
if (strncmp(str, "S-", 2) == 0) {
@@ -3388,7 +3415,7 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
goto done;
}
- if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx,
+ if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx,
pol, 1, &str, &sids,
&types))) {
result = False;
@@ -5161,7 +5188,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr
/* Try to open the file for reading ... */
- if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
+ if ((long)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
return -1; /* smbc_open sets errno */
@@ -5170,7 +5197,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr
/* Now, try to open the printer file for writing */
- if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
+ if ((long)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
saverr = errno; /* Save errno */
c_file->close_fn(c_file, fid1);
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index b02c2384a8..6b551e8774 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -5,6 +5,7 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Andrew Bartlett 2001-2003
+ Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
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
@@ -217,6 +218,12 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
uint32 ntlmssp_command;
int i;
+ if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
+ /* Called update after negotiations finished. */
+ DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
*out = data_blob(NULL, 0);
if (!in.length && ntlmssp_state->stored_response.length) {
@@ -348,6 +355,13 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
+ if (neg_flags & NTLMSSP_NEGOTIATE_56) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
+ }
+ }
+
+ if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
}
if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
@@ -360,6 +374,34 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
}
+/**
+ Weaken NTLMSSP keys to cope with down-level clients and servers.
+
+ We probably should have some parameters to control this, but as
+ it only occours for LM_KEY connections, and this is controlled
+ by the client lanman auth/lanman auth parameters, it isn't too bad.
+*/
+
+void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state)
+{
+ /* Key weakening not performed on the master key for NTLM2
+ and does not occour for NTLM1. Therefore we only need
+ to do this for the LM_KEY.
+ */
+
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
+ ;
+ } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
+ ntlmssp_state->session_key.data[7] = 0xa0;
+ } else { /* forty bits */
+ ntlmssp_state->session_key.data[5] = 0xe5;
+ ntlmssp_state->session_key.data[6] = 0x38;
+ ntlmssp_state->session_key.data[7] = 0xb0;
+ }
+ ntlmssp_state->session_key.length = 8;
+ }
+}
/**
* Next state function for the Negotiate packet
@@ -398,6 +440,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_INVALID_PARAMETER;
}
+ DEBUG(10, ("ntlmssp_server_negotiate: client = %s, domain = %s\n",
+ cliname ? cliname : "", domname ? domname : ""));
+
SAFE_FREE(cliname);
SAFE_FREE(domname);
@@ -495,7 +540,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
DATA_BLOB lm_session_key = data_blob(NULL, 0);
DATA_BLOB session_key = data_blob(NULL, 0);
uint32 ntlmssp_command, auth_flags;
- NTSTATUS nt_status;
+ NTSTATUS nt_status = NT_STATUS_OK;
/* used by NTLM2 */
BOOL doing_ntlm2 = False;
@@ -639,6 +684,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
data_blob_free(&encrypted_session_key);
return nt_status;
}
+
+ /* LM Key is incompatible. */
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
}
}
@@ -710,11 +758,11 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
data_blob_free(&encrypted_session_key);
DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
- encrypted_session_key.length));
+ (unsigned int)encrypted_session_key.length));
return NT_STATUS_INVALID_PARAMETER;
} else if (!session_key.data || session_key.length != 16) {
DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
- session_key.length));
+ (unsigned int)session_key.length));
ntlmssp_state->session_key = session_key;
} else {
dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
@@ -731,6 +779,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
ntlmssp_state->session_key = session_key;
}
+ /* The client might need us to use a partial-strength session key */
+ ntlmssp_weaken_keys(ntlmssp_state);
+
if (!NT_STATUS_IS_OK(nt_status)) {
ntlmssp_state->session_key = data_blob(NULL, 0);
} else if (ntlmssp_state->session_key.length) {
@@ -739,8 +790,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
data_blob_free(&encrypted_session_key);
- /* allow arbitarily many authentications */
- ntlmssp_state->expected_state = NTLMSSP_AUTH;
+ /* Only one authentication allowed per server state. */
+ ntlmssp_state->expected_state = NTLMSSP_DONE;
return nt_status;
}
@@ -784,7 +835,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_NEGOTIATE_NTLM2 |
NTLMSSP_NEGOTIATE_KEY_EXCH |
- NTLMSSP_NEGOTIATE_SIGN;
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL;
return NT_STATUS_OK;
}
@@ -851,7 +903,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
DATA_BLOB nt_response = data_blob(NULL, 0);
DATA_BLOB session_key = data_blob(NULL, 0);
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
- NTSTATUS nt_status;
+ NTSTATUS nt_status = NT_STATUS_OK;
if (!msrpc_parse(&reply, "CdBd",
"NTLMSSP",
@@ -977,8 +1029,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
} else {
-
-
uchar lm_hash[16];
uchar nt_hash[16];
E_deshash(ntlmssp_state->password, lm_hash);
@@ -998,8 +1048,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
&& lp_client_lanman_auth()) {
- SMBsesskeygen_lmv1(lm_hash, lm_response.data,
- session_key.data);
+ SMBsesskeygen_lm_sess_key(lm_hash, lm_response.data,
+ session_key.data);
dump_data_pw("LM session key\n", session_key.data, session_key.length);
} else {
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
@@ -1045,19 +1095,22 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
data_blob_free(&ntlmssp_state->chal);
+ ntlmssp_state->session_key = session_key;
+
+ /* The client might be using 56 or 40 bit weakened keys */
+ ntlmssp_weaken_keys(ntlmssp_state);
+
ntlmssp_state->chal = challenge_blob;
ntlmssp_state->lm_resp = lm_response;
ntlmssp_state->nt_resp = nt_response;
- ntlmssp_state->session_key = session_key;
- ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
+ ntlmssp_state->expected_state = NTLMSSP_DONE;
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
- return nt_status;
}
- return NT_STATUS_MORE_PROCESSING_REQUIRED;
+ return nt_status;
}
NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
@@ -1103,4 +1156,3 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
return NT_STATUS_OK;
}
-
diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c
index 4b3043aec8..e71504867e 100644
--- a/source3/libsmb/ntlmssp_parse.c
+++ b/source3/libsmb/ntlmssp_parse.c
@@ -216,7 +216,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
/* if odd length and unicode */
return False;
}
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
+ if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
return False;
if (0 < len1) {
@@ -244,7 +244,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
return False;
}
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
+ if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
return False;
if (0 < len1) {
@@ -272,7 +272,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
return False;
}
- if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
+ if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
return False;
*b = data_blob(blob->data + ptr, len1);
diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c
index b810597076..51023ca356 100644
--- a/source3/libsmb/ntlmssp_sign.c
+++ b/source3/libsmb/ntlmssp_sign.c
@@ -2,8 +2,7 @@
* Unix SMB/CIFS implementation.
* Version 3.0
* NTLMSSP Signing routines
- * Copyright (C) Luke Kenneth Casson Leighton 1996-2001
- * Copyright (C) Andrew Bartlett 2003
+ * Copyright (C) Andrew Bartlett 2003-2005
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,74 +26,25 @@
#define SRV_SIGN "session key to server-to-client signing key magic constant"
#define SRV_SEAL "session key to server-to-client sealing key magic constant"
-static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len)
-{
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
-
- for (ind = 0; ind < len; ind++)
- {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
- }
-
- hash[256] = index_i;
- hash[257] = index_j;
-}
-
-static void calc_hash(unsigned char hash[258], unsigned char *k2, int k2l)
-{
- unsigned char j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++)
- {
- hash[ind] = (unsigned char)ind;
- }
-
- for (ind = 0; ind < 256; ind++)
- {
- unsigned char tc;
-
- j += (hash[ind] + k2[ind%k2l]);
-
- tc = hash[ind];
- hash[ind] = hash[j];
- hash[j] = tc;
- }
-
- hash[256] = 0;
- hash[257] = 0;
-}
+/**
+ * Some notes on then NTLM2 code:
+ *
+ * NTLM2 is a AEAD system. This means that the data encrypted is not
+ * all the data that is signed. In DCE-RPC case, the headers of the
+ * DCE-RPC packets are also signed. This prevents some of the
+ * fun-and-games one might have by changing them.
+ *
+ */
-static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16],
- DATA_BLOB session_key,
- const char *constant)
+static void calc_ntlmv2_key(unsigned char subkey[16],
+ DATA_BLOB session_key,
+ const char *constant)
{
struct MD5Context ctx3;
-
- /* NOTE: This code is currently complate fantasy - it's
- got more in common with reality than the previous code
- (the LM session key is not the right thing to use) but
- it still needs work */
-
MD5Init(&ctx3);
MD5Update(&ctx3, session_key.data, session_key.length);
- MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1);
- MD5Final(digest, &ctx3);
-
- calc_hash(hash, digest, 16);
+ MD5Update(&ctx3, constant, strlen(constant)+1);
+ MD5Final(subkey, &ctx3);
}
enum ntlmssp_direction {
@@ -103,64 +53,107 @@ enum ntlmssp_direction {
};
static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
- const uchar *data, size_t length,
- enum ntlmssp_direction direction,
- DATA_BLOB *sig)
+ const uchar *data, size_t length,
+ const uchar *whole_pdu, size_t pdu_length,
+ enum ntlmssp_direction direction,
+ DATA_BLOB *sig,
+ BOOL encrypt_sig)
{
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
HMACMD5Context ctx;
uchar seq_num[4];
uchar digest[16];
- SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
-
- hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
- hmac_md5_update(seq_num, 4, &ctx);
- hmac_md5_update(data, length, &ctx);
- hmac_md5_final(digest, &ctx);
- if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
- , ntlmssp_state->ntlmssp_seq_num)) {
+ *sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+ if (!sig->data) {
return NT_STATUS_NO_MEMORY;
}
- if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
+ switch (direction) {
+ case NTLMSSP_SEND:
+ DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n",
+ ntlmssp_state->ntlm2_send_seq_num,
+ (unsigned int)length,
+ (unsigned int)pdu_length));
+
+ SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num);
+ ntlmssp_state->ntlm2_send_seq_num++;
+ hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx);
+ break;
+ case NTLMSSP_RECEIVE:
+
+ DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n",
+ ntlmssp_state->ntlm2_recv_seq_num,
+ (unsigned int)length,
+ (unsigned int)pdu_length));
+
+ SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num);
+ ntlmssp_state->ntlm2_recv_seq_num++;
+ hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx);
+ break;
+ }
+
+ dump_data_pw("pdu data ", whole_pdu, pdu_length);
+
+ hmac_md5_update(seq_num, 4, &ctx);
+ hmac_md5_update(whole_pdu, pdu_length, &ctx);
+ hmac_md5_final(digest, &ctx);
+
+ if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
switch (direction) {
case NTLMSSP_SEND:
- NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
+ smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, digest, 8);
break;
case NTLMSSP_RECEIVE:
- NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4);
+ smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, digest, 8);
break;
}
}
+
+ SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
+ memcpy(sig->data + 4, digest, 8);
+ memcpy(sig->data + 12, seq_num, 4);
+
+ dump_data_pw("ntlmssp v2 sig ", sig->data, sig->length);
+
} else {
uint32 crc;
crc = crc32_calc_buffer((const char *)data, length);
- if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
+ if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
return NT_STATUS_NO_MEMORY;
}
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
+ ntlmssp_state->ntlmv1_seq_num++;
+
+ dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmv1_arc4_state,
+ sizeof(ntlmssp_state->ntlmv1_arc4_state));
+ smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
}
return NT_STATUS_OK;
}
NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
const uchar *data, size_t length,
+ const uchar *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
NTSTATUS nt_status;
+
+ if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
+ DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot check sign packet\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
}
- nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig);
+ nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ data, length,
+ whole_pdu, pdu_length,
+ NTLMSSP_SEND, sig, True);
- /* increment counter on send */
- ntlmssp_state->ntlmssp_seq_num++;
return nt_status;
}
@@ -171,8 +164,9 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
*/
NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
- const uchar *data, size_t length,
- const DATA_BLOB *sig)
+ const uchar *data, size_t length,
+ const uchar *whole_pdu, size_t pdu_length,
+ const DATA_BLOB *sig)
{
DATA_BLOB local_sig;
NTSTATUS nt_status;
@@ -187,32 +181,51 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
(unsigned long)sig->length));
}
- nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data,
- length, NTLMSSP_RECEIVE, &local_sig);
+ nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ data, length,
+ whole_pdu, pdu_length,
+ NTLMSSP_RECEIVE, &local_sig, True);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
+ data_blob_free(&local_sig);
return nt_status;
}
- if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) {
- DEBUG(5, ("BAD SIG: wanted signature of\n"));
- dump_data(5, (const char *)local_sig.data, local_sig.length);
-
- DEBUG(5, ("BAD SIG: got signature of\n"));
- dump_data(5, (const char *)(sig->data), sig->length);
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
+ if (local_sig.length != sig->length ||
+ memcmp(local_sig.data, sig->data, sig->length) != 0) {
+ DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n"));
+ dump_data(5, local_sig.data, local_sig.length);
- DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
+ DEBUG(5, ("BAD SIG: got signature of\n"));
+ dump_data(5, sig->data, sig->length);
+
+ DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n"));
+ data_blob_free(&local_sig);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ } else {
+ if (local_sig.length != sig->length ||
+ memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) {
+ DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n"));
+ dump_data(5, local_sig.data, local_sig.length);
+
+ DEBUG(5, ("BAD SIG: got signature of\n"));
+ dump_data(5, sig->data, sig->length);
- /* increment counter on recieive */
- ntlmssp_state->ntlmssp_seq_num++;
+ DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n"));
+ data_blob_free(&local_sig);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
+ DEBUG(10,("ntlmssp_check_packet: NTLMSSP signature OK !\n"));
+ data_blob_free(&local_sig);
return NT_STATUS_OK;
}
-
/**
* Seal data with the NTLMSSP algorithm
*
@@ -220,8 +233,16 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
uchar *data, size_t length,
+ uchar *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
+ NTSTATUS nt_status;
+
+ if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
+ DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot seal packet\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
@@ -230,53 +251,44 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
DEBUG(10,("ntlmssp_seal_data: seal\n"));
dump_data_pw("ntlmssp clear data\n", data, length);
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- HMACMD5Context ctx;
- char seq_num[4];
- uchar digest[16];
- SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
-
- hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
- hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
- hmac_md5_update(data, length, &ctx);
- hmac_md5_final(digest, &ctx);
-
- if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
- , ntlmssp_state->ntlmssp_seq_num)) {
- return NT_STATUS_NO_MEMORY;
+ /* The order of these two operations matters - we must first seal the packet,
+ then seal the sequence number - this is becouse the send_seal_hash is not
+ constant, but is is rather updated with each iteration */
+ nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
+ data, length,
+ whole_pdu, pdu_length,
+ NTLMSSP_SEND, sig, False);
+ smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, data, length);
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
+ smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, sig->data+4, 8);
}
-
- dump_data_pw("ntlmssp client sealing hash:\n",
- ntlmssp_state->send_seal_hash,
- sizeof(ntlmssp_state->send_seal_hash));
- NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
- dump_data_pw("ntlmssp client signing hash:\n",
- ntlmssp_state->send_sign_hash,
- sizeof(ntlmssp_state->send_sign_hash));
- NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
} else {
uint32 crc;
crc = crc32_calc_buffer((const char *)data, length);
- if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
+ if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
return NT_STATUS_NO_MEMORY;
}
/* The order of these two operations matters - we must first seal the packet,
- then seal the sequence number - this is becouse the ntlmssp_hash is not
+ then seal the sequence number - this is becouse the ntlmv1_arc4_state is not
constant, but is is rather updated with each iteration */
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
+ dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
+ sizeof(ntlmssp_state->ntlmv1_arc4_state));
+ smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length);
+
+ dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
+ sizeof(ntlmssp_state->ntlmv1_arc4_state));
+
+ smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
+ ntlmssp_state->ntlmv1_seq_num++;
+
+ nt_status = NT_STATUS_OK;
}
+ dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
dump_data_pw("ntlmssp sealed data\n", data, length);
- /* increment counter on send */
- ntlmssp_state->ntlmssp_seq_num++;
-
return NT_STATUS_OK;
}
@@ -286,26 +298,27 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
*/
NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
- uchar *data, size_t length,
- DATA_BLOB *sig)
+ uchar *data, size_t length,
+ uchar *whole_pdu, size_t pdu_length,
+ DATA_BLOB *sig)
{
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot unseal packet\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
}
- DEBUG(10,("ntlmssp__unseal_data: seal\n"));
+ DEBUG(10,("ntlmssp_unseal_data: seal\n"));
dump_data_pw("ntlmssp sealed data\n", data, length);
+
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
- NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length);
+ /* First unseal the data. */
+ smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, data, length);
+ dump_data_pw("ntlmv2 clear data\n", data, length);
} else {
- dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
+ smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length);
+ dump_data_pw("ntlmv1 clear data\n", data, length);
}
- dump_data_pw("ntlmssp clear data\n", data, length);
-
- return ntlmssp_check_packet(ntlmssp_state, data, length, sig);
+ return ntlmssp_check_packet(ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
}
/**
@@ -326,6 +339,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
{
+ DATA_BLOB weak_session_key = ntlmssp_state->session_key;
const char *send_sign_const;
const char *send_seal_const;
const char *recv_sign_const;
@@ -352,62 +366,96 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
break;
}
- calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
- ntlmssp_state->send_sign_const,
- ntlmssp_state->session_key, send_sign_const);
- dump_data_pw("NTLMSSP send sign hash:\n",
- ntlmssp_state->send_sign_hash,
- sizeof(ntlmssp_state->send_sign_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->send_seal_hash,
- ntlmssp_state->send_seal_const,
- ntlmssp_state->session_key, send_seal_const);
- dump_data_pw("NTLMSSP send sesl hash:\n",
- ntlmssp_state->send_seal_hash,
- sizeof(ntlmssp_state->send_seal_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash,
- ntlmssp_state->recv_sign_const,
- ntlmssp_state->session_key, recv_sign_const);
- dump_data_pw("NTLMSSP receive sign hash:\n",
- ntlmssp_state->recv_sign_hash,
- sizeof(ntlmssp_state->recv_sign_hash));
-
- calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash,
- ntlmssp_state->recv_seal_const,
- ntlmssp_state->session_key, recv_seal_const);
- dump_data_pw("NTLMSSP receive seal hash:\n",
- ntlmssp_state->recv_sign_hash,
- sizeof(ntlmssp_state->recv_sign_hash));
-
- }
- else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
- if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) {
- /* can't sign or check signatures yet */
- DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n"));
- return NT_STATUS_UNSUCCESSFUL;
+ /**
+ Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
+ We probably should have some parameters to control this, once we get NTLM2 working.
+ */
+
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
+ ;
+ } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
+ weak_session_key.length = 6;
+ } else { /* forty bits */
+ weak_session_key.length = 5;
}
+
+ dump_data_pw("NTLMSSP weakend master key:\n",
+ weak_session_key.data,
+ weak_session_key.length);
+
+ /* SEND */
+ calc_ntlmv2_key(ntlmssp_state->send_sign_key,
+ ntlmssp_state->session_key, send_sign_const);
+ dump_data_pw("NTLMSSP send sign key:\n",
+ ntlmssp_state->send_sign_key, 16);
+
+ calc_ntlmv2_key(ntlmssp_state->send_seal_key,
+ weak_session_key, send_seal_const);
+ dump_data_pw("NTLMSSP send seal key:\n",
+ ntlmssp_state->send_seal_key, 16);
+
+ smb_arc4_init(ntlmssp_state->send_seal_arc4_state,
+ ntlmssp_state->send_seal_key, 16);
+
+ dump_data_pw("NTLMSSP send seal arc4 state:\n",
+ ntlmssp_state->send_seal_arc4_state,
+ sizeof(ntlmssp_state->send_seal_arc4_state));
+
+ /* RECV */
+ calc_ntlmv2_key(ntlmssp_state->recv_sign_key,
+ ntlmssp_state->session_key, recv_sign_const);
+ dump_data_pw("NTLMSSP recv send sign key:\n",
+ ntlmssp_state->recv_sign_key, 16);
+
+ calc_ntlmv2_key(ntlmssp_state->recv_seal_key,
+ weak_session_key, recv_seal_const);
- DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n"));
+ dump_data_pw("NTLMSSP recv seal key:\n",
+ ntlmssp_state->recv_seal_key, 16);
+
+ smb_arc4_init(ntlmssp_state->recv_seal_arc4_state,
+ ntlmssp_state->recv_seal_key, 16);
+
+ dump_data_pw("NTLMSSP recv seal arc4 state:\n",
+ ntlmssp_state->recv_seal_arc4_state,
+ sizeof(ntlmssp_state->recv_seal_arc4_state));
+
+ ntlmssp_state->ntlm2_send_seq_num = 0;
+ ntlmssp_state->ntlm2_recv_seq_num = 0;
+
- calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8);
- dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
} else {
- if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) {
- /* can't sign or check signatures yet */
- DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n"));
- return NT_STATUS_UNSUCCESSFUL;
+#if 0
+ /* Hmmm. Shouldn't we also weaken keys for ntlmv1 ? JRA. */
+
+ DATA_BLOB weak_session_key = ntlmssp_state->session_key;
+ /**
+ Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
+ We probably should have some parameters to control this, once we get NTLM2 working.
+ */
+
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
+ ;
+ } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
+ weak_session_key.length = 6;
+ } else { /* forty bits */
+ weak_session_key.length = 5;
}
-
- DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
+ dump_data_pw("NTLMSSP weakend master key:\n",
+ weak_session_key.data,
+ weak_session_key.length);
+#endif
- calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16);
- dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
- }
+ DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
+
+ smb_arc4_init(ntlmssp_state->ntlmv1_arc4_state,
+ ntlmssp_state->session_key.data, ntlmssp_state->session_key.length);
- ntlmssp_state->ntlmssp_seq_num = 0;
+ dump_data_pw("NTLMv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
+ sizeof(ntlmssp_state->ntlmv1_arc4_state));
+
+ ntlmssp_state->ntlmv1_seq_num = 0;
+ }
return NT_STATUS_OK;
}
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index 8bce9c86a1..b104a4678d 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -21,16 +21,17 @@
#include "includes.h"
/*************************************************************
-change a password on a remote machine using IPC calls
+ Change a password on a remote machine using IPC calls.
*************************************************************/
+
BOOL remote_password_change(const char *remote_machine, const char *user_name,
const char *old_passwd, const char *new_passwd,
char *err_str, size_t err_str_len)
{
struct nmb_name calling, called;
struct cli_state cli;
+ struct rpc_pipe_client *pipe_hnd;
struct in_addr ip;
- struct ntuser_creds creds;
NTSTATUS result;
@@ -85,11 +86,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- init_creds(&creds, "", "", NULL);
- cli_init_creds(&cli, &creds);
+ cli_init_creds(&cli, "", "", NULL);
} else {
- init_creds(&creds, user_name, "", old_passwd);
- cli_init_creds(&cli, &creds);
+ cli_init_creds(&cli, user_name, "", old_passwd);
}
if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
@@ -99,14 +98,19 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- /* Try not to give the password away to easily */
+ /* Try not to give the password away too easily */
- cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli.pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli.pipe_auth_flags |= AUTH_PIPE_SEAL;
-
- if ( !cli_nt_session_open( &cli, PI_SAMR ) ) {
+ pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli,
+ PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ "", /* what domain... ? */
+ user_name,
+ old_passwd,
+ &result);
+
+ if (!pipe_hnd) {
if (lp_client_lanman_auth()) {
+ /* Use the old RAP method. */
if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
remote_machine, cli_errstr(&cli) );
@@ -114,14 +118,16 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
} else {
- slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
- remote_machine);
+ slprintf(err_str, err_str_len-1,
+ "SAMR connection to machine %s failed. Error was %s, "
+ "but LANMAN password changed are disabled\n",
+ nt_errstr(result), remote_machine);
cli_shutdown(&cli);
return False;
}
}
- if (NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name,
+ if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name,
new_passwd, old_passwd))) {
/* Great - it all worked! */
cli_shutdown(&cli);
@@ -138,25 +144,25 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
}
/* OK, that failed, so try again... */
- cli_nt_session_close(&cli);
+ cli_rpc_pipe_close(pipe_hnd);
/* Try anonymous NTLMSSP... */
- init_creds(&creds, "", "", NULL);
- cli_init_creds(&cli, &creds);
+ cli_init_creds(&cli, "", "", NULL);
- cli.pipe_auth_flags = 0;
-
result = NT_STATUS_UNSUCCESSFUL;
- /* OK, this is ugly, but... */
- if ( cli_nt_session_open( &cli, PI_SAMR )
- && NT_STATUS_IS_OK(result
- = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name,
- new_passwd, old_passwd))) {
+ /* OK, this is ugly, but... try an anonymous pipe. */
+ pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result);
+
+ if ( pipe_hnd &&
+ (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd,
+ cli.mem_ctx,
+ user_name,
+ new_passwd,
+ old_passwd)))) {
/* Great - it all worked! */
cli_shutdown(&cli);
return True;
-
} else {
if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)
|| NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) {
@@ -173,6 +179,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
just might not support SAMR password changes, so fall back */
if (lp_client_lanman_auth()) {
+ /* Use the old RAP method. */
if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
/* SAMR failed, but the old LanMan protocol worked! */
@@ -185,9 +192,10 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
cli_shutdown(&cli);
return False;
} else {
- slprintf(err_str, err_str_len-1,
- "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
- remote_machine);
+ slprintf(err_str, err_str_len-1,
+ "SAMR connection to machine %s failed. Error was %s, "
+ "but LANMAN password changed are disabled\n",
+ nt_errstr(result), remote_machine);
cli_shutdown(&cli);
return False;
}
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
index e010f226a0..a0f3383e29 100644
--- a/source3/libsmb/pwd_cache.c
+++ b/source3/libsmb/pwd_cache.c
@@ -60,4 +60,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
clr[0] = 0;
}
-
diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c
index 87a386307c..7659d1cd6e 100644
--- a/source3/libsmb/smb_share_modes.c
+++ b/source3/libsmb/smb_share_modes.c
@@ -55,6 +55,12 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
return smb_db;
}
+/* key and data records in the tdb locking database */
+struct locking_key {
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+};
+
int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
{
int ret = tdb_close(db_ctx->smb_tdb);
@@ -102,10 +108,10 @@ struct locking_data {
int num_share_mode_entries;
BOOL delete_on_close;
} s;
- share_mode_entry dummy; /* Needed for alignment. */
+ struct share_mode_entry dummy; /* Needed for alignment. */
} u;
/* the following two entries are implicit
- share_mode_entry modes[num_share_mode_entries];
+ struct share_mode_entry modes[num_share_mode_entries];
char file_name[];
*/
};
@@ -114,9 +120,9 @@ struct locking_data {
* Check if an external smb_share_mode_entry and an internal share_mode entry match.
*/
-static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const share_mode_entry *entry)
+static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const struct share_mode_entry *entry)
{
- return (e_entry->pid == entry->pid &&
+ return (procid_equal(&e_entry->pid, &entry->pid) &&
e_entry->file_id == (uint32_t)entry->share_file_id &&
e_entry->open_time.tv_sec == entry->time.tv_sec &&
e_entry->open_time.tv_usec == entry->time.tv_usec &&
@@ -130,9 +136,9 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, co
* Create an internal Samba share_mode entry from an external smb_share_mode_entry.
*/
-static void create_share_mode_entry(share_mode_entry *out, const struct smb_share_mode_entry *in)
+static void create_share_mode_entry(struct share_mode_entry *out, const struct smb_share_mode_entry *in)
{
- memset(out, '\0', sizeof(share_mode_entry));
+ memset(out, '\0', sizeof(struct share_mode_entry));
out->pid = in->pid;
out->share_file_id = (unsigned long)in->file_id;
@@ -159,7 +165,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
struct smb_share_mode_entry *list = NULL;
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
- share_mode_entry *shares = NULL;
+ struct share_mode_entry *shares = NULL;
size_t i;
int list_num;
@@ -187,19 +193,24 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry));
- shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
+ shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
list_num = 0;
for (i = 0; i < num_share_modes; i++) {
- share_mode_entry *share = &shares[i];
+ struct share_mode_entry *share = &shares[i];
struct smb_share_mode_entry *sme = &list[list_num];
- pid_t pid = share->pid;
+ struct process_id pid = share->pid;
/* Check this process really exists. */
- if (kill(pid, 0) == -1 && (errno == ESRCH)) {
+ if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
continue; /* No longer exists. */
}
+ /* Ignore deferred open entries. */
+ if (share->op_type == DEFERRED_OPEN_ENTRY) {
+ continue;
+ }
+
/* Copy into the external list. */
sme->dev = (uint64_t)share->dev;
sme->ino = (uint64_t)share->inode;
@@ -238,27 +249,27 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
TDB_DATA locking_key = get_locking_key(dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
- share_mode_entry *shares = NULL;
+ struct share_mode_entry *shares = NULL;
char *new_data_p = NULL;
size_t new_data_size = 0;
db_data = tdb_fetch(db_ctx->smb_tdb, locking_key);
if (!db_data.dptr) {
/* We must create the entry. */
- db_data.dptr = malloc((2*sizeof(share_mode_entry)) + strlen(filename) + 1);
+ db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1);
if (!db_data.dptr) {
return -1;
}
ld = (struct locking_data *)db_data.dptr;
ld->u.s.num_share_mode_entries = 1;
ld->u.s.delete_on_close = 0;
- shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
+ shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
create_share_mode_entry(shares, new_entry);
- memcpy(db_data.dptr + 2*sizeof(share_mode_entry),
+ memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry),
filename,
strlen(filename) + 1);
- db_data.dsize = 2*sizeof(share_mode_entry) + strlen(filename) + 1;
+ db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1;
if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) {
free(db_data.dptr);
return -1;
@@ -268,7 +279,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
}
/* Entry exists, we must add a new entry. */
- new_data_p = malloc(db_data.dsize + sizeof(share_mode_entry));
+ new_data_p = malloc(db_data.dsize + sizeof(struct share_mode_entry));
if (!new_data_p) {
free(db_data.dptr);
return -1;
@@ -278,11 +289,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
orig_num_share_modes = ld->u.s.num_share_mode_entries;
/* Copy the original data. */
- memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(share_mode_entry));
+ memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(struct share_mode_entry));
/* Add in the new share mode */
- shares = (share_mode_entry *)(new_data_p +
- ((orig_num_share_modes+1)*sizeof(share_mode_entry)));
+ shares = (struct share_mode_entry *)(new_data_p +
+ ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)));
create_share_mode_entry(shares, new_entry);
@@ -290,11 +301,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
ld->u.s.num_share_mode_entries++;
/* Append the original filename */
- memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(share_mode_entry)),
- db_data.dptr + ((orig_num_share_modes+1)*sizeof(share_mode_entry)),
- db_data.dsize - ((orig_num_share_modes+1) * sizeof(share_mode_entry)));
+ memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(struct share_mode_entry)),
+ db_data.dptr + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)),
+ db_data.dsize - ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)));
- new_data_size = db_data.dsize + sizeof(share_mode_entry);
+ new_data_size = db_data.dsize + sizeof(struct share_mode_entry);
free(db_data.dptr);
@@ -318,7 +329,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
TDB_DATA locking_key = get_locking_key(dev, ino);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
- share_mode_entry *shares = NULL;
+ struct share_mode_entry *shares = NULL;
char *new_data_p = NULL;
size_t filename_size = 0;
size_t i, num_share_modes;
@@ -331,7 +342,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
ld = (struct locking_data *)db_data.dptr;
orig_num_share_modes = ld->u.s.num_share_mode_entries;
- shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
+ shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
if (orig_num_share_modes == 1) {
/* Only one entry - better be ours... */
@@ -346,22 +357,22 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
}
/* More than one - allocate a new record minus the one we'll delete. */
- new_data_p = malloc(db_data.dsize - sizeof(share_mode_entry));
+ new_data_p = malloc(db_data.dsize - sizeof(struct share_mode_entry));
if (!new_data_p) {
free(db_data.dptr);
return -1;
}
/* Copy the header. */
- memcpy(new_data_p, db_data.dptr, sizeof(share_mode_entry));
+ memcpy(new_data_p, db_data.dptr, sizeof(struct share_mode_entry));
num_share_modes = 0;
for (i = 0; i < orig_num_share_modes; i++) {
- share_mode_entry *share = &shares[i];
- pid_t pid = share->pid;
+ struct share_mode_entry *share = &shares[i];
+ struct process_id pid = share->pid;
/* Check this process really exists. */
- if (kill(pid, 0) == -1 && (errno == ESRCH)) {
+ if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
continue; /* No longer exists. */
}
@@ -369,8 +380,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
continue; /* This is our delete taget. */
}
- memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)),
- share, sizeof(share_mode_entry) );
+ memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)),
+ share, sizeof(struct share_mode_entry) );
num_share_modes++;
}
@@ -383,10 +394,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
}
/* Copy the terminating filename. */
- fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(share_mode_entry));
+ fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry));
filename_size = db_data.dsize - (fname_ptr - db_data.dptr);
- memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)),
+ memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)),
fname_ptr,
filename_size);
@@ -398,7 +409,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
ld = (struct locking_data *)db_data.dptr;
ld->u.s.num_share_mode_entries = num_share_modes;
- db_data.dsize = ((num_share_modes+1)*sizeof(share_mode_entry)) + filename_size;
+ db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + filename_size;
if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) {
free(db_data.dptr);
@@ -418,7 +429,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
TDB_DATA locking_key = get_locking_key(dev, ino);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
- share_mode_entry *shares = NULL;
+ struct share_mode_entry *shares = NULL;
size_t i;
int found_entry = 0;
@@ -429,14 +440,14 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
ld = (struct locking_data *)db_data.dptr;
num_share_modes = ld->u.s.num_share_mode_entries;
- shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
+ shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
for (i = 0; i < num_share_modes; i++) {
- share_mode_entry *share = &shares[i];
- pid_t pid = share->pid;
+ struct share_mode_entry *share = &shares[i];
+ struct process_id pid = share->pid;
/* Check this process really exists. */
- if (kill(pid, 0) == -1 && (errno == ESRCH)) {
+ if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
continue; /* No longer exists. */
}
diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index b7f0cd05c3..dc49396d9e 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/libsmb/smbdes.c
@@ -357,78 +357,24 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key,
des_crypt56(out + 8, in + 8, key2, forw);
}
-void SamOEMhash( unsigned char *data, const unsigned char *key, int val)
-{
- unsigned char s_box[256];
- unsigned char index_i = 0;
- unsigned char index_j = 0;
- unsigned char j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++) {
- s_box[ind] = (unsigned char)ind;
- }
-
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
+/*****************************************************************
+ arc4 crypt/decrypt with a 16 byte key.
+*****************************************************************/
- j += (s_box[ind] + key[ind%16]);
-
- tc = s_box[ind];
- s_box[ind] = s_box[j];
- s_box[j] = tc;
- }
- for( ind = 0; ind < val; ind++) {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += s_box[index_i];
-
- tc = s_box[index_i];
- s_box[index_i] = s_box[index_j];
- s_box[index_j] = tc;
+void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len)
+{
+ unsigned char arc4_state[258];
- t = s_box[index_i] + s_box[index_j];
- data[ind] = data[ind] ^ s_box[t];
- }
+ smb_arc4_init(arc4_state, key, 16);
+ smb_arc4_crypt(arc4_state, data, len);
}
-void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key)
+void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key)
{
- unsigned char s_box[256];
- unsigned char index_i = 0;
- unsigned char index_j = 0;
- unsigned char j = 0;
- int ind;
-
- for (ind = 0; ind < 256; ind++) {
- s_box[ind] = (unsigned char)ind;
- }
-
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
-
- j += (s_box[ind] + key->data[ind%key->length]);
-
- tc = s_box[ind];
- s_box[ind] = s_box[j];
- s_box[j] = tc;
- }
- for( ind = 0; ind < len; ind++) {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += s_box[index_i];
+ unsigned char arc4_state[258];
- tc = s_box[index_i];
- s_box[index_i] = s_box[index_j];
- s_box[index_j] = tc;
-
- t = s_box[index_i] + s_box[index_j];
- data[ind] = data[ind] ^ s_box[t];
- }
+ smb_arc4_init(arc4_state, key->data, key->length);
+ smb_arc4_crypt(arc4_state, data, len);
}
/* Decode a sam password hash into a password. The password hash is the
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 8361c35a8e..0c9eacfe4c 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -308,32 +308,6 @@ void SMBsesskeygen_ntv1(const uchar kr[16],
#endif
}
-void SMBsesskeygen_lmv1(const uchar lm_hash[16],
- const uchar lm_resp[24], /* only uses 8 */
- uint8 sess_key[16])
-{
- /* Calculate the LM session key (effective length 40 bits,
- but changes with each session) */
-
- uchar p24[24];
- uchar partial_lm_hash[16];
-
- memcpy(partial_lm_hash, lm_hash, 8);
- memset(partial_lm_hash + 8, 0xbd, 8);
-
- SMBOWFencrypt(lm_hash, lm_resp, p24);
-
- memcpy(sess_key, p24, 16);
- sess_key[5] = 0xe5;
- sess_key[6] = 0x38;
- sess_key[7] = 0xb0;
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("SMBsesskeygen_lmv1:\n"));
- dump_data(100, sess_key, 16);
-#endif
-}
-
void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
const uchar lm_resp[24], /* only uses 8 */
uint8 sess_key[16])
@@ -485,7 +459,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
encode a password buffer with a unicode password. The buffer
is filled with random data to make it harder to attack.
************************************************************/
-BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
+BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags)
{
uchar new_pw[512];
size_t new_pw_len;
@@ -496,7 +470,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len);
- generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len);
+ generate_random_buffer(buffer, 512 - new_pw_len);
/*
* The length of the new password is in the last 4 bytes of
diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c
index a21063e52a..82a06bde2b 100644
--- a/source3/libsmb/smberr.c
+++ b/source3/libsmb/smberr.c
@@ -75,6 +75,7 @@ err_code_struct dos_msgs[] = {
{"ERRlogonfailure",ERRlogonfailure,"Logon failure"},
{"ERRdiskfull",ERRdiskfull,"Disk full"},
{"ERRgeneral",ERRgeneral, "General failure"},
+ {"ERRbaddirectory", ERRbaddirectory, "Bad directory name"},
{"ERRunknownlevel",ERRunknownlevel, "Unknown info level"},
{NULL,-1,NULL}};
diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c
index 2eaec61ed7..2cf3480fce 100644
--- a/source3/libsmb/spnego.c
+++ b/source3/libsmb/spnego.c
@@ -42,11 +42,11 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
asn1_start_tag(asn1, ASN1_CONTEXT(0));
asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- token->mechTypes = SMB_MALLOC_P(char *);
+ token->mechTypes = SMB_MALLOC_P(const char *);
for (i = 0; !asn1->has_error &&
0 < asn1_tag_remaining(asn1); i++) {
token->mechTypes =
- SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2);
+ SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2);
asn1_read_OID(asn1, &token->mechTypes[i]);
}
token->mechTypes[i] = NULL;
diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index aab0d7d151..50fa613e72 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -29,22 +29,36 @@
Caller must have the cli connected to the netlogon pipe
already.
**********************************************************/
-static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
unsigned char orig_trust_passwd_hash[16],
unsigned char new_trust_passwd_hash[16],
uint32 sec_channel_type)
{
NTSTATUS result;
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, lp_workgroup());
- if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) {
- DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
- nt_errstr(result)));
- return result;
+ /* Check if the netlogon pipe is open using schannel. If so we
+ already have valid creds. If not we must set them up. */
+
+ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+
+ result = rpccli_netlogon_setup_creds(cli,
+ cli->cli->desthost,
+ lp_workgroup(),
+ global_myname(),
+ orig_trust_passwd_hash,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
+ nt_errstr(result)));
+ return result;
+ }
}
-
- result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
+
+ result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
@@ -59,7 +73,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
Caller must have already setup the connection to the NETLOGON pipe
**********************************************************/
-NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *domain,
unsigned char orig_trust_passwd_hash[16],
uint32 sec_channel_type)
@@ -99,7 +113,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx
already setup the connection to the NETLOGON pipe
**********************************************************/
-NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
+NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *domain)
{
@@ -116,7 +130,6 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
return trust_pw_change_and_store_it(cli, mem_ctx, domain,
old_trust_passwd_hash,
sec_channel_type);
-
}
/*********************************************************************
@@ -133,6 +146,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
struct in_addr dc_ip;
uint32 enum_ctx = 0;
struct cli_state *cli = NULL;
+ struct rpc_pipe_client *lsa_pipe;
BOOL retry;
*domain_names = NULL;
@@ -156,21 +170,21 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
/* open the LSARPC_PIPE */
- if ( !cli_nt_session_open( cli, PI_LSARPC ) ) {
- result = NT_STATUS_UNSUCCESSFUL;
+ lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
+ if ( !lsa_pipe) {
goto done;
}
/* get a handle */
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
POLICY_VIEW_LOCAL_INFORMATION, &pol);
if ( !NT_STATUS_IS_OK(result) )
goto done;
/* Lookup list of trusted domains */
- result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
+ result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
num_domains, domain_names, sids);
if ( !NT_STATUS_IS_OK(result) )
goto done;
@@ -184,4 +198,3 @@ done:
return NT_STATUS_IS_OK(result);
}
-
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index da7fc1e67d..25a1ed5e2f 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -39,7 +39,7 @@
struct lock_context {
uint16 smbpid;
uint16 tid;
- pid_t pid;
+ struct process_id pid;
};
/* The data in brlock records is an unsorted linear array of these
@@ -89,9 +89,9 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
static BOOL brl_same_context(struct lock_context *ctx1,
struct lock_context *ctx2)
{
- return (ctx1->pid == ctx2->pid) &&
+ return (procid_equal(&ctx1->pid, &ctx2->pid) &&
(ctx1->smbpid == ctx2->smbpid) &&
- (ctx1->tid == ctx2->tid);
+ (ctx1->tid == ctx2->tid));
}
/****************************************************************************
@@ -252,7 +252,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n",
(unsigned int)lock->context.pid ));
- } else if (process_exists(lock->context.pid)) {
+ } else if (process_exists(&lock->context.pid)) {
DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid ));
continue;
@@ -347,7 +347,7 @@ static int lock_compare(struct lock_struct *lck1,
****************************************************************************/
NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
+ uint16 smbpid, struct process_id pid, uint16 tid,
br_off start, br_off size,
enum brl_type lock_type, BOOL *my_lock_ctx)
{
@@ -450,7 +450,7 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe
****************************************************************************/
BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
+ uint16 smbpid, struct process_id pid, uint16 tid,
br_off start, br_off size,
BOOL remove_pending_locks_only,
void (*pre_unlock_fn)(void *),
@@ -542,8 +542,8 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
/* We could send specific lock info here... */
if (brl_pending_overlap(lock, pend_lock)) {
- DEBUG(10,("brl_unlock: sending unlock message to pid %u\n",
- (unsigned int)pend_lock->context.pid ));
+ DEBUG(10,("brl_unlock: sending unlock message to pid %s\n",
+ procid_str_static(&pend_lock->context.pid )));
message_send_pid(pend_lock->context.pid,
MSG_SMB_UNLOCK,
@@ -584,7 +584,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
****************************************************************************/
BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
+ uint16 smbpid, struct process_id pid, uint16 tid,
br_off start, br_off size,
enum brl_type lock_type)
{
@@ -632,7 +632,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
Remove any locks associated with a open file.
****************************************************************************/
-void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
+void brl_close(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, int tid, int fnum)
{
TDB_DATA kbuf, dbuf;
int count, i, j, dcount=0;
@@ -655,7 +655,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
struct lock_struct *lock = &locks[i];
if (lock->context.tid == tid &&
- lock->context.pid == pid &&
+ procid_equal(&lock->context.pid, &pid) &&
lock->fnum == fnum) {
/* Send unlock messages to any pending waiters that overlap. */
@@ -667,7 +667,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
continue;
if (pend_lock->context.tid == tid &&
- pend_lock->context.pid == pid &&
+ procid_equal(&pend_lock->context.pid, &pid) &&
pend_lock->fnum == fnum)
continue;
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 5bcf7f2eda..e3131e26a2 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -43,7 +43,6 @@ uint16 global_smbpid;
/* the locking database handle */
static TDB_CONTEXT *tdb;
-static TDB_CONTEXT *deferred_open_tdb;
struct locking_data {
union {
@@ -51,10 +50,10 @@ struct locking_data {
int num_share_mode_entries;
BOOL delete_on_close;
} s;
- share_mode_entry dummy; /* Needed for alignment. */
+ struct share_mode_entry dummy; /* Needed for alignment. */
} u;
/* the following two entries are implicit
- share_mode_entry modes[num_share_mode_entries];
+ struct share_mode_entry modes[num_share_mode_entries];
char file_name[];
*/
};
@@ -90,17 +89,18 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
ret = 0;
- } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) {
+ } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
+ (lock_type == READ_LOCK)) {
DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
ret = 0;
} else {
ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
- global_smbpid, sys_getpid(), conn->cnum,
+ global_smbpid, procid_self(), conn->cnum,
offset, count, lock_type);
}
} else {
ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
- global_smbpid, sys_getpid(), conn->cnum,
+ global_smbpid, procid_self(), conn->cnum,
offset, count, lock_type);
}
@@ -143,7 +143,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
- lock_pid, sys_getpid(), conn->cnum,
+ lock_pid, procid_self(), conn->cnum,
offset, count,
lock_type, my_lock_ctx);
@@ -166,7 +166,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
* lock entry.
*/
(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- lock_pid, sys_getpid(), conn->cnum,
+ lock_pid, procid_self(), conn->cnum,
offset, count, False,
NULL, NULL);
}
@@ -264,7 +264,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
posix_data.count = count;
ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- lock_pid, sys_getpid(), conn->cnum, offset, count,
+ lock_pid, procid_self(), conn->cnum, offset, count,
False, posix_unlock, (void *)&posix_data);
if (!ok) {
@@ -280,7 +280,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
void locking_close_file(files_struct *fsp)
{
- pid_t pid = sys_getpid();
+ struct process_id pid = procid_self();
if (!lp_locking(SNUM(fsp->conn)))
return;
@@ -324,20 +324,6 @@ BOOL locking_init(int read_only)
return False;
}
- if (!read_only && !deferred_open_tdb) {
- deferred_open_tdb = tdb_open_log(lock_path("deferred_open.tdb"),
- 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST,
- O_RDWR|O_CREAT,
- 0644);
-
- if (!deferred_open_tdb) {
- DEBUG(0,("ERROR: Failed to initialise deferred open database\n"));
- tdb_close(tdb);
- tdb = NULL;
- return False;
- }
- }
-
if (!posix_locking_init(read_only))
return False;
@@ -360,11 +346,6 @@ BOOL locking_end(void)
ret = False;
}
- if (deferred_open_tdb) {
- if (tdb_close(deferred_open_tdb) != 0)
- ret = False;
- }
-
return ret;
}
@@ -372,6 +353,16 @@ BOOL locking_end(void)
Form a static locking key for a dev/inode pair.
******************************************************************/
+/* key and data records in the tdb locking database */
+struct locking_key {
+ SMB_DEV_T dev;
+ SMB_INO_T ino;
+};
+
+/*******************************************************************
+ Form a static locking key for a dev/inode pair.
+******************************************************************/
+
static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
{
static struct locking_key key;
@@ -379,70 +370,27 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
memset(&key, '\0', sizeof(key));
key.dev = dev;
- key.inode = inode;
+ key.ino = inode;
kbuf.dptr = (char *)&key;
kbuf.dsize = sizeof(key);
return kbuf;
}
-static TDB_DATA locking_key_fsp(files_struct *fsp)
-{
- return locking_key(fsp->dev, fsp->inode);
-}
-
-/*******************************************************************
- Lock a hash bucket entry.
-******************************************************************/
-
-BOOL lock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode)
-{
- return tdb_chainlock(tdb, locking_key(dev, inode)) == 0;
-}
-
-/*******************************************************************
- Unlock a hash bucket entry.
-******************************************************************/
-
-void unlock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode)
-{
- tdb_chainunlock(tdb, locking_key(dev, inode));
-}
-
-/*******************************************************************
- Lock a hash bucket entry. use a fsp for convenience
-******************************************************************/
-
-BOOL lock_share_entry_fsp(files_struct *fsp)
-{
- return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
-}
-
-/*******************************************************************
- Unlock a hash bucket entry.
-******************************************************************/
-
-void unlock_share_entry_fsp(files_struct *fsp)
-{
- tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode));
-}
-
/*******************************************************************
Print out a share mode.
********************************************************************/
-char *share_mode_str(int num, share_mode_entry *e)
+char *share_mode_str(int num, struct share_mode_entry *e)
{
static pstring share_str;
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: "
- "pid = %lu, share_access = 0x%x, private_options = 0x%x, "
- "access_mask = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, "
+ "pid = %s, share_access = 0x%x, private_options = 0x%x, "
+ "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
"dev = 0x%x, inode = %.0f",
- num, (unsigned long)e->pid,
+ num, procid_str_static(&e->pid),
e->share_access, e->private_options,
- e->access_mask, e->op_port, e->op_type, e->share_file_id,
+ e->access_mask, e->op_mid, e->op_type, e->share_file_id,
(unsigned int)e->dev, (double)e->inode );
return share_str;
@@ -455,12 +403,14 @@ char *share_mode_str(int num, share_mode_entry *e)
static void print_share_mode_table(struct locking_data *data)
{
int num_share_modes = data->u.s.num_share_mode_entries;
- share_mode_entry *shares = (share_mode_entry *)(data + 1);
+ struct share_mode_entry *shares =
+ (struct share_mode_entry *)(data + 1);
int i;
for (i = 0; i < num_share_modes; i++) {
- share_mode_entry *entry_p = &shares[i];
- DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) ));
+ struct share_mode_entry *entry_p = &shares[i];
+ DEBUG(10,("print_share_mode_table: %s\n",
+ share_mode_str(i, entry_p)));
}
}
@@ -468,825 +418,581 @@ static void print_share_mode_table(struct locking_data *data)
Get all share mode entries for a dev/inode pair.
********************************************************************/
-int get_share_modes(SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry **pp_shares,
- BOOL *delete_on_close)
+static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
{
- TDB_DATA dbuf;
struct locking_data *data;
- int num_share_modes;
- share_mode_entry *shares = NULL;
- TDB_DATA key = locking_key(dev, inode);
- *pp_shares = NULL;
- *delete_on_close = False;
-
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr)
- return 0;
-
- data = (struct locking_data *)dbuf.dptr;
+ int i;
- *delete_on_close = data->u.s.delete_on_close;
- DEBUG(10, ("get_share_modes: delete_on_close: %d\n",
- *delete_on_close));
- num_share_modes = data->u.s.num_share_mode_entries;
- if(num_share_modes) {
- pstring fname;
- int i;
- int del_count = 0;
-
- shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data),
- num_share_modes * sizeof(share_mode_entry));
-
- if (!shares) {
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
+ if (dbuf.dsize < sizeof(struct locking_data)) {
+ DEBUG(0, ("parse_share_modes: buffer too short\n"));
+ return False;
+ }
- /* Save off the associated filename. */
- pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry));
+ data = (struct locking_data *)dbuf.dptr;
- /*
- * Ensure that each entry has a real process attached.
- */
+ lck->delete_on_close = data->u.s.delete_on_close;
+ lck->num_share_modes = data->u.s.num_share_mode_entries;
- for (i = 0; i < num_share_modes; ) {
- share_mode_entry *entry_p = &shares[i];
- if (process_exists(entry_p->pid)) {
- DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) ));
- i++;
- } else {
- DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) ));
- if (num_share_modes - i - 1 > 0) {
- memcpy( &shares[i], &shares[i+1],
- sizeof(share_mode_entry) * (num_share_modes - i - 1));
- }
- num_share_modes--;
- del_count++;
- }
- }
+ DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
+ "num_share_modes: %d\n", lck->delete_on_close,
+ lck->num_share_modes));
- /* Did we delete any ? If so, re-store in tdb. */
- if (del_count) {
- data->u.s.num_share_mode_entries = num_share_modes;
-
- if (num_share_modes) {
- memcpy(dbuf.dptr + sizeof(*data), shares,
- num_share_modes * sizeof(share_mode_entry));
- /* Append the filename. */
- pstrcpy(dbuf.dptr + sizeof(*data) + num_share_modes * sizeof(share_mode_entry), fname);
- }
-
- /* The record has shrunk a bit */
- dbuf.dsize -= del_count * sizeof(share_mode_entry);
-
- if (data->u.s.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1) {
- SAFE_FREE(shares);
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
- } else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
- SAFE_FREE(shares);
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
- }
- }
+ if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
+ DEBUG(0, ("invalid number of share modes: %d\n",
+ lck->num_share_modes));
+ return False;
}
- SAFE_FREE(dbuf.dptr);
- *pp_shares = shares;
- return num_share_modes;
-}
+ lck->share_modes = NULL;
-BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
-{
- share_mode_entry *shares;
- BOOL result;
- get_share_modes(dev, inode, &shares, &result);
- SAFE_FREE(shares);
- return result;
-}
+ if (lck->num_share_modes != 0) {
-/*******************************************************************
- Fill a share mode entry.
-********************************************************************/
+ if (dbuf.dsize < (sizeof(struct locking_data) +
+ (lck->num_share_modes *
+ sizeof(struct share_mode_entry)))) {
+ DEBUG(0, ("parse_share_modes: buffer too short\n"));
+ return False;
+ }
+
+ lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
+ lck->num_share_modes *
+ sizeof(struct share_mode_entry));
-static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
-{
- share_mode_entry *e = (share_mode_entry *)p;
- void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
+ if (lck->share_modes == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return False;
+ }
+ }
- memset(e, '\0', sizeof(share_mode_entry));
- e->pid = sys_getpid();
- e->share_access = fsp->share_access;
- e->private_options = fsp->fh->private_options;
- e->access_mask = fsp->access_mask;
- e->op_port = port;
- e->op_type = op_type;
- memcpy(x, &fsp->open_time, sizeof(struct timeval));
- e->share_file_id = fsp->file_id;
- e->dev = fsp->dev;
- e->inode = fsp->inode;
-}
+ /* Save off the associated filename. */
+ lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
+ lck->num_share_modes *
+ sizeof(struct share_mode_entry));
-/*******************************************************************
- Check if two share mode entries are identical, ignoring oplock
- and port info and desired_access.
-********************************************************************/
+ /*
+ * Ensure that each entry has a real process attached.
+ */
-BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
-{
-#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
- if (e1->pid == e2->pid &&
- e1->share_file_id == e2->share_file_id &&
- e1->dev == e2->dev &&
- e1->inode == e2->inode &&
- (e1->share_access) != (e2->share_access)) {
- DEBUG(0,("PANIC: share_modes_identical: share_mode "
- "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
- (unsigned int)e1->share_access,
- (unsigned int)e2->share_access ));
- smb_panic("PANIC: share_modes_identical logic error.\n");
+ for (i = 0; i < lck->num_share_modes; i++) {
+ struct share_mode_entry *entry_p = &lck->share_modes[i];
+ DEBUG(10,("parse_share_modes: %s\n",
+ share_mode_str(i, entry_p) ));
+ if (!process_exists(entry_p->pid)) {
+ DEBUG(10,("parse_share_modes: deleted %s\n",
+ share_mode_str(i, entry_p) ));
+ entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
+ lck->modified = True;
+ }
}
-#endif
- return (e1->pid == e2->pid &&
- (e1->share_access) == (e2->share_access) &&
- e1->dev == e2->dev &&
- e1->inode == e2->inode &&
- e1->share_file_id == e2->share_file_id );
+ return True;
}
-/*******************************************************************
- Delete a specific share mode. Return the number
- of entries left, and a memdup'ed copy of the entry deleted (if required).
- Ignore if no entry deleted.
-********************************************************************/
-
-ssize_t del_share_entry(SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry *entry, share_mode_entry **ppse,
- BOOL *delete_on_close)
+static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
{
- TDB_DATA dbuf;
+ TDB_DATA result;
+ int num_valid = 0;
+ int i;
struct locking_data *data;
- int i, del_count=0;
- share_mode_entry *shares;
- ssize_t count = 0;
- TDB_DATA key = locking_key(dev, inode);
-
- if (ppse)
- *ppse = NULL;
-
- /* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr)
- return -1;
-
- data = (struct locking_data *)dbuf.dptr;
- *delete_on_close = data->u.s.delete_on_close;
- shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
-
- /*
- * Find any with this pid and delete it
- * by overwriting with the rest of the data
- * from the record.
- */
-
- DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.s.num_share_mode_entries ));
-
- for (i=0;i<data->u.s.num_share_mode_entries;) {
- if (share_modes_identical(&shares[i], entry)) {
- DEBUG(10,("del_share_entry: deleted %s\n",
- share_mode_str(i, &shares[i]) ));
- if (ppse)
- *ppse = memdup(&shares[i], sizeof(*shares));
- data->u.s.num_share_mode_entries--;
- if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))) > 0) {
- memmove(&shares[i], &shares[i+1],
- dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
- }
- del_count++;
+ ssize_t offset;
- DEBUG(10,("del_share_entry: deleting entry %d\n", i ));
+ result.dptr = NULL;
+ result.dsize = 0;
- } else {
- i++;
+ for (i=0; i<lck->num_share_modes; i++) {
+ if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
+ num_valid += 1;
}
}
- if (del_count) {
- /* the record may have shrunk a bit */
- dbuf.dsize -= del_count * sizeof(*shares);
-
- count = (ssize_t)data->u.s.num_share_mode_entries;
-
- /* store it back in the database */
- if (data->u.s.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
- count = -1;
- } else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
- count = -1;
- }
+ if (num_valid == 0) {
+ return result;
}
- DEBUG(10,("del_share_entry: Remaining table.\n"));
- print_share_mode_table((struct locking_data *)dbuf.dptr);
- SAFE_FREE(dbuf.dptr);
- return count;
-}
-/*******************************************************************
- Del the share mode of a file for this process. Return the number
- of entries left, and a memdup'ed copy of the entry deleted.
-********************************************************************/
-
-ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse,
- BOOL *delete_on_close)
-{
- share_mode_entry entry;
+ result.dsize = sizeof(*data) +
+ lck->num_share_modes * sizeof(struct share_mode_entry) +
+ strlen(lck->filename) + 1;
+ result.dptr = talloc_size(lck, result.dsize);
- /*
- * Fake up a share_mode_entry for comparisons.
- */
+ if (result.dptr == NULL) {
+ smb_panic("talloc failed\n");
+ }
- fill_share_mode((char *)&entry, fsp, 0, 0);
- return del_share_entry(fsp->dev, fsp->inode, &entry, ppse,
- delete_on_close);
+ data = (struct locking_data *)result.dptr;
+ ZERO_STRUCTP(data);
+ data->u.s.num_share_mode_entries = lck->num_share_modes;
+ data->u.s.delete_on_close = lck->delete_on_close;
+ DEBUG(10, ("unparse_share_modes: del: %d, num: %d\n",
+ data->u.s.delete_on_close,
+ data->u.s.num_share_mode_entries));
+ memcpy(result.dptr + sizeof(*data), lck->share_modes,
+ sizeof(struct share_mode_entry)*lck->num_share_modes);
+ offset = sizeof(*data) +
+ sizeof(struct share_mode_entry)*lck->num_share_modes;
+ safe_strcpy(result.dptr + offset, lck->filename,
+ result.dsize - offset - 1);
+ print_share_mode_table(data);
+ return result;
}
-/*******************************************************************
- Set the share mode of a file. Return False on fail, True on success.
-********************************************************************/
-
-BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
+static int share_mode_lock_destructor(void *p)
{
- TDB_DATA dbuf;
- struct locking_data *data;
- char *p=NULL;
- int size;
- TDB_DATA key = locking_key_fsp(fsp);
- BOOL ret = True;
-
- /* read in the existing share modes if any */
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr) {
- size_t offset;
- /* we'll need to create a new record */
- pstring fname;
-
- pstrcpy(fname, fsp->conn->connectpath);
- pstrcat(fname, "/");
- pstrcat(fname, fsp->fsp_name);
-
- size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1;
- p = (char *)SMB_MALLOC(size);
- if (!p)
- return False;
- data = (struct locking_data *)p;
- ZERO_STRUCT(data->u); /* Keep valgrind happy */
- data->u.s.num_share_mode_entries = 1;
-
- DEBUG(10,("set_share_mode: creating entry for file %s. num_share_modes = 1\n",
- fsp->fsp_name ));
+ struct share_mode_lock *lck =
+ talloc_get_type_abort(p, struct share_mode_lock);
+ TDB_DATA key = locking_key(lck->dev, lck->ino);
+ TDB_DATA data;
- offset = sizeof(*data) + sizeof(share_mode_entry);
- safe_strcpy(p + offset, fname, size - offset - 1);
- fill_share_mode(p + sizeof(*data), fsp, port, op_type);
- dbuf.dptr = p;
- dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
+ if (!lck->modified) {
+ goto done;
+ }
- print_share_mode_table((struct locking_data *)p);
+ data = unparse_share_modes(lck);
- SAFE_FREE(p);
- return ret;
+ if (data.dptr == NULL) {
+ if (!lck->fresh) {
+ /* There has been an entry before, delete it */
+ if (tdb_delete(tdb, key) == -1) {
+ smb_panic("Could not delete share entry\n");
+ }
+ }
+ goto done;
}
- /* we're adding to an existing entry - this is a bit fiddly */
- data = (struct locking_data *)dbuf.dptr;
+ if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
+ smb_panic("Could not store share mode entry\n");
+ }
- data->u.s.num_share_mode_entries++;
-
- DEBUG(10,("set_share_mode: adding entry for file %s. new num_share_modes = %d\n",
- fsp->fsp_name, data->u.s.num_share_mode_entries ));
+ done:
+ tdb_chainunlock(tdb, key);
- size = dbuf.dsize + sizeof(share_mode_entry);
- p = SMB_MALLOC(size);
- if (!p) {
- SAFE_FREE(dbuf.dptr);
- return False;
- }
- memcpy(p, dbuf.dptr, sizeof(*data));
- fill_share_mode(p + sizeof(*data), fsp, port, op_type);
- memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
- dbuf.dsize - sizeof(*data));
- SAFE_FREE(dbuf.dptr);
- dbuf.dptr = p;
- dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
- print_share_mode_table((struct locking_data *)p);
- SAFE_FREE(p);
- return ret;
+ return 0;
}
-/*******************************************************************
- A generic in-place modification call for share mode entries.
-********************************************************************/
-
-static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry,
- void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
- void *param)
+struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
+ SMB_DEV_T dev, SMB_INO_T ino,
+ const char *fname)
{
- TDB_DATA dbuf;
- struct locking_data *data;
- int i;
- share_mode_entry *shares;
- BOOL need_store=False;
- BOOL ret = True;
- TDB_DATA key = locking_key(dev, inode);
-
- /* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr)
- return False;
+ struct share_mode_lock *lck;
+ TDB_DATA key = locking_key(dev, ino);
+ TDB_DATA data;
- data = (struct locking_data *)dbuf.dptr;
- shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+ lck = TALLOC_P(mem_ctx, struct share_mode_lock);
+ if (lck == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
- /* find any with our pid and call the supplied function */
- for (i=0;i<data->u.s.num_share_mode_entries;i++) {
- if (share_modes_identical(entry, &shares[i])) {
- mod_fn(&shares[i], dev, inode, param);
- need_store=True;
- }
+ lck->dev = dev;
+ lck->ino = ino;
+ lck->delete_on_close = False;
+ lck->num_share_modes = 0;
+ lck->share_modes = NULL;
+ lck->modified = False;
+
+ if (tdb_chainlock(tdb, key) != 0) {
+ DEBUG(3, ("Could not lock share entry\n"));
+ talloc_free(lck);
+ return NULL;
}
- /* if the mod fn was called then store it back */
- if (need_store) {
- if (data->u.s.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
- ret = False;
- } else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
+ data = tdb_fetch(tdb, key);
+ lck->fresh = (data.dptr == NULL);
+
+ if (lck->fresh) {
+ if (fname == NULL) {
+ DEBUG(0, ("New file, but no filename supplied\n"));
+ talloc_free(lck);
+ return NULL;
+ }
+ lck->filename = talloc_strdup(lck, fname);
+ if (lck->filename == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ talloc_free(lck);
+ return NULL;
+ }
+ } else {
+ if (!parse_share_modes(data, lck)) {
+ DEBUG(0, ("Could not parse share modes\n"));
+ talloc_free(lck);
+ SAFE_FREE(data.dptr);
+ return NULL;
}
}
- SAFE_FREE(dbuf.dptr);
- return ret;
-}
+ talloc_set_destructor(lck, share_mode_lock_destructor);
+ SAFE_FREE(data.dptr);
-/*******************************************************************
- Static function that actually does the work for the generic function
- below.
-********************************************************************/
+ return lck;
+}
-static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
- void *param)
+BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
+ const char *fname)
{
- DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode ));
- /* Delete the oplock info. */
- entry->op_port = 0;
- entry->op_type = NO_OPLOCK;
+ BOOL result;
+ struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode,
+ fname);
+ result = lck->delete_on_close;
+ talloc_free(lck);
+ return result;
}
-/*******************************************************************
- Remove an oplock port and mode entry from a share mode.
-********************************************************************/
-
-BOOL remove_share_oplock(files_struct *fsp)
+BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
{
- share_mode_entry entry;
- /*
- * Fake up an entry for comparisons...
- */
- fill_share_mode((char *)&entry, fsp, 0, 0);
- return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL);
+ int num_props = 0;
+
+ num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
+ num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
+ num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
+
+ SMB_ASSERT(num_props <= 1);
+ return (num_props != 0);
}
-/*******************************************************************
- Static function that actually does the work for the generic function
- below.
-********************************************************************/
+BOOL is_deferred_open_entry(const struct share_mode_entry *e)
+{
+ return (e->op_type == DEFERRED_OPEN_ENTRY);
+}
-static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
- void *param)
+BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
{
- DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode ));
- entry->op_type = LEVEL_II_OPLOCK;
+ return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
}
/*******************************************************************
- Downgrade a oplock type from exclusive to level II.
+ Fill a share mode entry.
********************************************************************/
-BOOL downgrade_share_oplock(files_struct *fsp)
+static void fill_share_mode_entry(struct share_mode_entry *e,
+ files_struct *fsp,
+ uint16 mid, uint16 op_type)
{
- share_mode_entry entry;
- /*
- * Fake up an entry for comparisons...
- */
- fill_share_mode((char *)&entry, fsp, 0, 0);
- return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL);
+ ZERO_STRUCTP(e);
+ e->pid = procid_self();
+ e->share_access = fsp->share_access;
+ e->private_options = fsp->fh->private_options;
+ e->access_mask = fsp->access_mask;
+ e->op_mid = mid;
+ e->op_type = op_type;
+ e->time.tv_sec = fsp->open_time.tv_sec;
+ e->time.tv_usec = fsp->open_time.tv_usec;
+ e->share_file_id = fsp->file_id;
+ e->dev = fsp->dev;
+ e->inode = fsp->inode;
}
-/*******************************************************************
- Get/Set the delete on close flag in a set of share modes.
- Return False on fail, True on success.
-********************************************************************/
-
-BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
+static void fill_deferred_open_entry(struct share_mode_entry *e,
+ const struct timeval request_time,
+ SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
{
- TDB_DATA dbuf;
- struct locking_data *data;
- BOOL res;
- TDB_DATA key = locking_key(dev, inode);
+ ZERO_STRUCTP(e);
+ e->pid = procid_self();
+ e->op_mid = mid;
+ e->op_type = DEFERRED_OPEN_ENTRY;
+ e->time.tv_sec = request_time.tv_sec;
+ e->time.tv_usec = request_time.tv_usec;
+ e->dev = dev;
+ e->inode = ino;
+}
- /* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
- if (!dbuf.dptr)
- return False;
+static void add_share_mode_entry(struct share_mode_lock *lck,
+ const struct share_mode_entry *entry)
+{
+ int i;
- data = (struct locking_data *)dbuf.dptr;
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if (is_unused_share_mode_entry(e)) {
+ *e = *entry;
+ break;
+ }
+ }
- /* Set/Unset the delete on close element. */
- data->u.s.delete_on_close = delete_on_close;
+ if (i == lck->num_share_modes) {
+ /* No unused entry found */
+ ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
+ &lck->share_modes, &lck->num_share_modes);
+ }
+ lck->modified = True;
+}
- res = (tdb_store(tdb, key, dbuf, TDB_REPLACE)!=-1);
+void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
+ uint16 mid, uint16 op_type)
+{
+ struct share_mode_entry entry;
+ fill_share_mode_entry(&entry, fsp, mid, op_type);
+ add_share_mode_entry(lck, &entry);
+}
- SAFE_FREE(dbuf.dptr);
- return res;
+void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
+ struct timeval request_time,
+ SMB_DEV_T dev, SMB_INO_T ino)
+{
+ struct share_mode_entry entry;
+ fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
+ add_share_mode_entry(lck, &entry);
}
/*******************************************************************
- Print out a deferred open entry.
+ Check if two share mode entries are identical, ignoring oplock
+ and mid info and desired_access.
********************************************************************/
-char *deferred_open_str(int num, deferred_open_entry *e)
+static BOOL share_modes_identical(struct share_mode_entry *e1,
+ struct share_mode_entry *e2)
{
- static pstring de_str;
-
- slprintf(de_str, sizeof(de_str)-1, "deferred_open_entry[%d]: \
-pid = %lu, mid = %u, dev = 0x%x, inode = %.0f, port = %u, time = [%u.%06u]",
- num, (unsigned long)e->pid, (unsigned int)e->mid, (unsigned int)e->dev, (double)e->inode,
- (unsigned int)e->port,
- (unsigned int)e->time.tv_sec, (unsigned int)e->time.tv_usec );
+#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
+ if (procid_equal(&e1->pid, &e2->pid) &&
+ e1->share_file_id == e2->share_file_id &&
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ (e1->share_access) != (e2->share_access)) {
+ DEBUG(0,("PANIC: share_modes_identical: share_mode "
+ "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
+ (unsigned int)e1->share_access,
+ (unsigned int)e2->share_access ));
+ smb_panic("PANIC: share_modes_identical logic error.\n");
+ }
+#endif
- return de_str;
+ return (procid_equal(&e1->pid, &e2->pid) &&
+ (e1->share_access) == (e2->share_access) &&
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ e1->share_file_id == e2->share_file_id );
}
-/* Internal data structures for deferred opens... */
+static BOOL deferred_open_identical(struct share_mode_entry *e1,
+ struct share_mode_entry *e2)
+{
+ return (procid_equal(&e1->pid, &e2->pid) &&
+ (e1->op_mid == e2->op_mid) &&
+ (e1->dev == e2->dev) &&
+ (e1->inode == e2->inode));
+}
-struct de_locking_key {
- char name[4];
- SMB_DEV_T dev;
- SMB_INO_T inode;
-};
+static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
+ struct share_mode_entry *entry)
+{
+ int i;
-struct deferred_open_data {
- union {
- int num_deferred_open_entries;
- deferred_open_entry dummy; /* Needed for alignment. */
- } u;
- /* the following two entries are implicit
- deferred_open_entry de_entries[num_deferred_open_entries];
- char file_name[];
- */
-};
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if (is_valid_share_mode_entry(entry) &&
+ is_valid_share_mode_entry(e) &&
+ share_modes_identical(e, entry)) {
+ return e;
+ }
+ if (is_deferred_open_entry(entry) &&
+ is_deferred_open_entry(e) &&
+ deferred_open_identical(e, entry)) {
+ return e;
+ }
+ }
+ return NULL;
+}
/*******************************************************************
- Print out a deferred open table.
+ Del the share mode of a file for this process. Return the number of
+ entries left.
********************************************************************/
-static void print_deferred_open_table(struct deferred_open_data *data)
+BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
{
- int num_de_entries = data->u.num_deferred_open_entries;
- deferred_open_entry *de_entries = (deferred_open_entry *)(data + 1);
- int i;
+ struct share_mode_entry entry, *e;
+
+ fill_share_mode_entry(&entry, fsp, 0, 0);
- for (i = 0; i < num_de_entries; i++) {
- deferred_open_entry *entry_p = &de_entries[i];
- DEBUG(10,("print_deferred_open_table: %s\n", deferred_open_str(i, entry_p) ));
+ e = find_share_mode_entry(lck, &entry);
+ if (e == NULL) {
+ return False;
}
+
+ e->op_type = UNUSED_SHARE_MODE_ENTRY;
+ lck->modified = True;
+ return True;
}
+void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
+{
+ struct share_mode_entry entry, *e;
-/*******************************************************************
- Form a static deferred open locking key for a dev/inode pair.
-******************************************************************/
+ fill_deferred_open_entry(&entry, timeval_zero(),
+ lck->dev, lck->ino, mid);
-static TDB_DATA deferred_open_locking_key(SMB_DEV_T dev, SMB_INO_T inode)
-{
- static struct de_locking_key key;
- TDB_DATA kbuf;
+ e = find_share_mode_entry(lck, &entry);
+ if (e == NULL) {
+ return;
+ }
- memset(&key, '\0', sizeof(key));
- memcpy(&key.name[0], "DOE", 4);
- key.dev = dev;
- key.inode = inode;
- kbuf.dptr = (char *)&key;
- kbuf.dsize = sizeof(key);
- return kbuf;
+ e->op_type = UNUSED_SHARE_MODE_ENTRY;
+ lck->modified = True;
}
/*******************************************************************
- Get all deferred open entries for a dev/inode pair.
+ Remove an oplock mid and mode entry from a share mode.
********************************************************************/
-int get_deferred_opens(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode,
- deferred_open_entry **pp_de_entries)
+BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
{
- TDB_DATA dbuf;
- struct deferred_open_data *data;
- int num_de_entries;
- deferred_open_entry *de_entries = NULL;
- TDB_DATA key = deferred_open_locking_key(dev, inode);
+ struct share_mode_entry entry, *e;
- *pp_de_entries = NULL;
+ fill_share_mode_entry(&entry, fsp, 0, 0);
- dbuf = tdb_fetch(deferred_open_tdb, key);
- if (!dbuf.dptr)
- return 0;
-
- data = (struct deferred_open_data *)dbuf.dptr;
- num_de_entries = data->u.num_deferred_open_entries;
- if(num_de_entries) {
- pstring fname;
- int i;
- int del_count = 0;
-
- de_entries = (deferred_open_entry *)memdup(dbuf.dptr + sizeof(*data),
- num_de_entries * sizeof(deferred_open_entry));
-
- if (!de_entries) {
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
+ e = find_share_mode_entry(lck, &entry);
+ if (e == NULL) {
+ return False;
+ }
- /* Save off the associated filename. */
- pstrcpy(fname, dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry));
+ e->op_mid = 0;
+ e->op_type = NO_OPLOCK;
+ lck->modified = True;
+ return True;
+}
- /*
- * Ensure that each entry has a real process attached.
- */
+/*******************************************************************
+ Downgrade a oplock type from exclusive to level II.
+********************************************************************/
- for (i = 0; i < num_de_entries; ) {
- deferred_open_entry *entry_p = &de_entries[i];
- if (process_exists(entry_p->pid)) {
- DEBUG(10,("get_deferred_opens: %s\n", deferred_open_str(i, entry_p) ));
- i++;
- } else {
- DEBUG(10,("get_deferred_opens: deleted %s\n", deferred_open_str(i, entry_p) ));
- if (num_de_entries - i - 1 > 0) {
- memcpy( &de_entries[i], &de_entries[i+1],
- sizeof(deferred_open_entry) * (num_de_entries - i - 1));
- }
- num_de_entries--;
- del_count++;
- }
- }
+BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
+{
+ struct share_mode_entry entry, *e;
- /* Did we delete any ? If so, re-store in tdb. */
- if (del_count) {
- data->u.num_deferred_open_entries = num_de_entries;
-
- if (num_de_entries) {
- memcpy(dbuf.dptr + sizeof(*data), de_entries,
- num_de_entries * sizeof(deferred_open_entry));
- /* Append the filename. */
- pstrcpy(dbuf.dptr + sizeof(*data) + num_de_entries * sizeof(deferred_open_entry), fname);
- }
+ fill_share_mode_entry(&entry, fsp, 0, 0);
- /* The record has shrunk a bit */
- dbuf.dsize -= del_count * sizeof(deferred_open_entry);
-
- if (data->u.num_deferred_open_entries == 0) {
- if (tdb_delete(deferred_open_tdb, key) == -1) {
- SAFE_FREE(de_entries);
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
- } else {
- if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1) {
- SAFE_FREE(de_entries);
- SAFE_FREE(dbuf.dptr);
- return 0;
- }
- }
- }
+ e = find_share_mode_entry(lck, &entry);
+ if (e == NULL) {
+ return False;
}
- SAFE_FREE(dbuf.dptr);
- *pp_de_entries = de_entries;
- return num_de_entries;
+ e->op_type = LEVEL_II_OPLOCK;
+ lck->modified = True;
+ return True;
}
+
/*******************************************************************
- Check if two deferred open entries are identical.
+ We've just told all the smbd's that our level2 or fake level2 has been
+ written to.
********************************************************************/
-
-static BOOL deferred_open_entries_identical( deferred_open_entry *e1, deferred_open_entry *e2)
+BOOL remove_all_share_oplocks(struct share_mode_lock *lck, files_struct *fsp)
{
- return (e1->pid == e2->pid &&
- e1->mid == e2->mid &&
- e1->port == e2->port &&
- e1->dev == e2->dev &&
- e1->inode == e2->inode &&
- e1->time.tv_sec == e2->time.tv_sec &&
- e1->time.tv_usec == e2->time.tv_usec);
+ int i;
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if (!is_valid_share_mode_entry(e)) {
+ continue;
+ }
+ if (e->op_type == NO_OPLOCK) {
+ continue;
+ }
+ e->op_type = NO_OPLOCK;
+ lck->modified = True;
+ }
+ return True;
}
-/*******************************************************************
- Delete a specific deferred open entry.
- Ignore if no entry deleted.
-********************************************************************/
+/****************************************************************************
+ Deal with the internal needs of setting the delete on close flag. Note that
+ as the tdb locking is recursive, it is safe to call this from within
+ open_file_shared. JRA.
+****************************************************************************/
-BOOL delete_deferred_open_entry(deferred_open_entry *entry)
+NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
+ uint32 dosmode)
{
- TDB_DATA dbuf;
- struct deferred_open_data *data;
- int i, del_count=0;
- deferred_open_entry *de_entries;
- BOOL ret = True;
- TDB_DATA key = deferred_open_locking_key(entry->dev, entry->inode);
-
- /* read in the existing share modes */
- dbuf = tdb_fetch(deferred_open_tdb, key);
- if (!dbuf.dptr)
- return -1;
-
- data = (struct deferred_open_data *)dbuf.dptr;
- de_entries = (deferred_open_entry *)(dbuf.dptr + sizeof(*data));
+ if (!delete_on_close) {
+ return NT_STATUS_OK;
+ }
/*
- * Find any with this pid and delete it
- * by overwriting with the rest of the data
- * from the record.
+ * Only allow delete on close for writable files.
*/
- DEBUG(10,("delete_deferred_open_entry: num_deferred_open_entries = %d\n",
- data->u.num_deferred_open_entries ));
-
- for (i=0;i<data->u.num_deferred_open_entries;) {
- if (deferred_open_entries_identical(&de_entries[i], entry)) {
- DEBUG(10,("delete_deferred_open_entry: deleted %s\n",
- deferred_open_str(i, &de_entries[i]) ));
-
- data->u.num_deferred_open_entries--;
- if ((dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries))) > 0) {
- memmove(&de_entries[i], &de_entries[i+1],
- dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*de_entries)));
- }
- del_count++;
-
- DEBUG(10,("delete_deferred_open_entry: deleting entry %d\n", i ));
-
- } else {
- i++;
- }
+ if ((dosmode & aRONLY) &&
+ !lp_delete_readonly(SNUM(fsp->conn))) {
+ DEBUG(10,("can_set_delete_on_close: file %s delete on close "
+ "flag set but file attribute is readonly.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_CANNOT_DELETE;
}
- SMB_ASSERT(del_count == 0 || del_count == 1);
-
- if (del_count) {
- /* the record may have shrunk a bit */
- dbuf.dsize -= del_count * sizeof(*de_entries);
+ /*
+ * Only allow delete on close for writable shares.
+ */
- /* store it back in the database */
- if (data->u.num_deferred_open_entries == 0) {
- if (tdb_delete(deferred_open_tdb, key) == -1)
- ret = False;
- } else {
- if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
- }
+ if (!CAN_WRITE(fsp->conn)) {
+ DEBUG(10,("can_set_delete_on_close: file %s delete on "
+ "close flag set but write access denied on share.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_ACCESS_DENIED;
}
- DEBUG(10,("delete_deferred_open_entry: Remaining table.\n"));
- print_deferred_open_table((struct deferred_open_data*)dbuf.dptr);
- SAFE_FREE(dbuf.dptr);
- return ret;
-}
-/*******************************************************************
- Fill a deferred open entry.
-********************************************************************/
+ /*
+ * Only allow delete on close for files/directories opened with delete
+ * intent.
+ */
-static void fill_deferred_open(char *p, uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port)
-{
- deferred_open_entry *e = (deferred_open_entry *)p;
- void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
+ if (!(fsp->access_mask & DELETE_ACCESS)) {
+ DEBUG(10,("can_set_delete_on_close: file %s delete on "
+ "close flag set but delete access denied.\n",
+ fsp->fsp_name ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
- memset(e, '\0', sizeof(deferred_open_entry));
- e->mid = mid;
- e->pid = sys_getpid();
- memcpy(x, ptv, sizeof(struct timeval));
- e->dev = dev;
- e->inode = inode;
- e->port = port;
+ return NT_STATUS_OK;
}
-/*******************************************************************
- Add a deferred open record. Return False on fail, True on success.
-********************************************************************/
+/****************************************************************************
+ Sets the delete on close flag over all share modes on this file.
+ Modify the share mode entry for all files open
+ on this device and inode to tell other smbds we have
+ changed the delete on close flag. This will be noticed
+ in the close code, the last closer will delete the file
+ if flag is set.
+****************************************************************************/
-BOOL add_deferred_open(uint16 mid, struct timeval *ptv, SMB_DEV_T dev, SMB_INO_T inode, uint16 port, const char *fname)
+BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
{
- TDB_DATA dbuf;
- struct deferred_open_data *data;
- char *p=NULL;
- int size;
- TDB_DATA key = deferred_open_locking_key(dev, inode);
- BOOL ret = True;
-
- /* read in the existing deferred open records if any */
- dbuf = tdb_fetch(deferred_open_tdb, key);
- if (!dbuf.dptr) {
- size_t offset;
- /* we'll need to create a new record */
-
- size = sizeof(*data) + sizeof(deferred_open_entry) + strlen(fname) + 1;
- p = (char *)SMB_MALLOC(size);
- if (!p)
- return False;
- data = (struct deferred_open_data *)p;
- ZERO_STRUCT(data->u.dummy); /* Keep valgrind happy */
- data->u.num_deferred_open_entries = 1;
+ struct share_mode_lock *lck;
- DEBUG(10,("add_deferred_open: creating entry for file %s. num_deferred_open_entries = 1\n",
- fname ));
-
- offset = sizeof(*data) + sizeof(deferred_open_entry);
- safe_strcpy(p + offset, fname, size - offset - 1);
- fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
- dbuf.dptr = p;
- dbuf.dsize = size;
- if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
-
- print_deferred_open_table((struct deferred_open_data *)p);
-
- SAFE_FREE(p);
- return ret;
- }
-
- /* we're adding to an existing entry - this is a bit fiddly */
- data = (struct deferred_open_data *)dbuf.dptr;
+ DEBUG(10,("set_delete_on_close: %s delete on close flag for "
+ "fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum,
+ fsp->fsp_name ));
- data->u.num_deferred_open_entries++;
-
- DEBUG(10,("add_deferred_open: adding entry for file %s. new num_deferred_open_entries = %d\n",
- fname, data->u.num_deferred_open_entries ));
+ if (fsp->is_directory || fsp->is_stat)
+ return True;
- size = dbuf.dsize + sizeof(deferred_open_entry);
- p = SMB_MALLOC(size);
- if (!p) {
- SAFE_FREE(dbuf.dptr);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+ if (lck == NULL) {
return False;
}
- memcpy(p, dbuf.dptr, sizeof(*data));
- fill_deferred_open(p + sizeof(*data), mid, ptv, dev, inode, port);
- memcpy(p + sizeof(*data) + sizeof(deferred_open_entry), dbuf.dptr + sizeof(*data),
- dbuf.dsize - sizeof(*data));
- SAFE_FREE(dbuf.dptr);
- dbuf.dptr = p;
- dbuf.dsize = size;
- if (tdb_store(deferred_open_tdb, key, dbuf, TDB_REPLACE) == -1)
- ret = False;
- print_deferred_open_table((struct deferred_open_data *)p);
- SAFE_FREE(p);
- return ret;
-}
+ if (lck->delete_on_close != delete_on_close) {
+ lck->delete_on_close = delete_on_close;
+ lck->modified = True;
+ }
-/****************************************************************************
- Traverse the whole database with this function, calling traverse_callback
- on each share mode
-****************************************************************************/
+ talloc_free(lck);
+ return True;
+}
static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void* state)
+ void *state)
{
struct locking_data *data;
- share_mode_entry *shares;
+ struct share_mode_entry *shares;
char *name;
int i;
-
- SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
+ void (*traverse_callback)(struct share_mode_entry *, char *) = state;
/* Ensure this is a locking_key record. */
if (kbuf.dsize != sizeof(struct locking_key))
return 0;
data = (struct locking_data *)dbuf.dptr;
- shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
- name = dbuf.dptr + sizeof(*data) + data->u.s.num_share_mode_entries*sizeof(*shares);
+ shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
+ name = dbuf.dptr + sizeof(*data) +
+ data->u.s.num_share_mode_entries*sizeof(*shares);
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
traverse_callback(&shares[i], name);
@@ -1299,9 +1005,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
share mode system.
********************************************************************/
-int share_mode_forall(SHAREMODE_FN(fn))
+int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *))
{
- if (!tdb)
+ if (tdb == NULL)
return 0;
- return tdb_traverse(tdb, traverse_fn, (void*)fn);
+ return tdb_traverse(tdb, traverse_fn, fn);
}
diff --git a/source3/modules/weird.c b/source3/modules/weird.c
index 3c59fd9d61..ccee9d71ed 100644
--- a/source3/modules/weird.c
+++ b/source3/modules/weird.c
@@ -23,7 +23,7 @@
static struct {
char from;
- char *to;
+ const char *to;
int len;
} weird_table[] = {
{'q', "^q^", 3},
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index 653cb97fbb..4db54ea198 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -201,7 +201,7 @@ void run_dns_queue(void)
/* Allow SIGTERM to kill us. */
BlockSignals(False, SIGTERM);
- if (!process_exists(child_pid)) {
+ if (!process_exists_by_pid(child_pid)) {
close(fd_in);
start_async_dns();
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index bc58dd3a28..fcaba03b3d 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -76,7 +76,8 @@ static void terminate(void)
Handle a SHUTDOWN message from smbcontrol.
**************************************************************************** */
-static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
+static void nmbd_terminate(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
terminate();
}
@@ -307,7 +308,8 @@ static BOOL reload_nmbd_services(BOOL test)
* detects that there are no subnets.
**************************************************************************** */
-static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len)
+static void msg_reload_nmbd_services(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
write_browse_list( 0, True );
dump_all_namelists();
@@ -323,31 +325,33 @@ static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t
}
}
-static void msg_nmbd_send_packet(int msg_type, pid_t src,
+static void msg_nmbd_send_packet(int msg_type, struct process_id src,
void *buf, size_t len)
{
struct packet_struct *p = (struct packet_struct *)buf;
struct subnet_record *subrec;
struct in_addr *local_ip;
- DEBUG(10, ("Received send_packet from %d\n", src));
+ DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
if (len != sizeof(struct packet_struct)) {
- DEBUG(2, ("Discarding invalid packet length from %d\n", src));
+ DEBUG(2, ("Discarding invalid packet length from %d\n",
+ procid_to_pid(&src)));
return;
}
if ((p->packet_type != NMB_PACKET) &&
(p->packet_type != DGRAM_PACKET)) {
DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
- src, p->packet_type));
+ procid_to_pid(&src), p->packet_type));
return;
}
local_ip = iface_ip(p->ip);
if (local_ip == NULL) {
- DEBUG(2, ("Could not find ip for packet from %d\n", src));
+ DEBUG(2, ("Could not find ip for packet from %d\n",
+ procid_to_pid(&src)));
return;
}
@@ -590,7 +594,8 @@ static void process(void)
if(reload_after_sighup) {
DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
- msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, (void*) &no_subnets, 0);
+ msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
+ pid_to_procid(0), (void*) &no_subnets, 0);
if(no_subnets)
return;
reload_after_sighup = 0;
diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c
index 470cf4277b..6e8e8429be 100644
--- a/source3/nmbd/nmbd_elections.c
+++ b/source3/nmbd/nmbd_elections.c
@@ -374,7 +374,8 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
Process a internal Samba message forcing an election.
***************************************************************************/
-void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
+void nmbd_message_election(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
struct subnet_record *subrec;
diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c
index 4baf2d3d6c..c25473c4fb 100644
--- a/source3/nmbd/nmbd_packets.c
+++ b/source3/nmbd/nmbd_packets.c
@@ -1246,7 +1246,7 @@ packet sent to name %s from IP %s\n",
packet sent to name %s from IP %s\n",
dgram->datasize,
len,
- PTR_DIFF(buf2, dgram->data),
+ (int)PTR_DIFF(buf2, dgram->data),
nmb_namestr(&dgram->dest_name),
inet_ntoa(p->ip) ));
return;
@@ -1257,7 +1257,7 @@ packet sent to name %s from IP %s\n",
packet sent to name %s from IP %s\n",
dgram->datasize,
len,
- PTR_DIFF(buf2, dgram->data),
+ (int)PTR_DIFF(buf2, dgram->data),
nmb_namestr(&dgram->dest_name),
inet_ntoa(p->ip) ));
return;
diff --git a/source3/nmbd/nmbd_synclists.c b/source3/nmbd/nmbd_synclists.c
index 33690133bf..28ad92ed10 100644
--- a/source3/nmbd/nmbd_synclists.c
+++ b/source3/nmbd/nmbd_synclists.c
@@ -294,7 +294,7 @@ void sync_check_completion(void)
for (s=syncs;s;s=next) {
next = s->next;
- if (!process_exists(s->pid)) {
+ if (!process_exists_by_pid(s->pid)) {
/* it has completed - grab the info */
complete_sync(s);
DLIST_REMOVE(syncs, s);
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index 86f5b9c426..d76cb8f032 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -1874,7 +1874,8 @@ void wins_write_database(BOOL background)
Process a internal Samba message receiving a wins record.
***************************************************************************/
-void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
+void nmbd_wins_new_entry(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
WINS_RECORD *record;
struct name_record *namerec = NULL;
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 6d09666525..5521614965 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -543,6 +543,11 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
if (write_sock(request, sizeof(*request), request->flags & WBFLAG_RECURSE) == -1) {
return NSS_STATUS_UNAVAIL;
}
+
+ if ((request->extra_len != 0) &&
+ (write_sock(request->extra_data, request->extra_len, request->flags & WBFLAG_RECURSE) == -1)) {
+ return NSS_STATUS_UNAVAIL;
+ }
return NSS_STATUS_SUCCESS;
}
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 34b2d6c929..60f1d6b722 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -192,7 +192,6 @@ static BOOL wbinfo_get_userdomgroups(const char *user_sid)
return True;
}
-
/* Convert NetBIOS name to IP */
static BOOL wbinfo_wins_byname(char *name)
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index dffaad5ef0..565764fa4b 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -204,7 +204,7 @@ static void sigchld_handler(int signum)
}
/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
-static void msg_reload_services(int msg_type, pid_t src, void *buf, size_t len)
+static void msg_reload_services(int msg_type, struct process_id src, void *buf, size_t len)
{
/* Flush various caches */
flush_caches();
@@ -212,7 +212,7 @@ static void msg_reload_services(int msg_type, pid_t src, void *buf, size_t len)
}
/* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
-static void msg_shutdown(int msg_type, pid_t src, void *buf, size_t len)
+static void msg_shutdown(int msg_type, struct process_id src, void *buf, size_t len)
{
terminate();
}
@@ -455,6 +455,7 @@ void setup_async_write(struct fd_event *event, void *data, size_t length,
static void request_len_recv(void *private_data, BOOL success);
static void request_recv(void *private_data, BOOL success);
+static void request_main_recv(void *private_data, BOOL success);
static void request_finished(struct winbindd_cli_state *state);
void request_finished_cont(void *private_data, BOOL success);
static void response_main_sent(void *private_data, BOOL success);
@@ -475,6 +476,7 @@ static void response_extra_sent(void *private_data, BOOL success)
return;
}
+ SAFE_FREE(state->request.extra_data);
SAFE_FREE(state->response.extra_data);
setup_async_read(&state->fd_event, &state->request, sizeof(uint32),
@@ -538,7 +540,7 @@ void request_finished_cont(void *private_data, BOOL success)
request_error(state);
}
-static void request_recv(void *private_data, BOOL success)
+static void request_len_recv(void *private_data, BOOL success)
{
struct winbindd_cli_state *state =
talloc_get_type_abort(private_data, struct winbindd_cli_state);
@@ -548,10 +550,19 @@ static void request_recv(void *private_data, BOOL success)
return;
}
- process_request(state);
+ if (*(uint32 *)(&state->request) != sizeof(state->request)) {
+ DEBUG(0,("request_len_recv: Invalid request size received: %d\n",
+ *(uint32 *)(&state->request)));
+ state->finished = True;
+ return;
+ }
+
+ setup_async_read(&state->fd_event, (uint32 *)(&state->request)+1,
+ sizeof(state->request) - sizeof(uint32),
+ request_main_recv, state);
}
-static void request_len_recv(void *private_data, BOOL success)
+static void request_main_recv(void *private_data, BOOL success)
{
struct winbindd_cli_state *state =
talloc_get_type_abort(private_data, struct winbindd_cli_state);
@@ -561,16 +572,48 @@ static void request_len_recv(void *private_data, BOOL success)
return;
}
- if (*(uint32 *)(&state->request) != sizeof(state->request)) {
- DEBUG(0,("request_len_recv: Invalid request size received: %d\n",
- *(uint32 *)(&state->request)));
+ if (state->request.extra_len == 0) {
+ state->request.extra_data = NULL;
+ request_recv(state, True);
+ return;
+ }
+
+ if ((!state->privileged) &&
+ (state->request.extra_len > WINBINDD_MAX_EXTRA_DATA)) {
+ DEBUG(3, ("Got request with %d bytes extra data on "
+ "unprivileged socket\n", (int)state->request.extra_len));
+ state->request.extra_data = NULL;
state->finished = True;
return;
}
- setup_async_read(&state->fd_event, (uint32 *)(&state->request)+1,
- sizeof(state->request) - sizeof(uint32),
- request_recv, state);
+ state->request.extra_data =
+ SMB_MALLOC_ARRAY(char, state->request.extra_len + 1);
+
+ if (state->request.extra_data == NULL) {
+ DEBUG(0, ("malloc failed\n"));
+ state->finished = True;
+ return;
+ }
+
+ /* Ensure null termination */
+ state->request.extra_data[state->request.extra_len] = '\0';
+
+ setup_async_read(&state->fd_event, state->request.extra_data,
+ state->request.extra_len, request_recv, state);
+}
+
+static void request_recv(void *private_data, BOOL success)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (!success) {
+ state->finished = True;
+ return;
+ }
+
+ process_request(state);
}
/* Process a new connection by adding it to the client connection list */
@@ -842,7 +885,7 @@ static void process_loop(void)
DEBUG(3, ("got SIGHUP\n"));
- msg_reload_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, NULL, 0);
+ msg_reload_services(MSG_SMB_CONF_UPDATED, pid_to_procid(0), NULL, 0);
do_sighup = False;
}
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 3a7728e4a2..0db109dacd 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -47,6 +47,14 @@ struct fd_event {
void *private_data;
};
+struct sid_ctr {
+ DOM_SID *sid;
+ BOOL finished;
+ const char *domain;
+ const char *name;
+ enum SID_NAME_USE type;
+};
+
struct winbindd_cli_state {
struct winbindd_cli_state *prev, *next; /* Linked list pointers */
int sock; /* Open socket from client */
@@ -122,12 +130,6 @@ struct winbindd_cm_conn {
struct rpc_pipe_client *lsa_pipe;
POLICY_HND lsa_policy;
- /* Auth2 pipe is the pipe used to setup the netlogon schannel key
- * using rpccli_net_auth2. It needs to be kept open. */
-
- struct rpc_pipe_client *netlogon_auth2_pipe;
- unsigned char sess_key[16]; /* Current session key. */
- DOM_CRED clnt_cred; /* Client NETLOGON credential. */
struct rpc_pipe_client *netlogon_pipe;
};
@@ -305,8 +307,6 @@ struct winbindd_idmap_methods {
#include "nsswitch/winbindd_proto.h"
-#include "rpc_parse.h"
-
#define WINBINDD_ESTABLISH_LOOP 30
#define WINBINDD_RESCAN_FREQ 300
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index eda6dea2c4..dfabccd419 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -830,13 +830,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
*names = NULL;
*dom_sids = NULL;
- {
- unsigned char *session_key;
- DOM_CRED *creds;
-
- result = cm_connect_netlogon(domain, mem_ctx, &cli,
- &session_key, &creds);
- }
+ result = cm_connect_netlogon(domain, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(5, ("trusted_domains: Could not open a connection to %s "
@@ -845,11 +839,12 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
return NT_STATUS_UNSUCCESSFUL;
}
- if ( NT_STATUS_IS_OK(result) )
+ if ( NT_STATUS_IS_OK(result) ) {
result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
cli->cli->desthost,
flags, &domains,
(unsigned int *)&count);
+ }
if ( NT_STATUS_IS_OK(result) && count) {
diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c
index acae7e7f37..d43671380d 100644
--- a/source3/nsswitch/winbindd_async.c
+++ b/source3/nsswitch/winbindd_async.c
@@ -84,12 +84,12 @@ static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
&state->response, do_async_recv, state);
}
-static void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
- const struct winbindd_request *request,
- void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data),
- void *c, void *private_data)
+void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
+ const struct winbindd_request *request,
+ void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data),
+ void *c, void *private_data)
{
struct do_async_state *state;
@@ -706,16 +706,16 @@ enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
return WINBINDD_OK;
}
-static BOOL print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
- int num_sids, char **result)
+BOOL print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
+ int num_sids, char **result, ssize_t *len)
{
int i;
size_t buflen = 0;
- ssize_t len = 0;
+ *len = 0;
*result = NULL;
for (i=0; i<num_sids; i++) {
- sprintf_append(mem_ctx, result, &len, &buflen,
+ sprintf_append(mem_ctx, result, len, &buflen,
"%s\n", sid_string_static(&sids[i]));
}
@@ -726,14 +726,14 @@ static BOOL print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,
return True;
}
-static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
- DOM_SID **sids, int *num_sids)
+BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
+ DOM_SID **sids, int *num_sids)
{
char *p, *q;
p = sidstr;
if (p == NULL)
- return True;
+ return False;
while (p[0] != '\0') {
DOM_SID sid;
@@ -754,6 +754,49 @@ static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
return True;
}
+BOOL print_ridlist(TALLOC_CTX *mem_ctx, uint32 *rids, int num_rids,
+ char **result, ssize_t *len)
+{
+ int i;
+ size_t buflen = 0;
+
+ *len = 0;
+ *result = NULL;
+ for (i=0; i<num_rids; i++) {
+ sprintf_append(mem_ctx, result, len, &buflen,
+ "%ld\n", rids[i]);
+ }
+
+ if ((num_rids != 0) && (*result == NULL)) {
+ return False;
+ }
+
+ return True;
+}
+
+BOOL parse_ridlist(TALLOC_CTX *mem_ctx, char *ridstr,
+ uint32 **sids, int *num_rids)
+{
+ char *p;
+
+ p = ridstr;
+ if (p == NULL)
+ return False;
+
+ while (p[0] != '\0') {
+ uint32 rid;
+ char *q;
+ rid = strtoul(p, &q, 10);
+ if (*q != '\n') {
+ DEBUG(0, ("Got invalid ridstr: %s\n", p));
+ return False;
+ }
+ p = q+1;
+ ADD_TO_ARRAY(mem_ctx, uint32, rid, sids, num_rids);
+ }
+ return True;
+}
+
static void getsidaliases_recv(TALLOC_CTX *mem_ctx, BOOL success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -806,28 +849,22 @@ void winbindd_getsidaliases_async(struct winbindd_domain *domain,
{
struct winbindd_request request;
char *sidstr = NULL;
- char *keystr;
+ ssize_t len;
if (num_sids == 0) {
cont(private_data, True, NULL, 0);
return;
}
- if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr)) {
- cont(private_data, False, NULL, 0);
- return;
- }
-
- keystr = cache_store_request_data(mem_ctx, sidstr);
- if (keystr == NULL) {
+ if (!print_sidlist(mem_ctx, sids, num_sids, &sidstr, &len)) {
cont(private_data, False, NULL, 0);
return;
}
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_GETSIDALIASES;
- fstrcpy(request.domain_name, domain->name);
- fstrcpy(request.data.dual_sidaliases.cache_key, keystr);
+ request.extra_len = len;
+ request.extra_data = sidstr;
do_async_domain(mem_ctx, domain, &request, getsidaliases_recv,
cont, private_data);
@@ -838,20 +875,15 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
{
DOM_SID *sids = NULL;
int num_sids = 0;
- char *key = state->request.data.dual_sidaliases.cache_key;
char *sidstr;
+ size_t len;
int i, num_aliases;
uint32 *alias_rids;
NTSTATUS result;
DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
- /* Ensure null termination */
- state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
- state->request.data.dual_sidaliases.cache_key
- [sizeof(state->request.data.dual_sidaliases.cache_key)-1]='\0';
-
- sidstr = cache_retrieve_request_data(state->mem_ctx, key);
+ sidstr = state->request.extra_data;
if (sidstr == NULL)
sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */
@@ -891,7 +923,7 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
}
if (!print_sidlist(NULL, sids, num_sids,
- (char **)&state->response.extra_data)) {
+ (char **)&state->response.extra_data, &len)) {
DEBUG(0, ("Could not print_sidlist\n"));
return WINBINDD_ERROR;
}
@@ -899,7 +931,7 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain,
if (state->response.extra_data != NULL) {
DEBUG(10, ("aliases_list: %s\n",
(char *)state->response.extra_data));
- state->response.length += strlen(state->response.extra_data)+1;
+ state->response.length += len+1;
}
return WINBINDD_OK;
@@ -1405,3 +1437,4 @@ void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
do_async_domain(mem_ctx, domain, &request, query_user_recv,
cont, private_data);
}
+
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index ce291a6c25..78b49d01ea 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -469,6 +469,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
centry->sequence_number = centry_uint32(centry);
if (centry_expired(domain, kstr, centry)) {
+
DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
kstr, domain->name ));
@@ -1048,7 +1049,6 @@ do_query:
return status;
}
-
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -1466,7 +1466,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
/* There's extra data */
DEBUG(10, ("Storing extra data: len=%d\n",
- response->length - sizeof(*response)));
+ (int)(response->length - sizeof(*response))));
fstr_sprintf(key_str, "DE/%d", pid);
if (tdb_store(wcache->tdb, string_tdb_data(key_str),
@@ -1514,7 +1514,7 @@ BOOL cache_retrieve_response(pid_t pid, struct winbindd_response * response)
/* There's extra data */
DEBUG(10, ("Retrieving extra data length=%d\n",
- response->length - sizeof(*response)));
+ (int)(response->length - sizeof(*response))));
fstr_sprintf(key_str, "DE/%d", pid);
data = tdb_fetch(wcache->tdb, string_tdb_data(key_str));
@@ -1525,63 +1525,57 @@ BOOL cache_retrieve_response(pid_t pid, struct winbindd_response * response)
}
if (data.dsize != (response->length - sizeof(*response))) {
- DEBUG(0, ("Invalid extra data length: %d\n", data.dsize));
+ DEBUG(0, ("Invalid extra data length: %d\n", (int)data.dsize));
SAFE_FREE(data.dptr);
return False;
}
+ dump_data(11, data.dptr, data.dsize);
+
response->extra_data = data.dptr;
return True;
}
-char *cache_store_request_data(TALLOC_CTX *mem_ctx, char *request_string)
+BOOL lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ const char **domain_name, const char **name,
+ enum SID_NAME_USE *type)
{
- int i;
-
- if (!init_wcache())
- return NULL;
+ struct winbindd_domain *domain;
+ struct winbind_cache *cache;
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
- for (i=0; i<2; i++) {
- char *key = talloc_strdup(mem_ctx, generate_random_str(16));
- if (key == NULL)
- return NULL;
- DEBUG(10, ("Storing request key %s\n", key));
- if (tdb_store_bystring(wcache->tdb, key,
- string_tdb_data(request_string),
- TDB_INSERT) == 0)
- return key;
+ domain = find_lookup_domain_from_sid(sid);
+ if (domain == NULL) {
+ return False;
}
- return NULL;
-}
-char *cache_retrieve_request_data(TALLOC_CTX *mem_ctx, char *key)
-{
- TDB_DATA data;
- char *result = NULL;
+ cache = get_cache(domain);
- if (!init_wcache())
- return NULL;
-
- DEBUG(10, ("Retrieving key %s\n", key));
-
- data = tdb_fetch_bystring(wcache->tdb, key);
- if (data.dptr == NULL)
- return NULL;
-
- if (strnlen(data.dptr, data.dsize) != (data.dsize)) {
- DEBUG(0, ("Received invalid request string\n"));
- goto done;
+ if (cache->tdb == NULL) {
+ return False;
}
- result = TALLOC_ARRAY(mem_ctx, char, data.dsize+1);
- if (result != NULL) {
- memcpy(result, data.dptr, data.dsize);
- result[data.dsize] = '\0';
+
+ centry = wcache_fetch(cache, domain, "SN/%s", sid_string_static(sid));
+ if (centry == NULL) {
+ return False;
}
- if (tdb_delete_bystring(wcache->tdb, key) != 0) {
- DEBUG(0, ("Could not delete key %s\n", key));
- result = NULL;
+
+ if (NT_STATUS_IS_OK(centry->status)) {
+ *type = (enum SID_NAME_USE)centry_uint32(centry);
+ *domain_name = centry_string(centry, mem_ctx);
+ *name = centry_string(centry, mem_ctx);
}
- done:
- SAFE_FREE(data.dptr);
- return result;
+
+ status = centry->status;
+ centry_free(centry);
+ return NT_STATUS_IS_OK(status);
+}
+
+void cache_sid2name(struct winbindd_domain *domain, const DOM_SID *sid,
+ const char *domain_name, const char *name,
+ enum SID_NAME_USE type)
+{
+ wcache_save_sid_to_name(domain, NT_STATUS_OK, sid, domain_name,
+ name, type);
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 14221483ad..c91f955568 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -73,7 +73,7 @@
SAMR pipe as well for now. --jerry
******************************************************************/
-#define DISABLE_SCHANNEL_WIN2K3_SP1 1
+/* #define DISABLE_SCHANNEL_WIN2K3_SP1 1 */
/* Choose between anonymous or authenticated connections. We need to use
@@ -113,8 +113,8 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
fstring dcname, struct in_addr *dc_ip)
{
struct winbindd_domain *our_domain;
+ struct rpc_pipe_client *netlogon_pipe;
NTSTATUS result;
- struct rpc_pipe_client *cli;
TALLOC_CTX *mem_ctx;
fstring tmp;
@@ -123,30 +123,26 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
/* Hmmmm. We can only open one connection to the NETLOGON pipe at the
* moment.... */
- if (IS_DC)
+ if (IS_DC) {
return False;
+ }
- if (domain->primary)
+ if (domain->primary) {
return False;
+ }
our_domain = find_our_domain();
- if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL)
+ if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
return False;
-
- {
- /* These var's can be ignored -- we're not requesting
- anything in the credential chain here */
- unsigned char *session_key;
- DOM_CRED *creds;
- result = cm_connect_netlogon(our_domain, mem_ctx, &cli,
- &session_key, &creds);
}
- if (!NT_STATUS_IS_OK(result))
+ result = cm_connect_netlogon(our_domain, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
return False;
+ }
- result = rpccli_netlogon_getdcname(cli, mem_ctx, domain->dcname,
+ result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, domain->dcname,
domain->name, tmp);
talloc_destroy(mem_ctx);
@@ -156,13 +152,18 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
/* cli_netlogon_getdcname gives us a name with \\ */
p = tmp;
- if (*p == '\\') p+=1;
- if (*p == '\\') p+=1;
+ if (*p == '\\') {
+ p+=1;
+ }
+ if (*p == '\\') {
+ p+=1;
+ }
fstrcpy(dcname, p);
- if (!resolve_name(dcname, dc_ip, 0x20))
+ if (!resolve_name(dcname, dc_ip, 0x20)) {
return False;
+ }
return True;
}
@@ -178,7 +179,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
struct cli_state **cli,
BOOL *retry)
{
- char *machine_password, *machine_krb5_principal;
+ char *machine_password, *machine_krb5_principal, *machine_account;
char *ipc_username, *ipc_domain, *ipc_password;
BOOL got_mutex;
@@ -194,8 +195,14 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
NULL);
+ if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
+ SAFE_FREE(machine_password);
+ return NT_STATUS_NO_MEMORY;
+ }
+
if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
lp_realm()) == -1) {
+ SAFE_FREE(machine_account);
SAFE_FREE(machine_password);
return NT_STATUS_NO_MEMORY;
}
@@ -257,33 +264,61 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
goto done;
}
- /* Krb5 session */
- if ((lp_security() == SEC_ADS)
- && ((*cli)->protocol >= PROTOCOL_NT1 &&
- (*cli)->capabilities & CAP_EXTENDED_SECURITY)) {
-
+ if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
ADS_STATUS ads_status;
- (*cli)->use_kerberos = True;
- DEBUG(5, ("connecting to %s from %s with kerberos principal "
- "[%s]\n", controller, global_myname(),
- machine_krb5_principal));
+
+ if (lp_security() == SEC_ADS) {
+
+ /* Try a krb5 session */
+
+ (*cli)->use_kerberos = True;
+ DEBUG(5, ("connecting to %s from %s with kerberos principal "
+ "[%s]\n", controller, global_myname(),
+ machine_krb5_principal));
+
+ ads_status = cli_session_setup_spnego(*cli,
+ machine_krb5_principal,
+ machine_password,
+ lp_workgroup());
+
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4,("failed kerberos session setup with %s\n",
+ ads_errstr(ads_status)));
+ }
+
+ result = ads_ntstatus(ads_status);
+ if (NT_STATUS_IS_OK(result)) {
+ /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
+ cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ goto session_setup_done;
+ }
+ }
+
+ /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
+ (*cli)->use_kerberos = False;
+
+ DEBUG(5, ("connecting to %s from %s with username "
+ "[%s]\\[%s]\n", controller, global_myname(),
+ machine_account, machine_password));
ads_status = cli_session_setup_spnego(*cli,
- machine_krb5_principal,
+ machine_account,
machine_password,
lp_workgroup());
-
- if (!ADS_ERR_OK(ads_status))
- DEBUG(4,("failed kerberos session setup with %s\n",
- ads_errstr(ads_status)));
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4, ("authenticated session setup failed with %s\n",
+ ads_errstr(ads_status)));
+ }
result = ads_ntstatus(ads_status);
+ if (NT_STATUS_IS_OK(result)) {
+ /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
+ cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ goto session_setup_done;
+ }
}
- if (NT_STATUS_IS_OK(result))
- goto session_setup_done;
-
/* Fall back to non-kerberos session setup */
(*cli)->use_kerberos = False;
@@ -301,8 +336,12 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
ipc_password, strlen(ipc_password)+1,
ipc_password, strlen(ipc_password)+1,
ipc_domain)) {
- DEBUG(5, ("authenticated session setup failed\n"));
+ /* Successful logon with given username. */
+ cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
goto session_setup_done;
+ } else {
+ DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
+ ipc_domain, ipc_username ));
}
}
@@ -310,6 +349,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
DEBUG(5, ("Connected anonymously\n"));
+ cli_init_creds(*cli, "", "", "");
goto session_setup_done;
}
@@ -342,26 +382,28 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
*retry = False;
/* set the domain if empty; needed for schannel connections */
- if ( !*(*cli)->domain )
+ if ( !*(*cli)->domain ) {
fstrcpy( (*cli)->domain, domain->name );
-
- (*cli)->pipe_auth_flags = 0;
+ }
result = NT_STATUS_OK;
add_failed_connection = False;
done:
- if (got_mutex)
+ if (got_mutex) {
secrets_named_mutex_release(controller);
+ }
+ SAFE_FREE(machine_account);
SAFE_FREE(machine_password);
SAFE_FREE(machine_krb5_principal);
SAFE_FREE(ipc_username);
SAFE_FREE(ipc_domain);
SAFE_FREE(ipc_password);
- if (add_failed_connection)
+ if (add_failed_connection) {
add_failed_connection_entry(domain->name, controller, result);
+ }
return result;
}
@@ -721,7 +763,7 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
for (retries = 0; retries < 3; retries++) {
int fd = -1;
- BOOL retry;
+ BOOL retry = False;
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
@@ -758,27 +800,23 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
void invalidate_cm_connection(struct winbindd_cm_conn *conn)
{
if (conn->samr_pipe != NULL) {
- cli_rpc_close(conn->samr_pipe);
+ cli_rpc_pipe_close(conn->samr_pipe);
conn->samr_pipe = NULL;
}
if (conn->lsa_pipe != NULL) {
- cli_rpc_close(conn->lsa_pipe);
+ cli_rpc_pipe_close(conn->lsa_pipe);
conn->lsa_pipe = NULL;
}
- if (conn->netlogon_auth2_pipe != NULL) {
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
- }
-
if (conn->netlogon_pipe != NULL) {
- cli_rpc_close(conn->netlogon_pipe);
+ cli_rpc_pipe_close(conn->netlogon_pipe);
conn->netlogon_pipe = NULL;
}
- if (conn->cli)
+ if (conn->cli) {
cli_shutdown(conn->cli);
+ }
conn->cli = NULL;
}
@@ -872,7 +910,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
return;
}
- cli = cli_rpc_open_noauth(domain->conn.cli, PI_LSARPC_DS);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS, &result);
if (cli == NULL) {
DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
@@ -885,7 +923,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
DsRolePrimaryDomainInfoBasic,
&ctr);
- cli_rpc_close(cli);
+ cli_rpc_pipe_close(cli);
if (!NT_STATUS_IS_OK(result)) {
domain->initialized = True;
@@ -896,7 +934,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
!(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
domain->native_mode = True;
- cli = cli_rpc_open_noauth(domain->conn.cli, PI_LSARPC);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
if (cli == NULL) {
domain->initialized = True;
@@ -907,6 +945,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
domain->name);
if (!mem_ctx) {
DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
+ cli_rpc_pipe_close(cli);
return;
}
@@ -956,7 +995,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
}
done:
- cli_rpc_close(cli);
+ cli_rpc_pipe_close(cli);
talloc_destroy(mem_ctx);
@@ -965,20 +1004,28 @@ done:
return;
}
-static BOOL cm_get_schannel_key(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- unsigned char **session_key)
+#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
+static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain, struct dcinfo **ppdc)
{
- struct rpc_pipe_client *cli;
- DOM_CRED *credentials;
+ NTSTATUS result;
+ struct rpc_pipe_client *netlogon_pipe;
- if (lp_client_schannel() == False)
+ if (lp_client_schannel() == False) {
return False;
+ }
- return NT_STATUS_IS_OK(cm_connect_netlogon(domain, mem_ctx,
- &cli, session_key,
- &credentials));
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
+ return False;
+ }
+
+ /* Return a pointer to the struct dcinfo from the
+ netlogon pipe. */
+
+ *ppdc = domain->conn.netlogon_pipe->dc;
+ return True;
}
+#endif
NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
@@ -987,24 +1034,85 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
NTSTATUS result;
result = init_dc_connection(domain);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
conn = &domain->conn;
if (conn->samr_pipe == NULL) {
+ /*
+ * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO
+ * authenticated sign and sealed pipe using the machine
+ * account password by preference. If we can't - try schannel,
+ * if that fails, try anonymous.
+ */
+
+ fstring conn_pwd;
+ pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
+ if (conn->cli->user_name[0] && conn->cli->domain[0] &&
+ conn_pwd[0]) {
+ /* We have an authenticated connection. Use
+ a NTLMSSP SPNEGO authenticated SAMR pipe with
+ sign & seal. */
+ conn->samr_pipe =
+ cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
+ PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ conn->cli->domain,
+ conn->cli->user_name,
+ conn_pwd,
+ &result);
+ if (conn->samr_pipe == NULL) {
+ DEBUG(10,("cm_connect_sam: failed to connect "
+ "to SAMR pipe for domain %s using "
+ "NTLMSSP authenticated pipe: user "
+ "%s\\%s. Error was %s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name,
+ nt_errstr(result)));
+ } else {
+ DEBUG(10,("cm_connect_sam: connected to SAMR "
+ "pipe for domain %s using NTLMSSP "
+ "authenticated pipe: user %s\\%s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name ));
+ }
+ }
+
#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
- unsigned char *session_key;
-
- if (cm_get_schannel_key(domain, mem_ctx, &session_key))
- conn->samr_pipe = cli_rpc_open_schannel(conn->cli,
- PI_SAMR,
- session_key,
- domain->name);
- else
+ /* Fall back to schannel if it's a W2K pre-SP1 box. */
+ if (conn->samr_pipe == NULL) {
+ struct dcinfo *p_dcinfo;
+
+ if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
+ conn->samr_pipe =
+ cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ p_dcinfo,
+ &result);
+ }
+ if (conn->samr_pipe == NULL) {
+ DEBUG(10,("cm_connect_sam: failed to connect "
+ "to SAMR pipe for domain %s using "
+ "schannel authenticated. Error "
+ "was %s\n", domain->name,
+ nt_errstr(result) ));
+ } else {
+ DEBUG(10,("cm_connect_sam: connected to SAMR "
+ "pipe for domain %s using schannel.\n",
+ domain->name ));
+ }
+ }
#endif /* DISABLE_SCHANNEL_WIN2K3_SP1 */
- conn->samr_pipe = cli_rpc_open_noauth(conn->cli,
- PI_SAMR);
+
+ /* Finally fall back to anonymous. */
+ if (conn->samr_pipe == NULL) {
+ conn->samr_pipe =
+ cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR, &result);
+ }
if (conn->samr_pipe == NULL) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
@@ -1014,8 +1122,12 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&conn->sam_connect_handle);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
+ "for domain %s Error was %s\n",
+ domain->name, nt_errstr(result) ));
goto done;
+ }
result = rpccli_samr_open_domain(conn->samr_pipe,
mem_ctx,
@@ -1026,9 +1138,10 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
}
done:
+
if (!NT_STATUS_IS_OK(result)) {
invalidate_cm_connection(conn);
- return NT_STATUS_UNSUCCESSFUL;
+ return result;
}
*cli = conn->samr_pipe;
@@ -1049,18 +1162,72 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
conn = &domain->conn;
if (conn->lsa_pipe == NULL) {
+ fstring conn_pwd;
+ pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
+ if (conn->cli->user_name[0] && conn->cli->domain[0] &&
+ conn_pwd[0]) {
+ /* We have an authenticated connection. Use
+ a NTLMSSP SPNEGO authenticated LSA pipe with
+ sign & seal. */
+ conn->lsa_pipe =
+ cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
+ PI_LSARPC,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ conn->cli->domain,
+ conn->cli->user_name,
+ conn_pwd,
+ &result);
+ if (conn->lsa_pipe == NULL) {
+ DEBUG(10,("cm_connect_lsa: failed to connect "
+ "to LSA pipe for domain %s using "
+ "NTLMSSP authenticated pipe: user "
+ "%s\\%s. Error was %s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name,
+ nt_errstr(result)));
+ } else {
+ DEBUG(10,("cm_connect_lsa: connected to LSA "
+ "pipe for domain %s using NTLMSSP "
+ "authenticated pipe: user %s\\%s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name ));
+ }
+ }
+
#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
- unsigned char *session_key;
-
- if (cm_get_schannel_key(domain, mem_ctx, &session_key))
- conn->lsa_pipe = cli_rpc_open_schannel(conn->cli,
- PI_LSARPC,
- session_key,
- domain->name);
- else
+ /* Fall back to schannel if it's a W2K pre-SP1 box. */
+ if (conn->lsa_pipe == NULL) {
+ struct dcinfo *p_dcinfo;
+
+ if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
+ conn->lsa_pipe =
+ cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_LSARPC,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ p_dcinfo,
+ &result);
+ }
+ if (conn->lsa_pipe == NULL) {
+ DEBUG(10,("cm_connect_lsa: failed to connect "
+ "to LSA pipe for domain %s using "
+ "schannel authenticated. Error "
+ "was %s\n", domain->name,
+ nt_errstr(result) ));
+ } else {
+ DEBUG(10,("cm_connect_lsa: connected to LSA "
+ "pipe for domain %s using schannel.\n",
+ domain->name ));
+ }
+ }
#endif /* DISABLE_SCHANNEL_WIN2K3_SP1 */
- conn->lsa_pipe = cli_rpc_open_noauth(conn->cli,
- PI_LSARPC);
+
+ /* Finally fall back to anonymous. */
+ if (conn->lsa_pipe == NULL) {
+ conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli,
+ PI_LSARPC,
+ &result);
+ }
if (conn->lsa_pipe == NULL) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
@@ -1083,55 +1250,12 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
return result;
}
-/*******************************************************************
- wrapper around retrieving the trust account password
-*******************************************************************/
+/****************************************************************************
+ Open the netlogon pipe to this DC. Use schannel if specified in client conf.
+ session key stored in conn->netlogon_pipe->dc->sess_key.
+****************************************************************************/
-static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
- uint32 *channel)
-{
- DOM_SID sid;
- char *pwd;
- time_t last_set_time;
-
- /* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) &&
- lp_allow_trusted_domains() ) {
-
- if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- &last_set_time)) {
- DEBUG(0, ("get_trust_pw: could not fetch trust "
- "account password for trusted domain %s\n",
- domain));
- return False;
- }
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
-
- return True;
- }
-
- /* Just get the account for the requested domain. In the future this
- * might also cover to be member of more than one domain. */
-
- if (secrets_fetch_trust_account_password(domain, ret_pwd,
- &last_set_time, channel))
- return True;
-
- DEBUG(5, ("get_trust_pw: could not fetch trust account "
- "password for domain %s\n", domain));
- return False;
-}
-
-NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **cli,
- unsigned char **session_key,
- DOM_CRED **credentials)
+NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli)
{
struct winbindd_cm_conn *conn;
NTSTATUS result;
@@ -1139,119 +1263,100 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
uint8 mach_pwd[16];
uint32 sec_chan_type;
- DOM_CHAL clnt_chal, srv_chal, rcv_chal;
- const char *server_name;
const char *account_name;
- UTIME zerotime;
+ struct rpc_pipe_client *netlogon_pipe;
result = init_dc_connection(domain);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
conn = &domain->conn;
if (conn->netlogon_pipe != NULL) {
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
return NT_STATUS_OK;
}
- if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type))
+ if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
- conn->netlogon_auth2_pipe = cli_rpc_open_noauth(conn->cli,
- PI_NETLOGON);
- if (conn->netlogon_auth2_pipe == NULL)
- return NT_STATUS_UNSUCCESSFUL;
+ netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON, &result);
+ if (netlogon_pipe == NULL) {
+ return result;
+ }
- if (lp_client_schannel() != False)
+ if (lp_client_schannel() != False) {
neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- generate_random_buffer(clnt_chal.data, 8);
-
- server_name = talloc_asprintf(mem_ctx, "\\\\%s", domain->dcname);
+ }
/* if we are a DC and this is a trusted domain, then we need to use our
domain name in the net_req_auth2() request */
- if ( IS_DC
+ if ( IS_DC
&& !strequal(domain->name, lp_workgroup())
&& lp_allow_trusted_domains() )
{
- account_name = talloc_asprintf( mem_ctx, "%s$", lp_workgroup() );
- }
- else {
- account_name = talloc_asprintf(mem_ctx, "%s$",
- domain->primary ? global_myname() : domain->name);
+ account_name = lp_workgroup();
+ } else {
+ account_name = domain->primary ? global_myname() : domain->name;
}
- if ((server_name == NULL) || (account_name == NULL))
+ if (account_name == NULL) {
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_NO_MEMORY;
+ }
- result = rpccli_net_req_chal(conn->netlogon_auth2_pipe, server_name,
- global_myname(), &clnt_chal, &srv_chal);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /**************** Long-term Session key **************/
-
- /* calculate the session key */
- cred_session_key(&clnt_chal, &srv_chal, mach_pwd, conn->sess_key);
- memset((char *)conn->sess_key+8, '\0', 8);
-
- /* calculate auth2 credentials */
- zerotime.time = 0;
- cred_create(conn->sess_key, &clnt_chal, zerotime,
- &conn->clnt_cred.challenge);
-
- result = rpccli_net_auth2(conn->netlogon_auth2_pipe, server_name,
- account_name, sec_chan_type, global_myname(),
- &conn->clnt_cred.challenge, &neg_flags,
- &rcv_chal);
+ result = rpccli_netlogon_setup_creds(netlogon_pipe,
+ domain->dcname, /* server name. */
+ domain->name, /* domain name */
+ account_name, /* machine account */
+ mach_pwd, /* machine password */
+ sec_chan_type, /* from get_trust_pw */
+ &neg_flags);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_rpc_pipe_close(netlogon_pipe);
return result;
-
- zerotime.time = 0;
- if (!cred_assert(&rcv_chal, conn->sess_key, &srv_chal, zerotime)) {
- DEBUG(0, ("Server replied with bad credential\n"));
- return NT_STATUS_ACCESS_DENIED;
}
if ((lp_client_schannel() == True) &&
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+ ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
DEBUG(3, ("Server did not offer schannel\n"));
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_ACCESS_DENIED;
}
if ((lp_client_schannel() == False) ||
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
- /* keep the existing connection to NETLOGON open */
- conn->netlogon_pipe = conn->netlogon_auth2_pipe;
- conn->netlogon_auth2_pipe = NULL;
+ ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+ /* We're done - just keep the existing connection to NETLOGON open */
+ conn->netlogon_pipe = netlogon_pipe;
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
return NT_STATUS_OK;
}
- conn->netlogon_pipe = cli_rpc_open_schannel(conn->cli, PI_NETLOGON,
- conn->sess_key,
- domain->name);
+ /* Using the credentials from the first pipe, open a signed and sealed
+ second netlogon pipe. The session key is stored in the schannel
+ part of the new pipe auth struct.
+ */
+
+ conn->netlogon_pipe = cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ netlogon_pipe->dc,
+ &result);
+
+ /* We can now close the initial netlogon pipe. */
+ cli_rpc_pipe_close(netlogon_pipe);
if (conn->netlogon_pipe == NULL) {
- DEBUG(3, ("Could not open schannel'ed NETLOGON pipe\n"));
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
- return NT_STATUS_ACCESS_DENIED;
+ DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error was %s\n",
+ nt_errstr(result)));
+ return result;
}
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
-
return NT_STATUS_OK;
}
diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c
index ec0b7a36e2..60b7411417 100644
--- a/source3/nsswitch/winbindd_dual.c
+++ b/source3/nsswitch/winbindd_dual.c
@@ -38,35 +38,48 @@
/* Read some data from a client connection */
-static void dual_client_read(struct winbindd_cli_state *state)
+static void child_read_request(struct winbindd_cli_state *state)
{
- int n;
-
+ ssize_t len;
+
/* Read data */
- n = sys_read(state->sock, state->read_buf_len +
- (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
-
- DEBUG(10,("client_read: read %d bytes. Need %ld more for a full "
- "request.\n", n, (unsigned long)(sizeof(state->request) - n -
- state->read_buf_len) ));
+ len = read_data(state->sock, (char *)&state->request,
+ sizeof(state->request));
- /* Read failed, kill client */
-
- if (n == -1 || n == 0) {
- DEBUG(5,("read failed on sock %d, pid %lu: %s\n",
- state->sock, (unsigned long)state->pid,
- (n == -1) ? strerror(errno) : "EOF"));
-
+ if (len != sizeof(state->request)) {
+ DEBUG(0, ("Got invalid request length: %d\n", (int)len));
+ state->finished = True;
+ return;
+ }
+
+ if (state->request.extra_len == 0) {
+ state->request.extra_data = NULL;
+ return;
+ }
+
+ DEBUG(10, ("Need to read %d extra bytes\n", (int)state->request.extra_len));
+
+ state->request.extra_data =
+ SMB_MALLOC_ARRAY(char, state->request.extra_len + 1);
+
+ if (state->request.extra_data == NULL) {
+ DEBUG(0, ("malloc failed\n"));
+ state->finished = True;
+ return;
+ }
+
+ /* Ensure null termination */
+ state->request.extra_data[state->request.extra_len] = '\0';
+
+ len = read_data(state->sock, state->request.extra_data,
+ state->request.extra_len);
+
+ if (len != state->request.extra_len) {
+ DEBUG(0, ("Could not read extra data\n"));
state->finished = True;
return;
}
-
- /* Update client state */
-
- state->read_buf_len += n;
- state->last_access = time(NULL);
}
/*
@@ -86,6 +99,7 @@ struct winbindd_async_request {
void *private_data;
};
+static void async_main_request_sent(void *private_data, BOOL success);
static void async_request_sent(void *private_data, BOOL success);
static void async_reply_recv(void *private_data, BOOL success);
static void schedule_async_request(struct winbindd_child *child);
@@ -122,7 +136,7 @@ void async_request(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
return;
}
-static void async_request_sent(void *private_data, BOOL success)
+static void async_main_request_sent(void *private_data, BOOL success)
{
struct winbindd_async_request *state =
talloc_get_type_abort(private_data, struct winbindd_async_request);
@@ -136,6 +150,30 @@ static void async_request_sent(void *private_data, BOOL success)
return;
}
+ if (state->request->extra_len == 0) {
+ async_request_sent(private_data, True);
+ return;
+ }
+
+ setup_async_write(&state->child->event, state->request->extra_data,
+ state->request->extra_len,
+ async_request_sent, state);
+}
+
+static void async_request_sent(void *private_data_data, BOOL success)
+{
+ struct winbindd_async_request *state =
+ talloc_get_type_abort(private_data_data, struct winbindd_async_request);
+
+ if (!success) {
+ DEBUG(5, ("Could not send async request\n"));
+
+ state->response->length = sizeof(struct winbindd_response);
+ state->response->result = WINBINDD_ERROR;
+ state->continuation(state->private_data, False);
+ return;
+ }
+
/* Request successfully sent to the child, setup the wait for reply */
setup_async_read(&state->child->event,
@@ -196,7 +234,7 @@ static void schedule_async_request(struct winbindd_child *child)
setup_async_write(&child->event, request->request,
sizeof(*request->request),
- async_request_sent, request);
+ async_main_request_sent, request);
return;
}
@@ -205,31 +243,31 @@ struct domain_request_state {
struct winbindd_domain *domain;
struct winbindd_request *request;
struct winbindd_response *response;
- void (*continuation)(void *private_data, BOOL success);
- void *private_data;
+ void (*continuation)(void *private_data_data, BOOL success);
+ void *private_data_data;
};
-static void domain_init_recv(void *private_data, BOOL success);
+static void domain_init_recv(void *private_data_data, BOOL success);
void async_domain_request(TALLOC_CTX *mem_ctx,
struct winbindd_domain *domain,
struct winbindd_request *request,
struct winbindd_response *response,
- void (*continuation)(void *private_data, BOOL success),
- void *private_data)
+ void (*continuation)(void *private_data_data, BOOL success),
+ void *private_data_data)
{
struct domain_request_state *state;
if (domain->initialized) {
async_request(mem_ctx, &domain->child, request, response,
- continuation, private_data);
+ continuation, private_data_data);
return;
}
state = TALLOC_P(mem_ctx, struct domain_request_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
- continuation(private_data, False);
+ continuation(private_data_data, False);
return;
}
@@ -238,15 +276,15 @@ void async_domain_request(TALLOC_CTX *mem_ctx,
state->request = request;
state->response = response;
state->continuation = continuation;
- state->private_data = private_data;
+ state->private_data_data = private_data_data;
init_child_connection(domain, domain_init_recv, state);
}
-static void recvfrom_child(void *private_data, BOOL success)
+static void recvfrom_child(void *private_data_data, BOOL success)
{
struct winbindd_cli_state *state =
- talloc_get_type_abort(private_data, struct winbindd_cli_state);
+ talloc_get_type_abort(private_data_data, struct winbindd_cli_state);
enum winbindd_result result = state->response.result;
/* This is an optimization: The child has written directly to the
@@ -278,20 +316,20 @@ void sendto_domain(struct winbindd_cli_state *state,
recvfrom_child, state);
}
-static void domain_init_recv(void *private_data, BOOL success)
+static void domain_init_recv(void *private_data_data, BOOL success)
{
struct domain_request_state *state =
- talloc_get_type_abort(private_data, struct domain_request_state);
+ talloc_get_type_abort(private_data_data, struct domain_request_state);
if (!success) {
DEBUG(5, ("Domain init returned an error\n"));
- state->continuation(state->private_data, False);
+ state->continuation(state->private_data_data, False);
return;
}
async_request(state->mem_ctx, &state->domain->child,
state->request, state->response,
- state->continuation, state->private_data);
+ state->continuation, state->private_data_data);
}
struct winbindd_child_dispatch_table {
@@ -466,39 +504,34 @@ static BOOL fork_domain_child(struct winbindd_child *child)
main_loop_talloc_free();
/* fetch a request from the main daemon */
- dual_client_read(&state);
+ child_read_request(&state);
if (state.finished) {
/* we lost contact with our parent */
exit(0);
}
- /* process full rquests */
- if (state.read_buf_len == sizeof(state.request)) {
- DEBUG(4,("child daemon request %d\n",
- (int)state.request.cmd));
+ DEBUG(4,("child daemon request %d\n", (int)state.request.cmd));
- ZERO_STRUCT(state.response);
- state.request.null_term = '\0';
- child_process_request(child->domain, &state);
+ ZERO_STRUCT(state.response);
+ state.request.null_term = '\0';
+ child_process_request(child->domain, &state);
- cache_store_response(sys_getpid(), &state.response);
+ SAFE_FREE(state.request.extra_data);
- SAFE_FREE(state.response.extra_data);
+ cache_store_response(sys_getpid(), &state.response);
- /* We just send the result code back, the result
- * structure needs to be fetched via the
- * winbindd_cache. Hmm. That needs fixing... */
+ SAFE_FREE(state.response.extra_data);
- if (write_data(state.sock,
- (void *)&state.response.result,
- sizeof(state.response.result)) !=
- sizeof(state.response.result)) {
- DEBUG(0, ("Could not write result\n"));
- exit(1);
- }
+ /* We just send the result code back, the result
+ * structure needs to be fetched via the
+ * winbindd_cache. Hmm. That needs fixing... */
- state.read_buf_len = 0;
+ if (write_data(state.sock, (void *)&state.response.result,
+ sizeof(state.response.result)) !=
+ sizeof(state.response.result)) {
+ DEBUG(0, ("Could not write result\n"));
+ exit(1);
}
}
}
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index 6261dfb616..c52ee2d960 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -1150,10 +1150,10 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
DOM_SID user_sid;
NTSTATUS status;
- int i, num_groups;
- size_t bufsize;
- ssize_t len;
+ char *sidstring;
+ size_t len;
DOM_SID *groups;
+ int num_groups;
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
@@ -1176,22 +1176,15 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
return WINBINDD_OK;
}
- len=bufsize=0;
- state->response.extra_data = NULL;
-
- for (i=0; i<num_groups; i++) {
- sprintf_append(NULL, (char **)&state->response.extra_data,
- &len, &bufsize,
- "%s\n", sid_string_static(&groups[i]));
- }
-
- if (state->response.extra_data == NULL) {
- /* Hmmm. Allocation failed somewhere */
+ if (!print_sidlist(NULL, groups, num_groups, &sidstring, &len)) {
+ DEBUG(0, ("malloc failed\n"));
return WINBINDD_ERROR;
}
- state->response.data.num_entries = num_groups;
+ state->response.extra_data = sidstring;
state->response.length += len+1;
+ state->response.data.num_entries = num_groups;
return WINBINDD_OK;
}
+
diff --git a/source3/nsswitch/winbindd_misc.c b/source3/nsswitch/winbindd_misc.c
index 6f72a0e2c6..83c4c0f6ee 100644
--- a/source3/nsswitch/winbindd_misc.c
+++ b/source3/nsswitch/winbindd_misc.c
@@ -58,12 +58,8 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do
invalidate_cm_connection(&contact_domain->conn);
{
- struct rpc_pipe_client *cli;
- unsigned char *session_key;
- DOM_CRED *creds;
-
- result = cm_connect_netlogon(contact_domain, state->mem_ctx,
- &cli, &session_key, &creds);
+ struct rpc_pipe_client *netlogon_pipe;
+ result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
}
if (!NT_STATUS_IS_OK(result)) {
@@ -169,7 +165,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
{
fstring dcname_slash;
char *p;
- struct rpc_pipe_client *cli;
+ struct rpc_pipe_client *netlogon_pipe;
NTSTATUS result;
state->request.domain_name
@@ -178,21 +174,14 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
DEBUG(3, ("[%5lu]: Get DC name for %s\n", (unsigned long)state->pid,
state->request.domain_name));
- {
- /* These var's can be ignored -- we're not requesting
- anything in the credential chain here */
- unsigned char *session_key;
- DOM_CRED *creds;
- result = cm_connect_netlogon(domain, state->mem_ctx, &cli,
- &session_key, &creds);
- }
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1, ("Can't contact our the NETLOGON pipe\n"));
return WINBINDD_ERROR;
}
- result = rpccli_netlogon_getdcname(cli, state->mem_ctx, domain->dcname,
+ result = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, domain->dcname,
state->request.domain_name,
dcname_slash);
@@ -202,11 +191,14 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
}
p = dcname_slash;
- if (*p == '\\') p+=1;
- if (*p == '\\') p+=1;
+ if (*p == '\\') {
+ p+=1;
+ }
+ if (*p == '\\') {
+ p+=1;
+ }
fstrcpy(state->response.data.dc_name, p);
-
return WINBINDD_OK;
}
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index d012811d37..c1bb4b2600 100644
--- a/source3/nsswitch/winbindd_nss.h
+++ b/source3/nsswitch/winbindd_nss.h
@@ -175,6 +175,8 @@ typedef struct winbindd_gr {
/* Flag to say this is a winbindd internal send - don't recurse. */
#define WBFLAG_RECURSE 0x0800
+#define WINBINDD_MAX_EXTRA_DATA (128*1024)
+
/* Winbind request structure */
struct winbindd_request {
@@ -183,7 +185,6 @@ struct winbindd_request {
pid_t pid; /* pid of calling process */
uint32 flags; /* flags relavant to a given request */
fstring domain_name; /* name of domain for which the request applies */
- int msgid;
union {
fstring winsreq; /* WINS request */
@@ -240,10 +241,9 @@ struct winbindd_request {
gid_t gid;
fstring sid;
} dual_idmapset;
- struct {
- fstring cache_key;
- } dual_sidaliases;
} data;
+ char *extra_data;
+ size_t extra_len;
char null_term;
};
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index a0712144ee..c2324291a6 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -37,7 +37,7 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
return NT_STATUS_NO_MEMORY;
}
- if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+ if (!net_io_user_info3("", info3, &ps, 1, 3, False)) {
prs_mem_free(&ps);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -227,15 +227,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
{
NTSTATUS result;
fstring name_domain, name_user;
- const char *srv_name_slash;
NET_USER_INFO_3 info3;
- unsigned char *session_key;
- struct rpc_pipe_client *pipe_cli;
+ struct rpc_pipe_client *netlogon_pipe;
uchar chal[8];
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
- DOM_CRED ret_creds;
- DOM_CRED *credentials;
int attempts = 0;
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
@@ -311,7 +307,6 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
local_nt_response,
sizeof(local_nt_response));
}
-
/* what domain should we contact? */
@@ -333,49 +328,30 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
contact_domain = find_our_domain();
}
- srv_name_slash = talloc_asprintf(state->mem_ctx, "\\\\%s",
- contact_domain->dcname);
- if (srv_name_slash == NULL) {
- DEBUG(0, ("talloc_asprintf failed\n"));
- return WINBINDD_ERROR;
- }
-
/* check authentication loop */
do {
- DOM_CRED clnt_creds;
ZERO_STRUCT(info3);
- ZERO_STRUCT(ret_creds);
retry = False;
- result = cm_connect_netlogon(contact_domain, state->mem_ctx,
- &pipe_cli, &session_key,
- &credentials);
+ result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
goto done;
}
- credentials->timestamp.time = time(NULL);
- memcpy(&clnt_creds, credentials, sizeof(clnt_creds));
-
- /* Calculate the new credentials. */
- cred_create(session_key, &credentials->challenge,
- clnt_creds.timestamp, &(clnt_creds.challenge));
-
- result = rpccli_netlogon_sam_network_logon(pipe_cli,
- state->mem_ctx,
- srv_name_slash,
- &clnt_creds,
- &ret_creds,
- name_user,
- name_domain,
- global_myname(),
- chal, lm_resp,
- nt_resp, &info3,
- session_key);
+ result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+ state->mem_ctx,
+ contact_domain->dcname, /* server name */
+ name_user, /* user name */
+ name_domain, /* target domain */
+ global_myname(), /* workstation */
+ chal,
+ lm_resp,
+ nt_resp,
+ &info3);
attempts += 1;
/* We have to try a second time as cm_connect_netlogon
@@ -404,21 +380,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
} while ( (attempts < 2) && retry );
- /* Only check creds if we got a connection. */
- if (contact_domain->conn.cli &&
- !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
- NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) {
- if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) {
- DEBUG(3, ("DC %s sent wrong credentials\n",
- pipe_cli->cli->srv_name_slash));
- result = NT_STATUS_ACCESS_DENIED;
- }
- }
-
if (NT_STATUS_IS_OK(result)) {
/* Check if the user is in the right group */
- if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, state->request.data.auth.require_membership_of_sid))) {
+ if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3,
+ state->request.data.auth.require_membership_of_sid))) {
DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
state->request.data.auth.user,
state->request.data.auth.require_membership_of_sid));
@@ -426,8 +392,10 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
}
done:
+
/* give us a more useful (more correct?) error code */
- if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
+ if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
+ (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
result = NT_STATUS_NO_LOGON_SERVERS;
}
@@ -450,7 +418,9 @@ done:
char *afsname = SMB_STRDUP(lp_afs_username_map());
char *cell;
- if (afsname == NULL) goto no_token;
+ if (afsname == NULL) {
+ goto no_token;
+ }
afsname = realloc_string_sub(afsname, "%D", name_domain);
afsname = realloc_string_sub(afsname, "%u", name_user);
@@ -466,7 +436,9 @@ done:
afsname = realloc_string_sub(afsname, "%s", sidstr);
}
- if (afsname == NULL) goto no_token;
+ if (afsname == NULL) {
+ goto no_token;
+ }
strlower_m(afsname);
@@ -474,7 +446,9 @@ done:
cell = strchr(afsname, '@');
- if (cell == NULL) goto no_token;
+ if (cell == NULL) {
+ goto no_token;
+ }
*cell = '\0';
cell += 1;
@@ -565,16 +539,12 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result;
- const char *srv_name_slash;
NET_USER_INFO_3 info3;
- unsigned char *session_key;
- struct rpc_pipe_client *pipe_cli;
- DOM_CRED *credentials;
+ struct rpc_pipe_client *netlogon_pipe;
const char *name_user = NULL;
const char *name_domain = NULL;
const char *workstation;
struct winbindd_domain *contact_domain;
- DOM_CRED ret_creds;
int attempts = 0;
BOOL retry;
@@ -618,9 +588,10 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
goto done;
}
- lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
- nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
-
+ lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp,
+ state->request.data.auth_crap.lm_resp_len);
+ nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp,
+ state->request.data.auth_crap.nt_resp_len);
/* what domain should we contact? */
@@ -631,33 +602,20 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
} else {
if (is_myname(name_domain)) {
DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
contact_domain = find_our_domain();
}
- srv_name_slash = talloc_asprintf(state->mem_ctx, "\\\\%s",
- contact_domain->dcname);
- if (srv_name_slash == NULL) {
- DEBUG(0, ("talloc_asprintf failed\n"));
- return WINBINDD_ERROR;
- }
-
do {
- DOM_CRED clnt_creds;
ZERO_STRUCT(info3);
- ZERO_STRUCT(ret_creds);
retry = False;
- result = cm_connect_netlogon(contact_domain, state->mem_ctx,
- &pipe_cli, &session_key,
- &credentials);
+ result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
@@ -665,25 +623,16 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
goto done;
}
- credentials->timestamp.time = time(NULL);
- memcpy(&clnt_creds, credentials, sizeof(clnt_creds));
-
- /* Calculate the new credentials. */
- cred_create(session_key, &credentials->challenge,
- clnt_creds.timestamp, &(clnt_creds.challenge));
-
- result = rpccli_netlogon_sam_network_logon(pipe_cli,
- state->mem_ctx,
- srv_name_slash,
- &clnt_creds,
- &ret_creds,
- name_user,
- name_domain,
- global_myname(),
- state->request.data.auth_crap.chal,
- lm_resp,
- nt_resp, &info3,
- session_key);
+ result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+ state->mem_ctx,
+ contact_domain->dcname,
+ name_user,
+ name_domain,
+ global_myname(),
+ state->request.data.auth_crap.chal,
+ lm_resp,
+ nt_resp,
+ &info3);
attempts += 1;
@@ -712,19 +661,9 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
} while ( (attempts < 2) && retry );
- /* Only check creds if we got a connection. */
- if (contact_domain->conn.cli &&
- !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
- (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
- if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) {
- DEBUG(3, ("DC %s sent wrong credentials\n",
- pipe_cli->cli->srv_name_slash));
- result = NT_STATUS_ACCESS_DENIED;
- }
- }
-
if (NT_STATUS_IS_OK(result)) {
- if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, state->request.data.auth_crap.require_membership_of_sid))) {
+ if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3,
+ state->request.data.auth_crap.require_membership_of_sid))) {
DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
state->request.data.auth_crap.user,
state->request.data.auth_crap.require_membership_of_sid));
@@ -736,14 +675,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
} else if (state->request.flags & WBFLAG_PAM_UNIX_NAME) {
/* ntlm_auth should return the unix username, per
'winbind use default domain' settings and the like */
-
+
fstring username_out;
const char *nt_username, *nt_domain;
if (!(nt_username = unistr2_tdup(state->mem_ctx, &(info3.uni_user_name)))) {
/* If the server didn't give us one, just use the one we sent them */
nt_username = name_user;
}
-
+
if (!(nt_domain = unistr2_tdup(state->mem_ctx, &(info3.uni_logon_dom)))) {
/* If the server didn't give us one, just use the one we sent them */
nt_domain = name_domain;
@@ -762,29 +701,34 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
}
if (state->request.flags & WBFLAG_PAM_USER_SESSION_KEY) {
- memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, sizeof(state->response.data.auth.user_session_key) /* 16 */);
+ memcpy(state->response.data.auth.user_session_key, info3.user_sess_key,
+ sizeof(state->response.data.auth.user_session_key) /* 16 */);
}
if (state->request.flags & WBFLAG_PAM_LMKEY) {
- memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
+ memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key,
+ sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
}
}
done:
+
/* give us a more useful (more correct?) error code */
- if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
+ if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||
+ (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
result = NT_STATUS_NO_LOGON_SERVERS;
}
if (state->request.flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
result = nt_status_squash(result);
}
-
+
state->response.data.auth.nt_status = NT_STATUS_V(result);
fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
-
+
/* we might have given a more useful error above */
- if (!*state->response.data.auth.error_string)
+ if (!*state->response.data.auth.error_string) {
fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
+ }
state->response.data.auth.pam_error = nt_status_to_pam(result);
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c
index 74645564d4..70275abf92 100644
--- a/source3/pam_smbpass/pam_smb_auth.c
+++ b/source3/pam_smbpass/pam_smb_auth.c
@@ -84,6 +84,11 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
pam_sm_setcred(). */
ret_data = SMB_MALLOC_P(int);
+ /* we need to do this before we call AUTH_RETURN */
+ /* Getting into places that might use LDAP -- protect the app
+ from a SIGPIPE it's not expecting */
+ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
+
/* get the username */
retval = pam_get_user( pamh, &name, "Username: " );
if ( retval != PAM_SUCCESS ) {
@@ -96,10 +101,6 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", name );
}
- /* Getting into places that might use LDAP -- protect the app
- from a SIGPIPE it's not expecting */
- oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
-
if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
retval = PAM_AUTHINFO_UNAVAIL;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 7c5a17b86f..0a4f0556ae 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -122,6 +122,7 @@ typedef struct
char *szConfigFile;
char *szSMBPasswdFile;
char *szPrivateDir;
+ char *szCountersDir;
char **szPassdbBackend;
char **szPreloadModules;
char *szPasswordServer;
@@ -188,6 +189,7 @@ typedef struct
char *szEventLogNumRecordsCommand;
char *szEventLogOldestRecordCommand;
char *szEventLogCloseCommand;
+ char *szEventLogControlCommand;
char **szEventLogs;
char *szGuestaccount;
char *szManglingMethod;
@@ -833,6 +835,7 @@ static struct parm_struct parm_table[] = {
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
{"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
+ {"counters dir", P_STRING, P_GLOBAL, &Globals.szCountersDir, NULL, NULL, FLAG_ADVANCED},
{"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
@@ -966,7 +969,7 @@ static struct parm_struct parm_table[] = {
{"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
{"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
- {"enable svcctl", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
+ {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
{N_("Tuning Options"), P_SEP, P_SEPARATOR},
@@ -1156,6 +1159,8 @@ static struct parm_struct parm_table[] = {
{"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 close command", P_STRING, P_GLOBAL, &Globals.szEventLogCloseCommand, handle_eventlog, NULL, FLAG_ADVANCED},
+ {"eventlog control command", P_STRING, P_GLOBAL, &Globals.szEventLogControlCommand, 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},
@@ -1428,6 +1433,7 @@ static void init_globals(void)
Globals.bLoadPrinters = True;
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;
@@ -1520,7 +1526,6 @@ static void init_globals(void)
#else
Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
#endif /* WITH_LDAP_SAMCONFIG */
-
string_set(&Globals.szLdapSuffix, "");
string_set(&Globals.szLdapMachineSuffix, "");
string_set(&Globals.szLdapUserSuffix, "");
@@ -1581,6 +1586,8 @@ static void init_globals(void)
string_set(&Globals.szEventLogClearCommand, "");
string_set(&Globals.szEventLogNumRecordsCommand, "");
string_set(&Globals.szEventLogOldestRecordCommand, "");
+ string_set(&Globals.szEventLogCloseCommand, "");
+ string_set(&Globals.szEventLogControlCommand, "");
Globals.winbind_cache_time = 300; /* 5 minutes */
Globals.bWinbindEnumUsers = True;
@@ -1609,7 +1616,7 @@ static void init_globals(void)
operations as root */
Globals.bEnablePrivileges = False;
-
+
Globals.bASUSupport = True;
Globals.szServicesList = str_list_make( "Spooler NETLOGON", NULL );
@@ -1703,6 +1710,7 @@ FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
+FN_GLOBAL_STRING(lp_counters_dir, &Globals.szCountersDir)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
@@ -1804,6 +1812,8 @@ 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_STRING(lp_eventlog_control_cmd, &Globals.szEventLogControlCommand)
+
FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
@@ -1904,7 +1914,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_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
@@ -3344,7 +3354,10 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
break;
case P_OCTAL:
- sscanf(pszParmValue, "%o", (int *)parm_ptr);
+ i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
+ if ( i != 1 ) {
+ DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
+ }
break;
case P_LIST:
@@ -3698,13 +3711,13 @@ static void dump_a_service(service * pService, FILE * f)
}
}
- if (pService->param_opt != NULL) {
- data = pService->param_opt;
- while(data) {
- fprintf(f, "\t%s = %s\n", data->key, data->value);
- data = data->next;
- }
- }
+ if (pService->param_opt != NULL) {
+ data = pService->param_opt;
+ while(data) {
+ fprintf(f, "\t%s = %s\n", data->key, data->value);
+ data = data->next;
+ }
+ }
}
/***************************************************************************
@@ -4128,7 +4141,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
are denied */
lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
if ( lp_enable_asu_support() )
- lp_add_ipc("ADMIN$", False);
+ lp_add_ipc("ADMIN$", False);
}
set_server_role();
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 4cd9516dd1..6b58210919 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -97,19 +97,27 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAM
}
}
- if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
- fstring sid_str;
- DOM_SID tmp_sid;
- uint32 rid;
+ if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ return True;
+ }
- DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+ DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying "
+ "special SIDs.\n", sid_string_static(sid)));
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- lookup_known_rid(&tmp_sid, rid, name, name_type);
+ {
+ const char *dom, *obj_name;
+
+ if (lookup_special_sid(sid, &dom, &obj_name, name_type)) {
+ DEBUG(10, ("found %s\\%s\n", dom, obj_name));
+ fstrcpy(dom_name, dom);
+ fstrcpy(name, obj_name);
+ return True;
+ }
}
- return True;
+
+ DEBUG(10, ("lookup_sid failed\n"));
+
+ return False;
}
/*****************************************************************
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 283eb7f1c1..a7ff3a04f7 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -1875,7 +1875,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
/* Change from V1 is addition of password history field. */
- account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
@@ -2083,7 +2083,7 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
nt_pw_len = 0;
}
- account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
@@ -2292,8 +2292,8 @@ BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
return True;
}
- if (!account_policy_get(AP_RESET_COUNT_TIME, &resettime)) {
- DEBUG(0, ("pdb_update_bad_password_count: account_policy_get failed.\n"));
+ if (!pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime)) {
+ DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
return False;
}
@@ -2334,8 +2334,8 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
return True;
}
- if (!account_policy_get(AP_LOCK_ACCOUNT_DURATION, &duration)) {
- DEBUG(0, ("pdb_update_autolock_flag: account_policy_get failed.\n"));
+ if (!pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration)) {
+ DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
return False;
}
@@ -2383,9 +2383,9 @@ BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
return False;
/* Retrieve the account lockout policy */
- if (!account_policy_get(AP_BAD_ATTEMPT_LOCKOUT,
+ if (!pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
&account_policy_lockout)) {
- DEBUG(0, ("pdb_increment_bad_password_count: account_policy_get failed.\n"));
+ DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
return False;
}
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index 12e8bcc9cf..783e9e23fa 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -1123,7 +1123,7 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
return False;
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
+ if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
|| (expire==(uint32)-1) || (expire == 0)) {
if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), PDB_CHANGED))
return False;
@@ -1134,7 +1134,7 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
return False;
}
- if (!account_policy_get(AP_MIN_PASSWORD_AGE, &min_age)
+ if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age)
|| (min_age==(uint32)-1)) {
if (!pdb_set_pass_can_change_time (sampass, 0, PDB_CHANGED))
return False;
@@ -1189,13 +1189,13 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
uchar *pwhistory;
uint32 pwHistLen;
- account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen != 0){
uint32 current_history_len;
/* We need to make sure we don't have a race condition here - the
account policy history length can change between when the pw_history
was first loaded into the SAM_ACCOUNT struct and now.... JRA. */
- pwhistory = CONST_DISCARD(uchar *, pdb_get_pw_history(sampass, &current_history_len));
+ pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
if (current_history_len != pwHistLen) {
/* After closing and reopening SAM_ACCOUNT the history
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index d4407492c2..a9e41984c3 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -665,43 +665,46 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
rids, names, attrs);
}
-static BOOL context_search_users(struct pdb_context *context,
- struct pdb_search *search, uint16 acct_flags)
+static NTSTATUS context_get_account_policy(struct pdb_context *context,
+ int policy_index, uint32 *value)
{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
if ((!context) || (!context->pdb_methods)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ return ret;
}
- return context->pdb_methods->search_users(context->pdb_methods,
- search, acct_flags);
+ return context->pdb_methods->get_account_policy(context->pdb_methods,
+ policy_index, value);
}
-static BOOL context_search_groups(struct pdb_context *context,
- struct pdb_search *search)
+static NTSTATUS context_set_account_policy(struct pdb_context *context,
+ int policy_index, uint32 value)
{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
if ((!context) || (!context->pdb_methods)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ return ret;
}
- return context->pdb_methods->search_groups(context->pdb_methods,
- search);
+ return context->pdb_methods->set_account_policy(context->pdb_methods,
+ policy_index, value);
}
-static BOOL context_search_aliases(struct pdb_context *context,
- struct pdb_search *search,
- const DOM_SID *sid)
+static NTSTATUS context_get_seq_num(struct pdb_context *context, time_t *seq_num)
{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
if ((!context) || (!context->pdb_methods)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
- return False;
+ return ret;
}
- return context->pdb_methods->search_aliases(context->pdb_methods,
- search, sid);
+ return context->pdb_methods->get_seq_num(context->pdb_methods, seq_num);
}
-
+
/******************************************************************
Free and cleanup a pdb context, any associated data and anything
that the attached modules might have associated.
@@ -721,6 +724,43 @@ static void free_pdb_context(struct pdb_context **context)
*context = NULL;
}
+static BOOL context_search_users(struct pdb_context *context,
+ struct pdb_search *search, uint16 acct_flags)
+{
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_methods->search_users(context->pdb_methods,
+ search, acct_flags);
+}
+
+static BOOL context_search_groups(struct pdb_context *context,
+ struct pdb_search *search)
+{
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_methods->search_groups(context->pdb_methods,
+ search);
+}
+
+static BOOL context_search_aliases(struct pdb_context *context,
+ struct pdb_search *search,
+ const DOM_SID *sid)
+{
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return False;
+ }
+
+ return context->pdb_methods->search_aliases(context->pdb_methods,
+ search, sid);
+}
+
/******************************************************************
Make a pdb_methods from scratch
*******************************************************************/
@@ -832,6 +872,11 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
(*context)->pdb_lookup_rids = context_lookup_rids;
+ (*context)->pdb_get_account_policy = context_get_account_policy;
+ (*context)->pdb_set_account_policy = context_set_account_policy;
+
+ (*context)->pdb_get_seq_num = context_get_seq_num;
+
(*context)->pdb_search_users = context_search_users;
(*context)->pdb_search_groups = context_search_groups;
(*context)->pdb_search_aliases = context_search_aliases;
@@ -1318,6 +1363,41 @@ NTSTATUS pdb_lookup_rids(TALLOC_CTX *mem_ctx,
num_rids, rids, names, attrs);
}
+BOOL pdb_get_account_policy(int policy_index, uint32 *value)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_get_account_policy(pdb_context, policy_index, value));
+}
+
+BOOL pdb_set_account_policy(int policy_index, uint32 value)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_set_account_policy(pdb_context, policy_index, value));
+}
+
+BOOL pdb_get_seq_num(time_t *seq_num)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return False;
+ }
+
+ return NT_STATUS_IS_OK(pdb_context->
+ pdb_get_seq_num(pdb_context, seq_num));
+}
/***************************************************************
Initialize the static context (at smbd startup etc).
@@ -1380,6 +1460,22 @@ static void pdb_default_endsampwent(struct pdb_methods *methods)
return; /* NT_STATUS_NOT_IMPLEMENTED; */
}
+static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+{
+ return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+{
+ return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+}
+
+static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
+{
+ *seq_num = time(NULL);
+ return NT_STATUS_OK;
+}
+
static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
uid_t uid, uid_t **uids, int *num)
{
@@ -1908,6 +2004,10 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
(*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
(*methods)->enum_alias_memberships = pdb_default_alias_memberships;
(*methods)->lookup_rids = pdb_default_lookup_rids;
+ (*methods)->get_account_policy = pdb_default_get_account_policy;
+ (*methods)->set_account_policy = pdb_default_set_account_policy;
+ (*methods)->get_seq_num = pdb_default_get_seq_num;
+
(*methods)->search_users = pdb_default_search_users;
(*methods)->search_groups = pdb_default_search_groups;
(*methods)->search_aliases = pdb_default_search_aliases;
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 99f6670653..e44ccc3bf9 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -178,6 +178,146 @@ static const char* get_objclass_filter( int schema_ver )
return objclass_filter;
}
+/*****************************************************************
+ Scan a sequence number off OpenLDAP's syncrepl contextCSN
+******************************************************************/
+
+static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
+{
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *entry = NULL;
+ TALLOC_CTX *mem_ctx;
+ char **values = NULL;
+ int rc, num_result, num_values, rid;
+ pstring suffix;
+ fstring tok;
+ const char *p;
+ const char **attrs;
+
+ /* Unfortunatly there is no proper way to detect syncrepl-support in
+ * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
+ * but do not show up in the root-DSE yet. Neither we can query the
+ * subschema-context for the syncProviderSubentry or syncConsumerSubentry
+ * objectclass. Currently we require lp_ldap_suffix() to show up as
+ * namingContext. - Guenther
+ */
+
+ if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
+ return ntstatus;
+ }
+
+ if (!seq_num) {
+ DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
+ return ntstatus;
+ }
+
+ if (!smbldap_has_naming_context(ldap_state->smbldap_state, lp_ldap_suffix())) {
+ DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
+ "as top-level namingContext\n", lp_ldap_suffix()));
+ return ntstatus;
+ }
+
+ mem_ctx = talloc_init("ldapsam_get_seq_num");
+
+ if (mem_ctx == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ attrs = TALLOC_ARRAY(mem_ctx, const char *, 2);
+
+ /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
+ rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
+ if (rid > 0) {
+
+ /* consumer syncreplCookie: */
+ /* csn=20050126161620Z#0000001#00#00000 */
+ attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
+ attrs[1] = NULL;
+ pstr_sprintf( suffix, "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
+
+ } else {
+
+ /* provider contextCSN */
+ /* 20050126161620Z#000009#00#000000 */
+ attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
+ attrs[1] = NULL;
+ pstr_sprintf( suffix, "cn=ldapsync,%s", lp_ldap_suffix());
+
+ }
+
+ rc = smbldap_search(ldap_state->smbldap_state, suffix,
+ LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
+
+ if (rc != LDAP_SUCCESS) {
+
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(0,("ldapsam_get_seq_num: Failed search for suffix: %s, error: %s (%s)\n",
+ suffix,ldap_err2string(rc), ld_error?ld_error:"unknown"));
+ SAFE_FREE(ld_error);
+ goto done;
+ }
+
+ num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg);
+ if (num_result != 1) {
+ DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
+ goto done;
+ }
+
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg);
+ if (entry == NULL) {
+ DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
+ goto done;
+ }
+
+ values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, attrs[0]);
+ if (values == NULL) {
+ DEBUG(3,("ldapsam_get_seq_num: no values\n"));
+ goto done;
+ }
+
+ num_values = ldap_count_values(values);
+ if (num_values == 0) {
+ DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
+ goto done;
+ }
+
+ p = values[0];
+ if (!next_token(&p, tok, "#", sizeof(tok))) {
+ DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
+ goto done;
+ }
+
+ p = tok;
+ if (!strncmp(p, "csn=", strlen("csn=")))
+ p += strlen("csn=");
+
+ DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
+
+ *seq_num = generalized_to_unix_time(p);
+
+ /* very basic sanity check */
+ if (*seq_num <= 0) {
+ DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
+ (int)*seq_num));
+ goto done;
+ }
+
+ ntstatus = NT_STATUS_OK;
+
+ done:
+ if (values != NULL)
+ ldap_value_free(values);
+ if (msg != NULL)
+ ldap_msgfree(msg);
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return ntstatus;
+}
+
/*******************************************************************
Run the search by name.
******************************************************************/
@@ -694,9 +834,9 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
if (ldap_state->is_nds_ldap) {
char *user_dn;
- int pwd_len;
+ size_t pwd_len;
char clear_text_pw[512];
-
+
/* Make call to Novell eDirectory ldap extension to get clear text password.
NOTE: This will only work if we have an SSL connection to eDirectory. */
user_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
@@ -717,7 +857,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
} else {
DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
}
- }
+ }
if (use_samba_attrs) {
if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
@@ -741,9 +881,11 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
return False;
ZERO_STRUCT(smbntpwd);
}
- }
+ }
+
+ pwHistLen = 0;
- account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen > 0){
uint8 *pwhist = NULL;
int i;
@@ -1087,7 +1229,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if (need_update(sampass, PDB_PWHISTORY)) {
uint32 pwHistLen = 0;
- account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen == 0) {
/* Remove any password history from the LDAP store. */
memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
@@ -1153,7 +1295,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
uint16 badcount = pdb_get_bad_password_count(sampass);
time_t badtime = pdb_get_bad_password_time(sampass);
uint32 pol;
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &pol);
+ pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
(unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
@@ -2158,10 +2300,10 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
{
pstring filter;
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%d))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
LDAP_OBJ_GROUPMAP,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- gid);
+ (unsigned long)gid);
return ldapsam_getgroup(methods, filter, map);
}
@@ -2312,7 +2454,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
{
const char *attrs[] = { "memberUid", NULL };
- rc = smbldap_search(conn, lp_ldap_group_suffix(),
+ rc = smbldap_search(conn, lp_ldap_user_suffix(),
LDAP_SCOPE_SUBTREE, filter, attrs, 0,
&msg);
}
@@ -2536,10 +2678,10 @@ static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
{
pstring filter;
- pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%d))",
+ pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))",
LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- gid);
+ (unsigned long)gid);
return ldapsam_search_one_group(ldap_state, filter, result);
}
@@ -2589,7 +2731,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
ldap_msgfree(result);
pstrcpy( suffix, lp_ldap_idmap_suffix() );
- pstr_sprintf(filter, "(&(objectClass=%s)(%s=%d))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
map->gid);
@@ -3131,6 +3273,187 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
return NT_STATUS_OK;
}
+static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+{
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+ int rc;
+ LDAPMod **mods = NULL;
+ fstring value_string;
+ const char *policy_attr = NULL;
+
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)methods->private_data;
+
+ const char *attrs[2];
+
+ DEBUG(10,("ldapsam_set_account_policy\n"));
+
+ if (!ldap_state->domain_dn) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ policy_attr = get_account_policy_attr(policy_index);
+ if (policy_attr == NULL) {
+ DEBUG(0,("ldapsam_set_account_policy: invalid policy\n"));
+ return ntstatus;
+ }
+
+ attrs[0] = policy_attr;
+ attrs[1] = NULL;
+
+ slprintf(value_string, sizeof(value_string) - 1, "%i", value);
+
+ smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
+
+ rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn, mods);
+
+ ldap_mods_free(mods, True);
+
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING,&ld_error);
+
+ DEBUG(0, ("ldapsam_set_account_policy: Could not set account policy "
+ "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
+ ld_error?ld_error:"unknown"));
+ SAFE_FREE(ld_error);
+ return ntstatus;
+ }
+
+ if (!cache_account_policy_set(policy_index, value)) {
+ DEBUG(0,("ldapsam_set_account_policy: failed to update local tdb cache\n"));
+ return ntstatus;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, int policy_index, uint32 *value)
+{
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ int count;
+ int rc;
+ char **vals = NULL;
+ const char *policy_attr = NULL;
+
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)methods->private_data;
+
+ const char *attrs[2];
+
+ DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
+
+ if (!ldap_state->domain_dn) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ policy_attr = get_account_policy_attr(policy_index);
+ if (!policy_attr) {
+ DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid policy index: %d\n", policy_index));
+ return ntstatus;
+ }
+
+ attrs[0] = policy_attr;
+ attrs[1] = NULL;
+
+ rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
+ LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct,
+ LDAP_OPT_ERROR_STRING,&ld_error);
+
+ DEBUG(0, ("ldapsam_get_account_policy_from_ldap: Could not set account policy "
+ "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
+ ld_error?ld_error:"unknown"));
+ SAFE_FREE(ld_error);
+ return ntstatus;
+ }
+
+ count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
+ if (count < 1) {
+ goto out;
+ }
+
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ if (entry == NULL) {
+ goto out;
+ }
+
+ vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, policy_attr);
+ if (vals == NULL) {
+ goto out;
+ }
+
+ *value = (uint32)atol(vals[0]);
+
+ ntstatus = NT_STATUS_OK;
+
+out:
+ if (vals)
+ ldap_value_free(vals);
+ ldap_msgfree(result);
+
+ return ntstatus;
+}
+
+/* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
+
+ - if there is a valid cache entry, return that
+ - if there is an LDAP entry, update cache and return
+ - otherwise set to default, update cache and return
+
+ Guenther
+*/
+static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+{
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+
+ if (cache_account_policy_get(policy_index, value)) {
+ DEBUG(11,("ldapsam_get_account_policy: got valid value from cache\n"));
+ return NT_STATUS_OK;
+ }
+
+ ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, value);
+ if (NT_STATUS_IS_OK(ntstatus)) {
+ goto update_cache;
+ }
+
+ DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from ldap, returning default.\n"));
+
+#if 0
+ /* should we automagically migrate old tdb value here ? */
+ if (account_policy_get(policy_index, value))
+ goto update_ldap;
+
+ DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying default\n", policy_index));
+#endif
+
+ if (!account_policy_get_default(policy_index, value)) {
+ return ntstatus;
+ }
+
+/* update_ldap: */
+
+ ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
+ if (!NT_STATUS_IS_OK(ntstatus)) {
+ return ntstatus;
+ }
+
+ update_cache:
+
+ if (!cache_account_policy_set(policy_index, *value)) {
+ DEBUG(0,("ldapsam_get_account_policy: failed to update local tdb as a cache\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
@@ -3890,6 +4213,11 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
(*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
(*pdb_method)->lookup_rids = ldapsam_lookup_rids;
+ (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
+ (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
+
+ (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
+
/* TODO: Setup private data and free */
ldap_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct ldapsam_privates);
diff --git a/source3/passdb/pdb_nds.c b/source3/passdb/pdb_nds.c
index 3e5f8d1b93..599a198c5a 100644
--- a/source3/passdb/pdb_nds.c
+++ b/source3/passdb/pdb_nds.c
@@ -550,7 +550,7 @@ static int nmasldap_get_password(
LDAP *ld,
char *objectDN,
size_t *pwdSize, /* in bytes */
- char *pwd )
+ unsigned char *pwd )
{
int err = 0;
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index edb578b1e7..6eb4305409 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -313,10 +313,11 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
unsigned char *smbpwd = smbpasswd_state->smbpwd;
unsigned char *smbntpwd = smbpasswd_state->smbntpwd;
char linebuf[256];
- unsigned char c;
+ int c;
unsigned char *p;
long uidval;
size_t linebuf_len;
+ char *status;
if(fp == NULL) {
DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
@@ -329,11 +330,12 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
/*
* Scan the file, a line at a time and check if the name matches.
*/
- while (!feof(fp)) {
+ status = linebuf;
+ while (status && !feof(fp)) {
linebuf[0] = '\0';
- fgets(linebuf, 256, fp);
- if (ferror(fp)) {
+ status = fgets(linebuf, 256, fp);
+ if (status == NULL && ferror(fp)) {
return NULL;
}
@@ -651,7 +653,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
#ifdef DEBUG_PASSWORD
DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|",
- fd, new_entry_length, new_entry));
+ fd, (int)new_entry_length, new_entry));
#endif
if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) {
@@ -689,9 +691,10 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/* Static buffers we will return. */
pstring user_name;
+ char *status;
char linebuf[256];
char readbuf[1024];
- unsigned char c;
+ int c;
fstring ascii_p16;
fstring encode_bits;
unsigned char *p = NULL;
@@ -738,13 +741,14 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/*
* Scan the file, a line at a time and check if the name matches.
*/
- while (!feof(fp)) {
+ status = linebuf;
+ while (status && !feof(fp)) {
pwd_seekpos = sys_ftell(fp);
linebuf[0] = '\0';
- fgets(linebuf, sizeof(linebuf), fp);
- if (ferror(fp)) {
+ status = fgets(linebuf, sizeof(linebuf), fp);
+ if (status == NULL && ferror(fp)) {
pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
fclose(fp);
return False;
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 6144037200..29437c35a8 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -30,6 +30,9 @@
static TDB_CONTEXT *tdb;
+/* Urrrg. global.... */
+BOOL global_machine_password_needs_changing;
+
/**
* Use a TDB to store an incrementing random seed.
*
@@ -294,12 +297,23 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
return False;
}
- if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
+ if (pass_last_set_time) {
+ *pass_last_set_time = pass->mod_time;
+ }
memcpy(ret_pwd, pass->hash, 16);
SAFE_FREE(pass);
- if (channel)
+ if (channel) {
*channel = get_default_sec_channel();
+ }
+
+ /* Test if machine password has expired and needs to be changed */
+ if (lp_machine_password_timeout()) {
+ if (pass->mod_time > 0 && time(NULL) > (pass->mod_time +
+ lp_machine_password_timeout())) {
+ global_machine_password_needs_changing = True;
+ }
+ }
return True;
}
@@ -454,11 +468,11 @@ BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32
return ret;
}
-
/************************************************************************
Routine to fetch the plaintext machine account password for a realm
-the password is assumed to be a null terminated ascii string
+ the password is assumed to be a null terminated ascii string.
************************************************************************/
+
char *secrets_fetch_machine_password(const char *domain,
time_t *pass_last_set_time,
uint32 *channel)
@@ -503,7 +517,46 @@ char *secrets_fetch_machine_password(const char *domain,
return ret;
}
+/*******************************************************************
+ Wrapper around retrieving the trust account password
+*******************************************************************/
+
+BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], uint32 *channel)
+{
+ DOM_SID sid;
+ char *pwd;
+ time_t last_set_time;
+
+ /* if we are a DC and this is not our domain, then lookup an account
+ for the domain trust */
+
+ if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) {
+ if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
+ &last_set_time)) {
+ DEBUG(0, ("get_trust_pw: could not fetch trust "
+ "account password for trusted domain %s\n",
+ domain));
+ return False;
+ }
+
+ *channel = SEC_CHAN_DOMAIN;
+ E_md4hash(pwd, ret_pwd);
+ SAFE_FREE(pwd);
+
+ return True;
+ }
+
+ /* Just get the account for the requested domain. In the future this
+ * might also cover to be member of more than one domain. */
+
+ if (secrets_fetch_trust_account_password(domain, ret_pwd,
+ &last_set_time, channel))
+ return True;
+ DEBUG(5, ("get_trust_pw: could not fetch trust account "
+ "password for domain %s\n", domain));
+ return False;
+}
/************************************************************************
Routine to delete the machine trust account password file for a domain.
@@ -523,7 +576,6 @@ BOOL trusted_domain_password_delete(const char *domain)
return secrets_delete(trustdom_keystr(domain));
}
-
BOOL secrets_store_ldap_pw(const char* dn, char* pw)
{
char *key = NULL;
@@ -541,8 +593,9 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw)
}
/*******************************************************************
- find the ldap password
+ Find the ldap password.
******************************************************************/
+
BOOL fetch_ldap_pw(char **dn, char** pw)
{
char *key = NULL;
@@ -605,7 +658,6 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
return True;
}
-
/**
* Get trusted domains info from secrets.tdb.
*
diff --git a/source3/passdb/util_sam_sid.c b/source3/passdb/util_sam_sid.c
index a9e1921e0d..42e4b6df96 100644
--- a/source3/passdb/util_sam_sid.c
+++ b/source3/passdb/util_sam_sid.c
@@ -30,15 +30,12 @@ typedef struct _known_sid_users {
const char *known_user_name;
} known_sid_users;
-static struct sid_name_map_info
+struct sid_name_map_info
{
const DOM_SID *sid;
const char *name;
const known_sid_users *known_users;
-} sid_name_map[MAX_SID_NAMES];
-
-static BOOL sid_name_map_initialized = False;
-/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
+};
static const known_sid_users everyone_users[] = {
{ 0, SID_NAME_WKN_GRP, "Everyone" },
@@ -83,64 +80,12 @@ static const known_sid_users builtin_groups[] = {
{ BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
{ 0, (enum SID_NAME_USE)0, NULL}};
-/**************************************************************************
- Quick init function.
-*************************************************************************/
-
-static void init_sid_name_map (void)
-{
- int i = 0;
-
- if (sid_name_map_initialized) return;
-
- if ((lp_security() == SEC_USER) && lp_domain_logons()) {
- sid_name_map[i].sid = get_global_sam_sid();
- /* This is not lp_workgroup() for good reason:
- it must stay around longer than the lp_*()
- strings do */
- sid_name_map[i].name = SMB_STRDUP(lp_workgroup());
- sid_name_map[i].known_users = NULL;
- i++;
- sid_name_map[i].sid = get_global_sam_sid();
- sid_name_map[i].name = SMB_STRDUP(global_myname());
- sid_name_map[i].known_users = NULL;
- i++;
- } else {
- sid_name_map[i].sid = get_global_sam_sid();
- sid_name_map[i].name = SMB_STRDUP(global_myname());
- sid_name_map[i].known_users = NULL;
- i++;
- }
-
- sid_name_map[i].sid = &global_sid_Builtin;
- sid_name_map[i].name = "BUILTIN";
- sid_name_map[i].known_users = &builtin_groups[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_World_Domain;
- sid_name_map[i].name = "";
- sid_name_map[i].known_users = &everyone_users[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_Creator_Owner_Domain;
- sid_name_map[i].name = "";
- sid_name_map[i].known_users = &creator_owner_users[0];
- i++;
-
- sid_name_map[i].sid = &global_sid_NT_Authority;
- sid_name_map[i].name = "NT Authority";
- sid_name_map[i].known_users = &nt_authority_users[0];
- i++;
-
- /* End of array. */
- sid_name_map[i].sid = NULL;
- sid_name_map[i].name = NULL;
- sid_name_map[i].known_users = NULL;
-
- sid_name_map_initialized = True;
-
- return;
-}
+static struct sid_name_map_info special_domains[] = {
+ { &global_sid_Builtin, "BUILTIN", builtin_groups },
+ { &global_sid_World_Domain, "", everyone_users },
+ { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
+ { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
+ { NULL, NULL, NULL }};
/**************************************************************************
Turns a domain SID into a name, returned in the nt_domain argument.
@@ -153,101 +98,74 @@ BOOL map_domain_sid_to_name(DOM_SID *sid, fstring nt_domain)
sid_to_string(sid_str, sid);
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
- if (nt_domain == NULL)
- return False;
+ if (sid_check_is_domain(sid)) {
+ fstrcpy(nt_domain, get_global_sam_name());
+ return True;
+ }
- while (sid_name_map[i].sid != NULL) {
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str));
- if (sid_equal(sid_name_map[i].sid, sid)) {
- fstrcpy(nt_domain, sid_name_map[i].name);
- DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain));
+ while (special_domains[i].sid != NULL) {
+ DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
+ sid_string_static(special_domains[i].sid)));
+ if (sid_equal(special_domains[i].sid, sid)) {
+ fstrcpy(nt_domain, special_domains[i].name);
+ DEBUG(5,("map_domain_sid_to_name: found '%s'\n",
+ nt_domain));
return True;
}
i++;
}
- DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str));
-
- return False;
-}
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
-{
- int i = 0;
- struct sid_name_map_info *psnm;
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
- for(i = 0; sid_name_map[i].sid != NULL; i++) {
- psnm = &sid_name_map[i];
- if(sid_equal(psnm->sid, sid)) {
- int j;
- for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) {
- if(rid == psnm->known_users[j].rid) {
- DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n",
- (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name ));
- fstrcpy( name, psnm->known_users[j].known_user_name);
- *psid_name_use = psnm->known_users[j].sid_name_use;
- return True;
- }
- }
- }
- }
+ DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n",
+ sid_string_static(sid)));
return False;
}
/**************************************************************************
- Turns a domain name into a SID.
- *** side-effect: if the domain name is NULL, it is set to our domain ***
+ Looks up a known username from one of the known domains.
***************************************************************************/
-BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain)
+BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
+ const char **name, enum SID_NAME_USE *type)
{
- int i = 0;
+ int i;
+ DOM_SID dom_sid;
+ uint32 rid;
+ const known_sid_users *users = NULL;
- if (nt_domain == NULL) {
- DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n"));
- sid_copy(sid, get_global_sam_sid());
- return True;
+ sid_copy(&dom_sid, sid);
+ if (!sid_split_rid(&dom_sid, &rid)) {
+ DEBUG(2, ("Could not split rid from SID\n"));
+ return False;
}
- if (nt_domain[0] == 0) {
- fstrcpy(nt_domain, global_myname());
- DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain));
- sid_copy(sid, get_global_sam_sid());
- return True;
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ if (sid_equal(&dom_sid, special_domains[i].sid)) {
+ *domain = special_domains[i].name;
+ users = special_domains[i].known_users;
+ break;
+ }
}
- DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain));
-
- if (!sid_name_map_initialized)
- init_sid_name_map();
+ if (users == NULL) {
+ DEBUG(10, ("SID %s is no special sid\n",
+ sid_string_static(sid)));
+ return False;
+ }
- while (sid_name_map[i].name != NULL) {
- DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name));
- if (strequal(sid_name_map[i].name, nt_domain)) {
- fstring sid_str;
- sid_copy(sid, sid_name_map[i].sid);
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str));
+ for (i=0; users[i].known_user_name != NULL; i++) {
+ if (rid == users[i].rid) {
+ *name = users[i].known_user_name;
+ *type = users[i].sid_name_use;
return True;
}
- i++;
}
- DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain));
+ DEBUG(10, ("RID of special SID %s not found\n",
+ sid_string_static(sid)));
+
return False;
}
@@ -283,20 +201,17 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char
{
int i, j;
- if (!sid_name_map_initialized)
- init_sid_name_map();
-
DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
- for (i=0; sid_name_map[i].sid != NULL; i++) {
- const known_sid_users *users = sid_name_map[i].known_users;
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ const known_sid_users *users = special_domains[i].known_users;
if (users == NULL)
continue;
for (j=0; users[j].known_user_name != NULL; j++) {
if ( strequal(users[j].known_user_name, name) ) {
- sid_copy(sid, sid_name_map[i].sid);
+ sid_copy(sid, special_domains[i].sid);
sid_append_rid(sid, users[j].rid);
*use = users[j].sid_name_use;
return True;
diff --git a/source3/printing/notify.c b/source3/printing/notify.c
index e289eba1b6..e71d9e6f25 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -176,13 +176,15 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
return;
for (i = 0; i < num_pids; i++) {
- unsigned int q_len = messages_pending_for_pid(pid_list[i]);
+ unsigned int q_len = messages_pending_for_pid(pid_to_procid(pid_list[i]));
if (q_len > 1000) {
DEBUG(5, ("print_notify_send_messages_to_printer: discarding notify to printer %s as queue length = %u\n",
printer, q_len ));
continue;
}
- message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
+ message_send_pid_with_timeout(pid_to_procid(pid_list[i]),
+ MSG_PRINTER_NOTIFY2,
+ buf, offset, True, timeout);
}
}
@@ -328,7 +330,7 @@ static void send_notify_field_values(const char *sharename, uint32 type,
static void send_notify_field_buffer(const char *sharename, uint32 type,
uint32 field, uint32 id, uint32 len,
- char *buffer)
+ const char *buffer)
{
struct spoolss_notify_msg *msg;
@@ -349,7 +351,7 @@ static void send_notify_field_buffer(const char *sharename, uint32 type,
msg->field = field;
msg->id = id;
msg->len = len;
- msg->notify.data = buffer;
+ msg->notify.data = CONST_DISCARD(char *,buffer);
send_spoolss_notify2_msg(msg);
}
@@ -484,7 +486,7 @@ void notify_printer_location(int snum, char *location)
snum, strlen(location) + 1, location);
}
-void notify_printer_byname( const char *printername, uint32 change, char *value )
+void notify_printer_byname( const char *printername, uint32 change, const char *value )
{
int snum = print_queue_snum(printername);
int type = PRINTER_NOTIFY_TYPE;
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index e6064564dc..8ae896fddf 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -265,7 +265,7 @@ BOOL cups_cache_reload(void)
* 'cups_job_delete()' - Delete a job.
*/
-static int cups_job_delete(int snum, struct printjob *pjob)
+static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
{
int ret = 1; /* Return value */
http_t *http = NULL; /* HTTP connection to server */
@@ -275,7 +275,7 @@ static int cups_job_delete(int snum, struct printjob *pjob)
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- DEBUG(5,("cups_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
+ DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
/*
* Make sure we don't ask for passwords...
@@ -712,7 +712,7 @@ static int cups_queue_get(const char *sharename,
*q = NULL;
- /* HACK ALERT!!! The porblem with support the 'printer name'
+ /* HACK ALERT!!! The problem with support the 'printer name'
option is that we key the tdb off the sharename. So we will
overload the lpq_command string to pass in the printername
(which is basically what we do for non-cups printers ... using
diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c
index 256654179e..b2484d5b43 100644
--- a/source3/printing/print_generic.c
+++ b/source3/printing/print_generic.c
@@ -27,7 +27,8 @@ run a given print command
a null terminated list of value/substitute pairs is provided
for local substitution strings
****************************************************************************/
-static int print_run_command(int snum, const char* printername, BOOL do_sub, char *command, int *outfd, ...)
+static int print_run_command(int snum, const char* printername, BOOL do_sub,
+ const char *command, int *outfd, ...)
{
pstring syscmd;
@@ -68,14 +69,13 @@ static int print_run_command(int snum, const char* printername, BOOL do_sub, cha
/****************************************************************************
delete a print job
****************************************************************************/
-static int generic_job_delete(int snum, struct printjob *pjob)
+static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
{
fstring jobstr;
/* need to delete the spooled entry */
slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum, PRINTERNAME(snum), True,
- lp_lprmcommand(snum), NULL,
+ return print_run_command( -1, sharename, False, lprm_command, NULL,
"%j", jobstr,
"%T", http_timestring(pjob->starttime),
NULL);
diff --git a/source3/printing/print_iprint.c b/source3/printing/print_iprint.c
index 33bbcb256a..6193dbe2ca 100644
--- a/source3/printing/print_iprint.c
+++ b/source3/printing/print_iprint.c
@@ -423,7 +423,7 @@ BOOL iprint_cache_reload(void)
* 'iprint_job_delete()' - Delete a job.
*/
-static int iprint_job_delete(int snum, struct printjob *pjob)
+static int iprint_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
{
int ret = 1; /* Return value */
http_t *http = NULL; /* HTTP connection to server */
@@ -434,7 +434,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
- DEBUG(5,("iprint_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
+ DEBUG(5,("iprint_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
/*
* Make sure we don't ask for passwords...
@@ -476,7 +476,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
+ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), sharename);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
@@ -489,7 +489,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
* Do the request and get back a response...
*/
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
+ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
if (response->request.status.status_code >= IPP_OK_CONFLICT) {
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 61470f1510..6e74095f71 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -691,6 +691,8 @@ struct traverse_struct {
int qcount, snum, maxcount, total_jobs;
const char *sharename;
time_t lpq_time;
+ const char *lprm_command;
+ struct printif *print_if;
};
/****************************************************************************
@@ -737,7 +739,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
/* if a job is not spooled and the process doesn't
exist then kill it. This cleans up after smbd
deaths */
- if (!process_exists(pjob.pid)) {
+ if (!process_exists_by_pid(pjob.pid)) {
DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
(unsigned int)jobid, (unsigned int)pjob.pid ));
pjob_delete(ts->sharename, jobid);
@@ -750,9 +752,38 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
if ( pjob.smbjob ) {
for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
- if (jobid == curr_jobid)
+ uint32 curr_jobid;
+
+ if ( pjob.status == LPQ_DELETED )
+ continue;
+
+ curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
+
+ if (jobid == curr_jobid) {
+
+ /* try to clean up any jobs that need to be deleted */
+
+ if ( pjob.status == LPQ_DELETING ) {
+ int result;
+
+ result = (*(ts->print_if->job_delete))(
+ ts->sharename, ts->lprm_command, &pjob );
+
+ if ( result != 0 ) {
+ /* if we can't delete, then reset the job status */
+ pjob.status = LPQ_QUEUED;
+ pjob_store(ts->sharename, jobid, &pjob);
+ }
+ else {
+ /* if we deleted the job, the remove the tdb record */
+ pjob_delete(ts->sharename, jobid);
+ pjob.status = LPQ_DELETED;
+ }
+
+ }
+
break;
+ }
}
}
@@ -779,9 +810,10 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
return 0;
}
- /* Save the pjob attributes we will store. */
- /* FIXME!!! This is the only place where queue->job
+ /* Save the pjob attributes we will store.
+ FIXME!!! This is the only place where queue->job
represents the SMB jobid --jerry */
+
ts->queue[i].job = jobid;
ts->queue[i].size = pjob.size;
ts->queue[i].page_count = pjob.page_count;
@@ -840,7 +872,7 @@ static pid_t get_updating_pid(const char *sharename)
updating_pid = IVAL(data.dptr, 0);
SAFE_FREE(data.dptr);
- if (process_exists(updating_pid))
+ if (process_exists_by_pid(updating_pid))
return updating_pid;
return (pid_t)-1;
@@ -910,6 +942,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
/****************************************************************************
Store the sorted queue representation for later portmon retrieval.
+ Skip deleted jobs
****************************************************************************/
static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
@@ -923,13 +956,17 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
if (max_reported_jobs && (max_reported_jobs < pts->qcount))
pts->qcount = max_reported_jobs;
- qcount = pts->qcount;
+ qcount = 0;
/* Work out the size. */
data.dsize = 0;
data.dsize += tdb_pack(NULL, 0, "d", qcount);
for (i = 0; i < pts->qcount; i++) {
+ if ( queue[i].status == LPQ_DELETED )
+ continue;
+
+ qcount++;
data.dsize += tdb_pack(NULL, 0, "ddddddff",
(uint32)queue[i].job,
(uint32)queue[i].size,
@@ -947,6 +984,9 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
len = 0;
len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
for (i = 0; i < pts->qcount; i++) {
+ if ( queue[i].status == LPQ_DELETED )
+ continue;
+
len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
(uint32)queue[i].job,
(uint32)queue[i].size,
@@ -1024,6 +1064,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
|| (time_now - last_qscan_time) >= lp_lpqcachetime()
|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
{
+ uint32 u;
time_t msg_pending_time;
DEBUG(4, ("print_cache_expired: cache expired for queue %s "
@@ -1039,8 +1080,8 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
if ( check_pending
- && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time )
- && msg_pending_time > 0
+ && tdb_fetch_uint32( pdb->tdb, key, &u )
+ && (msg_pending_time=u) > 0
&& msg_pending_time <= time_now
&& (time_now - msg_pending_time) < 60 )
{
@@ -1063,7 +1104,7 @@ done:
static void print_queue_update_internal( const char *sharename,
struct printif *current_printif,
- char *lpq_command )
+ char *lpq_command, char *lprm_command )
{
int i, qcount;
print_queue_struct *queue = NULL;
@@ -1141,8 +1182,14 @@ static void print_queue_update_internal( const char *sharename,
}
pjob->sysjob = queue[i].job;
- pjob->status = queue[i].status;
+
+ /* don't reset the status on jobs to be deleted */
+
+ if ( pjob->status != LPQ_DELETING )
+ pjob->status = queue[i].status;
+
pjob_store(sharename, jobid, pjob);
+
check_job_changed(sharename, jcdata, jobid);
}
@@ -1156,6 +1203,8 @@ static void print_queue_update_internal( const char *sharename,
tstruct.total_jobs = 0;
tstruct.lpq_time = time(NULL);
tstruct.sharename = sharename;
+ tstruct.lprm_command = lprm_command;
+ tstruct.print_if = current_printif;
tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
@@ -1216,7 +1265,7 @@ static void print_queue_update_internal( const char *sharename,
static void print_queue_update_with_lock( const char *sharename,
struct printif *current_printif,
- char *lpq_command )
+ char *lpq_command, char *lprm_command )
{
fstring keystr;
struct tdb_print_db *pdb;
@@ -1283,7 +1332,8 @@ static void print_queue_update_with_lock( const char *sharename,
/* do the main work now */
- print_queue_update_internal( sharename, current_printif, lpq_command );
+ print_queue_update_internal( sharename, current_printif,
+ lpq_command, lprm_command );
/* Delete our pid from the db. */
set_updating_pid(sharename, False);
@@ -1293,17 +1343,19 @@ static void print_queue_update_with_lock( const char *sharename,
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
+static void print_queue_receive(int msg_type, struct process_id src,
+ void *buf, size_t msglen)
{
fstring sharename;
- pstring lpqcommand;
+ pstring lpqcommand, lprmcommand;
int printing_type;
size_t len;
- len = tdb_unpack( buf, msglen, "fdP",
+ len = tdb_unpack( buf, msglen, "fdPP",
sharename,
&printing_type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
if ( len == -1 ) {
DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
@@ -1312,7 +1364,7 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle
print_queue_update_with_lock(sharename,
get_printer_fns_from_type(printing_type),
- lpqcommand );
+ lpqcommand, lprmcommand );
return;
}
@@ -1382,7 +1434,7 @@ static void print_queue_update(int snum, BOOL force)
{
fstring key;
fstring sharename;
- pstring lpqcommand;
+ pstring lpqcommand, lprmcommand;
char *buffer = NULL;
size_t len = 0;
size_t newlen;
@@ -1398,6 +1450,10 @@ static void print_queue_update(int snum, BOOL force)
string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False );
standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+ pstrcpy( lprmcommand, lp_lprmcommand(snum));
+ string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False );
+ standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );
+
/*
* Make sure that the background queue process exists.
* Otherwise just do the update ourselves
@@ -1406,7 +1462,7 @@ static void print_queue_update(int snum, BOOL force)
if ( force || background_lpq_updater_pid == -1 ) {
DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
current_printif = get_printer_fns( snum );
- print_queue_update_with_lock( sharename, current_printif, lpqcommand );
+ print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
return;
}
@@ -1415,23 +1471,26 @@ static void print_queue_update(int snum, BOOL force)
/* get the length */
- len = tdb_pack( buffer, len, "fdP",
+ len = tdb_pack( buffer, len, "fdPP",
sharename,
type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
buffer = SMB_XMALLOC_ARRAY( char, len );
/* now pack the buffer */
- newlen = tdb_pack( buffer, len, "fdP",
+ newlen = tdb_pack( buffer, len, "fdPP",
sharename,
type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
SMB_ASSERT( newlen == len );
DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
- "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
+ "type = %d, lpq command = [%s] lprm command = [%s]\n",
+ sharename, type, lpqcommand, lprmcommand ));
/* here we set a msg pending record for other smbd processes
to throttle the number of duplicate print_queue_update msgs
@@ -1457,7 +1516,7 @@ static void print_queue_update(int snum, BOOL force)
/* finally send the message */
become_root();
- message_send_pid(background_lpq_updater_pid,
+ message_send_pid(pid_to_procid(background_lpq_updater_pid),
MSG_PRINTER_UPDATE, buffer, len, False);
unbecome_root();
@@ -1806,8 +1865,6 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
int result = 0;
struct printif *current_printif = get_printer_fns( snum );
- pjob = print_job_find(sharename, jobid);
-
if (!pjob)
return False;
@@ -1819,7 +1876,9 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
return True;
/* Hrm - we need to be able to cope with deleting a job before it
- has reached the spooler. */
+ has reached the spooler. Just mark it as LPQ_DELETING and
+ let the print_queue_update() code rmeove the record */
+
if (pjob->sysjob == -1) {
DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
@@ -1830,24 +1889,31 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
pjob->status = LPQ_DELETING;
pjob_store(sharename, jobid, pjob);
- if (pjob->spooled && pjob->sysjob != -1)
- result = (*(current_printif->job_delete))(snum, pjob);
+ if (pjob->spooled && pjob->sysjob != -1)
+ {
+ result = (*(current_printif->job_delete))(
+ PRINTERNAME(snum),
+ lp_lprmcommand(snum),
+ pjob);
- /* Delete the tdb entry if the delete succeeded or the job hasn't
- been spooled. */
+ /* Delete the tdb entry if the delete succeeded or the job hasn't
+ been spooled. */
- if (result == 0) {
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- int njobs = 1;
+ if (result == 0) {
+ struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ int njobs = 1;
- if (!pdb)
- return False;
- pjob_delete(sharename, jobid);
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
- release_print_db(pdb);
+ if (!pdb)
+ return False;
+ pjob_delete(sharename, jobid);
+ /* Ensure we keep a rough count of the number of total jobs... */
+ tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
+ release_print_db(pdb);
+ }
}
+ remove_from_jobs_changed( sharename, jobid );
+
return (result == 0);
}
@@ -1877,7 +1943,8 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
{
const char* sharename = lp_const_servicename( snum );
- BOOL owner, deleted;
+ struct printjob *pjob;
+ BOOL owner;
char *fname;
*errcode = WERR_OK;
@@ -1929,11 +1996,11 @@ pause, or resume print job. User name: %s. Printer name: %s.",
print_queue_update(snum, True);
- deleted = !print_job_exists(sharename, jobid);
- if ( !deleted )
+ pjob = print_job_find(sharename, jobid);
+ if ( pjob && (pjob->status != LPQ_DELETING) )
*errcode = WERR_ACCESS_DENIED;
- return deleted;
+ return (pjob == NULL );
}
/****************************************************************************
diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c
index b9b4b3c6b0..adea10dfa6 100644
--- a/source3/printing/printing_db.c
+++ b/source3/printing/printing_db.c
@@ -188,7 +188,7 @@ TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name,
/* Entry is dead if process doesn't exist or refcount is zero. */
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
+ while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists_by_pid(pid))) {
/* Refcount == zero is a logic error and should never happen. */
if (IVAL(data.dptr, i + 4) == 0) {
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index e6d34e68cd..0cf8c8e15b 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -79,7 +79,8 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len)
/****************************************************************************
receive a request profile level message
****************************************************************************/
-void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len)
+void reqprofile_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
int level;
@@ -88,7 +89,8 @@ void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len)
#else
level = 0;
#endif
- DEBUG(1,("INFO: Received REQ_PROFILELEVEL message from PID %u\n",(unsigned int)src));
+ DEBUG(1,("INFO: Received REQ_PROFILELEVEL message from PID %u\n",
+ (unsigned int)procid_to_pid(&src)));
message_send_pid(src, MSG_PROFILELEVEL, &level, sizeof(int), True);
}
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index afb5c613c8..ab8fc14d90 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -92,18 +92,10 @@ static BOOL init_registry_data( void )
fstring keyname, subkeyname;
REGSUBKEY_CTR *subkeys;
REGVAL_CTR *values;
- uint32 *ctx;
int i;
const char *p, *p2;
UNISTR2 data;
- /* create a new top level talloc ctx */
-
- if ( !(ctx = TALLOC_P( NULL, uint32 )) ) {
- DEBUG(0,("init_registry_data: top level talloc() failure!\n"));
- return False;
- }
-
/* loop over all of the predefined paths and add each component */
for ( i=0; builtin_registry_paths[i] != NULL; i++ ) {
@@ -140,7 +132,7 @@ static BOOL init_registry_data( void )
we are about to update the record. We just want any
subkeys already present */
- if ( !(subkeys = TALLOC_ZERO_P( ctx, REGSUBKEY_CTR )) ) {
+ if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
DEBUG(0,("talloc() failure!\n"));
return False;
}
@@ -158,7 +150,7 @@ static BOOL init_registry_data( void )
/* loop over all of the predefined values and add each component */
for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
- if ( !(values = TALLOC_ZERO_P( ctx, REGVAL_CTR )) ) {
+ if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
DEBUG(0,("talloc() failure!\n"));
return False;
}
diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c
index 7f8f664ec6..b1a2a30755 100644
--- a/source3/registry/reg_dynamic.c
+++ b/source3/registry/reg_dynamic.c
@@ -37,7 +37,7 @@ static int netlogon_params( REGVAL_CTR *regvals )
{
uint32 dwValue;
- if ( !account_policy_get(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) )
+ if ( !pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) )
dwValue = 0;
regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD,
@@ -98,6 +98,99 @@ static int tcpip_params( REGVAL_CTR *regvals )
return regval_ctr_numvals( regvals );
}
+/***********************************************************************
+***********************************************************************/
+
+static int perflib_params( REGVAL_CTR *regvals )
+{
+ int base_index = -1;
+ int last_counter = -1;
+ int last_help = -1;
+ int version = 0x00010001;
+
+ base_index = reg_perfcount_get_base_index();
+ regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index));
+ last_counter = reg_perfcount_get_last_counter(base_index);
+ regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter));
+ last_help = reg_perfcount_get_last_help(last_counter);
+ regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help));
+ regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version));
+
+ return regval_ctr_numvals( regvals );
+}
+
+/***********************************************************************
+***********************************************************************/
+
+static int perflib_009_params( REGVAL_CTR *regvals )
+{
+ int base_index;
+ int buffer_size;
+ char *buffer = NULL;
+
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+ buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+
+ return regval_ctr_numvals( regvals );
+}
+
+/***********************************************************************
+***********************************************************************/
+
+static int hkpt_params( REGVAL_CTR *regvals )
+{
+ uint32 base_index;
+ uint32 buffer_size;
+ char *buffer = NULL;
+
+ /* This is ALMOST the same as perflib_009_params, but HKPT has
+ a "Counters" entry instead of a "Counter" key. <Grrrr> */
+
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, buffer_size);
+
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+
+ buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+
+ return regval_ctr_numvals( regvals );
+}
+
+/***********************************************************************
+***********************************************************************/
+
+static int current_version( REGVAL_CTR *values )
+{
+ const char *sysroot_string = "c:\\Windows";
+ fstring sysversion;
+ fstring value;
+ uint32 value_length;
+
+ value_length = push_ucs2( value, value, sysroot_string, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN );
+ regval_ctr_addvalue( values, "SystemRoot", REG_SZ, value, value_length );
+
+ fstr_sprintf( sysversion, "%d.%d", lp_major_announce_version(), lp_minor_announce_version() );
+ value_length = push_ucs2( value, value, sysversion, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN );
+ regval_ctr_addvalue( values, "CurrentVersion", REG_SZ, value, value_length );
+
+
+ return regval_ctr_numvals( values );
+}
+
/***********************************************************************
Structure holding the registry paths and pointers to the value
@@ -108,6 +201,10 @@ static struct reg_dyn_values dynamic_values[] = {
{ "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params },
{ "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options },
{ "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params },
+ { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params },
+ { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params },
+ { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION", &current_version },
+ { "HKPT", &hkpt_params },
{ NULL, NULL }
};
diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c
index b20eb046db..bed9e1d59a 100644
--- a/source3/registry/reg_eventlog.c
+++ b/source3/registry/reg_eventlog.c
@@ -1,7 +1,8 @@
/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
- * Copyright (C) Marcin Krzysztof Porwit 2005.
+ * Copyright (C) Marcin Krzysztof Porwit 2005,
+ * 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
@@ -20,288 +21,168 @@
#include "includes.h"
+
/**********************************************************************
- handle enumeration of values AT KEY_EVENTLOG
- *********************************************************************/
-
-static int eventlog_topkey_values( char *key, REGVAL_CTR *val )
+ Enumerate registry subkey names given a registry path.
+*********************************************************************/
+
+static int elog_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
{
- 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...
- */
+ const char **elogs = lp_eventlog_list();
+ char *path;
+ int i;
- if ( key )
- {
- key2 = SMB_STRDUP( key );
- keystr = key2;
- reg_split_path( keystr, &base, &new_path );
+ path = reg_remaining_path( key + strlen(KEY_EVENTLOG) );
- 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;
- }
- }
+ DEBUG(10,("elog_fetch_keys: entire key => [%s], subkey => [%s]\n",
+ key, path));
- SAFE_FREE( key2 );
- return num_values;
-}
+ if ( !path ) {
+
+ if ( !elogs || !*elogs )
+ return 0;
-/**********************************************************************
- 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 );
+ DEBUG(10,("elog_fetch_keys: Adding eventlog subkeys from smb.conf\n"));
+
+ for ( i=0; elogs[i]; i++ )
+ regsubkey_ctr_addkey( subkeys, elogs[i] );
+
+ return regsubkey_ctr_numkeys( subkeys );
+ }
- num_values = 0;
- }
-
- SAFE_FREE( key2 );
- return num_values;
-}
+ /* if we get <logname>/<logname> then we don't add anymore */
+ if ( strchr( path, '\\' ) ) {
+ DEBUG(10,("elog_fetch_keys: Not adding subkey to %s\n",path));
+ return 0;
+ }
-/**********************************************************************
- 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.
- **********************************************************************/
+ /* add in a subkey with the same name as the eventlog... */
-static char* trim_eventlog_reg_path( const char *path )
-{
- const 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
- *********************************************************************/
-static int eventlog_subkey_info( const 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;
-
- num_subkeys = 0;
- if ( !(evtlog_list = lp_eventlog_list()) ) {
- SAFE_FREE(path);
- return num_subkeys;
- }
+ DEBUG(10,("elog_fetch_keys: Looking to add eventlog subkey to %s\n",path));
-
- 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++;
+ /* look for a match */
+
+ if ( !elogs )
+ return -1;
+
+ for ( i=0; elogs[i]; i++ ) {
+ /* just verify that the keyname is a valid log name */
+ if ( strequal( path, elogs[i] ) )
+ return 0;
}
- if (0==num_subkeys)
- DEBUG(10,("eventlog_subkey_info: No match on SUBkey=>[%s]\n", path));
- }
-
- SAFE_FREE( path );
- return num_subkeys;
+ return -1;
}
/**********************************************************************
Enumerate registry values given a registry path.
Caller is responsible for freeing memory
- *********************************************************************/
+*********************************************************************/
-static int eventlog_value_info( const char *key, REGVAL_CTR *val )
+static int elog_fetch_values( const char *key, REGVAL_CTR *values )
{
- char *path;
- BOOL top_level = False;
- int num_values = 0;
+ char *path;
+ uint32 uiDisplayNameId, uiMaxSize, uiRetention;
+ char *base, *new_path;
+ UNISTR2 data;
- DEBUG(10,("eventlog_value_info: key=>[%s]\n", key));
+ DEBUG(10,("elog_fetch_values: key=>[%s]\n", key));
- path = trim_eventlog_reg_path( key );
+ path = reg_remaining_path( key + strlen(KEY_EVENTLOG) );
/* 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;
+ if ( !path )
+ return regdb_fetch_values( KEY_EVENTLOG, values );
+
+ /* deal with a log name */
+
+ reg_split_path( path, &base, &new_path );
+
+ /* MaxSize is limited to 0xFFFF0000 (UINT_MAX - USHRT_MAX) as per MSDN documentation */
+
+
+ if ( !new_path ) {
+
+ /* try to fetch from the registry */
+
+ regdb_fetch_values( key, values );
+
+ /* just verify one of the important keys. If this
+ fails, then assume the values have not been initialized */
+
+ if ( regval_ctr_getvalue( values, "Retention" ) )
+ return regval_ctr_numvals( values );
+
+ /* hard code some initial values */
+
+ uiDisplayNameId = 0x00000100;
+ uiMaxSize = 0x00080000;
+ uiRetention = 0x93A80;
+
+ regval_ctr_addvalue( values, "MaxSize", REG_DWORD, (char*)&uiMaxSize, sizeof(uint32));
+ regval_ctr_addvalue( values, "Retention", REG_DWORD, (char *)&uiRetention, sizeof(uint32));
+
+ init_unistr2( &data, base, UNI_STR_TERMINATE);
+ regval_ctr_addvalue( values, "PrimaryModule", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ init_unistr2( &data, base, UNI_STR_TERMINATE);
+ regval_ctr_addvalue( values, "Sources", REG_MULTI_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+
+ /* store them for later updates. Complain if this fails but continue on */
+
+ if ( !regdb_store_values( key, values ) ) {
+ DEBUG(0,("elog_fetch_values: Failed to store initial values for log [%s]\n",
+ base ));
+ }
+
+ return regval_ctr_numvals( values );
+ }
+
+#if 0
+ /* hmmm....what to do here? A subkey underneath the log name ? */
+
+ uiDisplayNameId = 0x07;
+ regval_ctr_addvalue( values, "CategoryCount", REG_DWORD, (char*)&uiDisplayNameId, sizeof(uint32) );
+
+ init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE);
+ regval_ctr_addvalue( values, "CategoryMessageFile", REG_EXPAND_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+#endif
+
+ return regval_ctr_numvals( values );
}
/**********************************************************************
- Stub function which always returns failure since we don't want
- people storing eventlog information directly via registry calls
- (for now at least)
- *********************************************************************/
-static BOOL eventlog_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
+*********************************************************************/
+
+static BOOL elog_store_keys( const char *key, REGSUBKEY_CTR *subkeys )
{
+ /* cannot create any subkeys here */
+
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)
- *********************************************************************/
-static BOOL eventlog_store_value( const char *key, REGVAL_CTR *val )
+ Allow storing of particular values related to eventlog operation.
+*********************************************************************/
+
+static BOOL elog_store_value( const char *key, REGVAL_CTR *values )
{
- return False;
+ /* the client had to have a valid handle to get here
+ so just hand off to the registry tdb */
+
+ return regdb_store_values( key, values );
}
-/*
- * Table of function pointers for accessing eventlog data
- */
+/********************************************************************
+ Table of function pointers for accessing eventlog data
+ *******************************************************************/
+
REGISTRY_OPS eventlog_ops = {
- eventlog_subkey_info,
- eventlog_value_info,
- eventlog_store_subkey,
- eventlog_store_value,
+ elog_fetch_keys,
+ elog_fetch_values,
+ elog_store_keys,
+ elog_store_value,
NULL
};
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index d6e0288461..f41c5885bc 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -38,15 +38,70 @@ REGISTRY_HOOK reg_hooks[] = {
{ KEY_PRINTING, &printing_ops },
{ KEY_PRINTING_2K, &printing_ops },
{ KEY_PRINTING_PORTS, &printing_ops },
-#if 0
{ KEY_EVENTLOG, &eventlog_ops },
-#endif
{ KEY_SHARES, &shares_reg_ops },
#endif
{ NULL, NULL }
};
+static struct generic_mapping reg_generic_map =
+ { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS registry_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
+ uint32 access_desired, uint32 *access_granted )
+{
+ NTSTATUS result;
+
+ if ( geteuid() == sec_initial_uid() ) {
+ DEBUG(5,("registry_access_check: using root's token\n"));
+ token = get_root_nt_token();
+ }
+
+ se_map_generic( &access_desired, &reg_generic_map );
+ se_access_check( sec_desc, token, access_desired, access_granted, &result );
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
+{
+ SEC_ACE ace[2];
+ SEC_ACCESS mask;
+ size_t i = 0;
+ SEC_DESC *sd;
+ SEC_ACL *acl;
+ size_t sd_size;
+
+ /* basic access for Everyone */
+
+ init_sec_access(&mask, REG_KEY_READ );
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* Full Access 'BUILTIN\Administrators' */
+
+ init_sec_access(&mask, REG_KEY_ALL );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+
+ /* create the security descriptor */
+
+ if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ return NULL;
+
+ if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
+ return NULL;
+
+ return sd;
+}
+
+
/***********************************************************************
Open the registry database and initialize the REGISTRY_HOOK cache
***********************************************************************/
@@ -55,11 +110,12 @@ BOOL init_registry( void )
{
int i;
+
if ( !init_registry_db() ) {
DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
return False;
}
-
+
/* build the cache tree of registry hooks */
reghook_cache_init();
@@ -72,6 +128,14 @@ BOOL init_registry( void )
if ( DEBUGLEVEL >= 20 )
reghook_dump_cache(20);
+ /* inform the external eventlog machinery of the change */
+
+ eventlog_refresh_external_parameters( get_root_nt_token() );
+
+ /* add any services keys */
+
+ svcctl_init_keys();
+
return True;
}
@@ -277,4 +341,70 @@ BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
return key->hook->ops->reg_access_check( key->name, requested, granted, token );
}
+/***********************************************************************
+***********************************************************************/
+
+WERROR regkey_open_internal( REGISTRY_KEY **regkey, const char *path,
+ NT_USER_TOKEN *token, uint32 access_desired )
+{
+ WERROR result = WERR_OK;
+ REGISTRY_KEY *keyinfo;
+ REGSUBKEY_CTR *subkeys = NULL;
+ uint32 access_granted;
+
+ DEBUG(7,("regkey_open_internal: name = [%s]\n", path));
+ if ( !(*regkey = TALLOC_ZERO_P(NULL, REGISTRY_KEY)) )
+ return WERR_NOMEM;
+
+ keyinfo = *regkey;
+
+ /* initialization */
+
+ keyinfo->type = REG_KEY_GENERIC;
+ keyinfo->name = talloc_strdup( keyinfo, path );
+
+
+ /* Tag this as a Performance Counter Key */
+
+ if( StrnCaseCmp(path, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
+ keyinfo->type = REG_KEY_HKPD;
+
+ /* Look up the table of registry I/O operations */
+
+ if ( !(keyinfo->hook = reghook_cache_find( keyinfo->name )) ) {
+ DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
+ keyinfo->name ));
+ result = WERR_BADFILE;
+ goto done;
+ }
+
+ /* check if the path really exists; failed is indicated by -1 */
+ /* if the subkey count failed, bail out */
+
+ if ( !(subkeys = TALLOC_ZERO_P( keyinfo, REGSUBKEY_CTR )) ) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ if ( fetch_reg_keys( keyinfo, subkeys ) == -1 ) {
+ result = WERR_BADFILE;
+ goto done;
+ }
+
+ TALLOC_FREE( subkeys );
+
+ if ( !regkey_access_check( keyinfo, access_desired, &access_granted, token ) ) {
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
+
+ keyinfo->access_granted = access_granted;
+
+done:
+ if ( !W_ERROR_IS_OK(result) ) {
+ TALLOC_FREE( *regkey );
+ }
+
+ return result;
+}
diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c
index 70410a6740..05567d561c 100644
--- a/source3/registry/reg_objects.c
+++ b/source3/registry/reg_objects.c
@@ -236,7 +236,7 @@ uint32 regval_type( REGISTRY_VALUE *val )
/***********************************************************************
Retreive a pointer to a specific value. Caller shoud dup the structure
- since this memory may go away with a regval_ctr_destroy()
+ since this memory will go away when the ctr is free()'d
**********************************************************************/
REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
@@ -385,3 +385,29 @@ REGISTRY_VALUE* regval_ctr_getvalue( REGVAL_CTR *ctr, const char *name )
return NULL;
}
+/***********************************************************************
+ return the data_p as a uint32
+ **********************************************************************/
+
+uint32 regval_dword( REGISTRY_VALUE *val )
+{
+ uint32 data;
+
+ data = IVAL( regval_data_p(val), 0 );
+
+ return data;
+}
+
+/***********************************************************************
+ return the data_p as a character string
+ **********************************************************************/
+
+char* regval_sz( REGISTRY_VALUE *val )
+{
+ static pstring data;
+
+ rpcstr_pull( data, regval_data_p(val), sizeof(data), regval_size(val), 0 );
+
+ return data;
+}
+
diff --git a/source3/registry/reg_perfcount.c b/source3/registry/reg_perfcount.c
new file mode 100644
index 0000000000..609f86da6c
--- /dev/null
+++ b/source3/registry/reg_perfcount.c
@@ -0,0 +1,1225 @@
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+#define PERFCOUNT_MAX_LEN 256
+
+uint32 reg_perfcount_get_base_index(void)
+{
+ pstring fname;
+ TDB_CONTEXT *names;
+ TDB_DATA kbuf, dbuf;
+ char key[] = "1";
+ uint32 retval = 0;
+ char buf[PERFCOUNT_MAX_LEN];
+ const char *counter_dir = lp_counters_dir();
+
+
+ if ( !*counter_dir )
+ return 0;
+
+ pstr_sprintf( fname, "%s/names.tdb", counter_dir );
+
+ names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if ( !names ) {
+ DEBUG(1, ("reg_perfcount_get_base_index: unable to open [%s].\n", fname));
+ return 0;
+ }
+ /* needs to read the value of key "1" from the counter_names.tdb file, as that is
+ where the total number of counters is stored. We're assuming no holes in the
+ enumeration.
+ The format for the counter_names.tdb file is:
+ key value
+ 1 num_counters
+ 2 perf_counter1
+ 3 perf_counter1_help
+ 4 perf_counter2
+ 5 perf_counter2_help
+ even_num perf_counter<even_num>
+ even_num+1 perf_counter<even_num>_help
+ and so on.
+ So last_counter becomes num_counters*2, and last_help will be last_counter+1 */
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key);
+ dbuf = tdb_fetch(names, kbuf);
+ if(dbuf.dptr == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_get_base_index: failed to find key \'1\' in [%s].\n", fname));
+ tdb_close(names);
+ return 0;
+ }
+ else
+ {
+ tdb_close(names);
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, dbuf.dptr, dbuf.dsize);
+ retval = (uint32)atoi(buf);
+ SAFE_FREE(dbuf.dptr);
+ return retval;
+ }
+ return 0;
+}
+
+uint32 reg_perfcount_get_last_counter(uint32 base_index)
+{
+ uint32 retval;
+
+ if(base_index == 0)
+ retval = 0;
+ else
+ retval = base_index * 2;
+
+ return retval;
+}
+
+uint32 reg_perfcount_get_last_help(uint32 last_counter)
+{
+ uint32 retval;
+
+ if(last_counter == 0)
+ retval = 0;
+ else
+ retval = last_counter + 1;
+
+ return retval;
+}
+
+static uint32 _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
+ int keyval,
+ char **retbuf,
+ uint32 buffer_size)
+{
+ TDB_DATA kbuf, dbuf;
+ char temp[256];
+ char *buf1 = *retbuf, *buf2 = NULL;
+ uint32 working_size = 0;
+ UNISTR2 name_index, name;
+
+ memset(temp, 0, sizeof(temp));
+ snprintf(temp, sizeof(temp), "%d", keyval);
+ kbuf.dptr = temp;
+ kbuf.dsize = strlen(temp);
+ dbuf = tdb_fetch(tdb, kbuf);
+ if(dbuf.dptr == NULL)
+ {
+ /* If a key isn't there, just bypass it -- this really shouldn't
+ happen unless someone's mucking around with the tdb */
+ DEBUG(3, ("_reg_perfcount_multi_sz_from_tdb: failed to find key [%s] in [%s].\n",
+ temp, tdb->name));
+ return buffer_size;
+ }
+ /* First encode the name_index */
+ working_size = (kbuf.dsize + 1)*sizeof(uint16);
+ buf2 = SMB_REALLOC(buf1, buffer_size + working_size);
+ if(!buf2)
+ {
+ SAFE_FREE(buf1);
+ buffer_size = 0;
+ return buffer_size;
+ }
+ buf1 = buf2;
+ init_unistr2(&name_index, kbuf.dptr, UNI_STR_TERMINATE);
+ memcpy(buf1+buffer_size, (char *)name_index.buffer, working_size);
+ buffer_size += working_size;
+ /* Now encode the actual name */
+ working_size = (dbuf.dsize + 1)*sizeof(uint16);
+ buf2 = SMB_REALLOC(buf1, buffer_size + working_size);
+ if(!buf2)
+ {
+ SAFE_FREE(buf1);
+ buffer_size = 0;
+ return buffer_size;
+ }
+ buf1 = buf2;
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, dbuf.dptr, dbuf.dsize);
+ SAFE_FREE(dbuf.dptr);
+ init_unistr2(&name, temp, UNI_STR_TERMINATE);
+ memcpy(buf1+buffer_size, (char *)name.buffer, working_size);
+ buffer_size += working_size;
+
+ *retbuf = buf1;
+
+ return buffer_size;
+}
+
+uint32 reg_perfcount_get_counter_help(uint32 base_index, char **retbuf)
+{
+ char *buf1 = NULL, *buf2 = NULL;
+ uint32 buffer_size = 0;
+ TDB_CONTEXT *names;
+ pstring fname;
+ int i;
+
+ if(base_index == 0)
+ return 0;
+
+ pstrcpy(fname, lp_counters_dir());
+ pstrcat(fname, "/names.tdb");
+
+ names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if(names == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_get_counter_help: unable to open [%s].\n", fname));
+ return 0;
+ }
+
+ for(i = 1; i <= base_index; i++)
+ {
+ buffer_size = _reg_perfcount_multi_sz_from_tdb(names, (i*2)+1, retbuf, buffer_size);
+ }
+ tdb_close(names);
+
+ /* Now terminate the MULTI_SZ with a double unicode NULL */
+ buf1 = *retbuf;
+ buf2 = SMB_REALLOC(buf1, buffer_size + 2);
+ if(!buf2)
+ {
+ SAFE_FREE(buf1);
+ buffer_size = 0;
+ }
+ else
+ {
+ buf1 = buf2;
+ buf1[buffer_size++] = '\0';
+ buf1[buffer_size++] = '\0';
+ }
+
+ *retbuf = buf1;
+
+ return buffer_size;
+}
+
+uint32 reg_perfcount_get_counter_names(uint32 base_index, char **retbuf)
+{
+ char *buf1 = NULL, *buf2 = NULL;
+ uint32 buffer_size = 0;
+ TDB_CONTEXT *names;
+ pstring fname;
+ int i;
+
+ if(base_index == 0)
+ return 0;
+
+ pstrcpy(fname, lp_counters_dir());
+ pstrcat(fname, "/names.tdb");
+
+ names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if(names == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_get_counter_names: unable to open [%s].\n", fname));
+ return 0;
+ }
+
+ buffer_size = _reg_perfcount_multi_sz_from_tdb(names, 1, retbuf, buffer_size);
+
+ for(i = 1; i <= base_index; i++)
+ {
+ buffer_size = _reg_perfcount_multi_sz_from_tdb(names, i*2, retbuf, buffer_size);
+ }
+ tdb_close(names);
+
+ /* Now terminate the MULTI_SZ with a double unicode NULL */
+ buf1 = *retbuf;
+ buf2 = SMB_REALLOC(buf1, buffer_size + 2);
+ if(!buf2)
+ {
+ SAFE_FREE(buf1);
+ buffer_size = 0;
+ }
+ else
+ {
+ buf1 = buf2;
+ buf1[buffer_size++] = '\0';
+ buf1[buffer_size++] = '\0';
+ }
+
+ *retbuf=buf1;
+
+ return buffer_size;
+}
+
+static void _reg_perfcount_make_key(TDB_DATA *key,
+ char *buf,
+ int buflen,
+ int key_part1,
+ const char *key_part2)
+{
+ memset(buf, 0, buflen);
+ if(key_part2 != NULL)
+ snprintf(buf, buflen,"%d%s", key_part1, key_part2);
+ else
+ snprintf(buf, buflen, "%d", key_part1);
+
+ key->dptr = buf;
+ key->dsize = strlen(buf);
+
+ return;
+}
+
+static BOOL _reg_perfcount_isparent(TDB_DATA data)
+{
+ if(data.dsize > 0)
+ {
+ if(data.dptr[0] == 'p')
+ return True;
+ else
+ return False;
+ }
+ return False;
+}
+
+static BOOL _reg_perfcount_ischild(TDB_DATA data)
+{
+ if(data.dsize > 0)
+ {
+ if(data.dptr[0] == 'c')
+ return True;
+ else
+ return False;
+ }
+ return False;
+}
+
+static uint32 _reg_perfcount_get_numinst(int objInd, TDB_CONTEXT *names)
+{
+ TDB_DATA key, data;
+ char buf[PERFCOUNT_MAX_LEN];
+
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, objInd, "inst");
+ data = tdb_fetch(names, key);
+
+ if(data.dptr == NULL)
+ return (uint32)PERF_NO_INSTANCES;
+
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ return (uint32)atoi(buf);
+}
+
+static BOOL _reg_perfcount_add_object(PERF_DATA_BLOCK *block,
+ prs_struct *ps,
+ int num,
+ TDB_DATA data,
+ TDB_CONTEXT *names)
+{
+ int i;
+ BOOL success = False;
+ PERF_OBJECT_TYPE *obj;
+
+ block->objects = (PERF_OBJECT_TYPE *)TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ block->objects,
+ PERF_OBJECT_TYPE,
+ block->NumObjectTypes+1);
+ if(block->objects == NULL)
+ return False;
+ obj = &(block->objects[block->NumObjectTypes]);
+ memset((void *)&(block->objects[block->NumObjectTypes]), 0, sizeof(PERF_OBJECT_TYPE));
+ block->objects[block->NumObjectTypes].ObjectNameTitleIndex = num;
+ block->objects[block->NumObjectTypes].ObjectNameTitlePointer = 0;
+ block->objects[block->NumObjectTypes].ObjectHelpTitleIndex = num+1;
+ block->objects[block->NumObjectTypes].ObjectHelpTitlePointer = 0;
+ block->objects[block->NumObjectTypes].NumCounters = 0;
+ block->objects[block->NumObjectTypes].DefaultCounter = 0;
+ block->objects[block->NumObjectTypes].NumInstances = _reg_perfcount_get_numinst(num, names);
+ block->objects[block->NumObjectTypes].counters = NULL;
+ block->objects[block->NumObjectTypes].instances = NULL;
+ block->objects[block->NumObjectTypes].counter_data.ByteLength = sizeof(uint32);
+ block->objects[block->NumObjectTypes].counter_data.data = NULL;
+ block->objects[block->NumObjectTypes].DetailLevel = PERF_DETAIL_NOVICE;
+ block->NumObjectTypes+=1;
+
+ for(i = 0; i < (int)obj->NumInstances; i++)
+ {
+ success = _reg_perfcount_add_instance(obj, ps, i, names);
+ }
+
+ return True;
+}
+
+BOOL _reg_perfcount_get_counter_data(TDB_DATA key, TDB_DATA *data)
+{
+ TDB_CONTEXT *counters;
+
+ pstring fname;
+
+ pstrcpy(fname, lp_counters_dir());
+ pstrcat(fname, "/data.tdb");
+
+ counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if(counters == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_get_counter_data: unable to open [%s].\n", fname));
+ return False;
+ }
+
+ *data = tdb_fetch(counters, key);
+
+ tdb_close(counters);
+
+ return True;
+}
+
+static uint32 _reg_perfcount_get_size_field(uint32 CounterType)
+{
+ uint32 retval;
+
+ retval = CounterType;
+
+ /* First mask out reserved lower 8 bits */
+ retval = retval & 0xFFFFFF00;
+ retval = retval << 22;
+ retval = retval >> 22;
+
+ return retval;
+}
+
+static uint32 _reg_perfcount_compute_scale(long long int data)
+{
+ int scale = 0;
+ if(data == 0)
+ return scale;
+ while(data > 100)
+ {
+ data /= 10;
+ scale--;
+ }
+ while(data < 10)
+ {
+ data *= 10;
+ scale++;
+ }
+
+ return (uint32)scale;
+}
+
+static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
+ prs_struct *ps,
+ int CounterIndex,
+ PERF_OBJECT_TYPE *obj,
+ TDB_CONTEXT *names)
+{
+ TDB_DATA key, data;
+ char buf[PERFCOUNT_MAX_LEN];
+ size_t dsize, padding;
+ long int data32, dbuf[2];
+ long long int data64;
+ uint32 counter_size;
+
+ obj->counters[obj->NumCounters].DefaultScale = 0;
+ dbuf[0] = dbuf[1] = 0;
+ padding = 0;
+
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "type");
+ data = tdb_fetch(names, key);
+ if(data.dptr == NULL)
+ {
+ DEBUG(3, ("_reg_perfcount_get_counter_info: No type data for counter [%d].\n", CounterIndex));
+ return False;
+ }
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ obj->counters[obj->NumCounters].CounterType = atoi(buf);
+ DEBUG(10, ("_reg_perfcount_get_counter_info: Got type [%d] for counter [%d].\n",
+ obj->counters[obj->NumCounters].CounterType, CounterIndex));
+ free(data.dptr);
+
+ /* Fetch the actual data */
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "");
+ _reg_perfcount_get_counter_data(key, &data);
+ if(data.dptr == NULL)
+ {
+ DEBUG(3, ("_reg_perfcount_get_counter_info: No counter data for counter [%d].\n", CounterIndex));
+ return False;
+ }
+
+ counter_size = _reg_perfcount_get_size_field(obj->counters[obj->NumCounters].CounterType);
+
+ if(counter_size == PERF_SIZE_DWORD)
+ {
+ dsize = sizeof(data32);
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ data32 = strtol(buf, NULL, 0);
+ if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
+ obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((long long int)data32);
+ else
+ obj->counters[obj->NumCounters].DefaultScale = 0;
+ dbuf[0] = data32;
+ padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
+ }
+ else if(counter_size == PERF_SIZE_LARGE)
+ {
+ dsize = sizeof(data64);
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ data64 = strtoll(buf, NULL, 0);
+ if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
+ obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale(data64);
+ else
+ obj->counters[obj->NumCounters].DefaultScale = 0;
+ memcpy((void *)dbuf, (const void *)&data64, dsize);
+ padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize;
+ }
+ else /* PERF_SIZE_VARIABLE_LEN */
+ {
+ dsize = data.dsize;
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ }
+ free(data.dptr);
+
+ obj->counter_data.ByteLength += dsize + padding;
+ obj->counter_data.data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ obj->counter_data.data,
+ uint8,
+ obj->counter_data.ByteLength - sizeof(uint32));
+ if(obj->counter_data.data == NULL)
+ return False;
+ if(dbuf[0] != 0 || dbuf[1] != 0)
+ {
+ memcpy((void *)(obj->counter_data.data +
+ (obj->counter_data.ByteLength - (sizeof(uint32) + dsize))),
+ (const void *)dbuf, dsize);
+ }
+ else
+ {
+ /* Handling PERF_SIZE_VARIABLE_LEN */
+ memcpy((void *)(obj->counter_data.data +
+ (obj->counter_data.ByteLength - (sizeof(uint32) + dsize))),
+ (const void *)buf, dsize);
+ }
+ obj->counters[obj->NumCounters].CounterOffset = obj->counter_data.ByteLength - dsize;
+ if(obj->counters[obj->NumCounters].CounterOffset % dsize != 0)
+ {
+ DEBUG(3,("Improperly aligned counter [%d]\n", obj->NumCounters));
+ }
+ obj->counters[obj->NumCounters].CounterSize = dsize;
+
+ return True;
+}
+
+PERF_OBJECT_TYPE *_reg_perfcount_find_obj(PERF_DATA_BLOCK *block, int objind)
+{
+ int i;
+
+ PERF_OBJECT_TYPE *obj = NULL;
+
+ for(i = 0; i < block->NumObjectTypes; i++)
+ {
+ if(block->objects[i].ObjectNameTitleIndex == objind)
+ {
+ obj = &(block->objects[i]);
+ }
+ }
+
+ return obj;
+}
+
+static BOOL _reg_perfcount_add_counter(PERF_DATA_BLOCK *block,
+ prs_struct *ps,
+ int num,
+ TDB_DATA data,
+ TDB_CONTEXT *names)
+{
+ char *begin, *end, *start, *stop;
+ int parent;
+ PERF_OBJECT_TYPE *obj;
+ BOOL success = False;
+ char buf[PERFCOUNT_MAX_LEN];
+
+ obj = NULL;
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ begin = index(buf, '[');
+ end = index(buf, ']');
+ if(begin == NULL || end == NULL)
+ return False;
+ start = begin+1;
+
+ while(start < end)
+ {
+ stop = index(start, ',');
+ if(stop == NULL)
+ stop = end;
+ *stop = '\0';
+ parent = atoi(start);
+
+ obj = _reg_perfcount_find_obj(block, parent);
+ if(obj == NULL)
+ {
+ /* At this point we require that the parent object exist.
+ This can probably be handled better at some later time */
+ DEBUG(3, ("_reg_perfcount_add_counter: Could not find parent object [%d] for counter [%d].\n",
+ parent, num));
+ return False;
+ }
+ obj->counters = (PERF_COUNTER_DEFINITION *)TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ obj->counters,
+ PERF_COUNTER_DEFINITION,
+ obj->NumCounters+1);
+ if(obj->counters == NULL)
+ return False;
+ memset((void *)&(obj->counters[obj->NumCounters]), 0, sizeof(PERF_COUNTER_DEFINITION));
+ obj->counters[obj->NumCounters].CounterNameTitleIndex=num;
+ obj->counters[obj->NumCounters].CounterHelpTitleIndex=num+1;
+ obj->counters[obj->NumCounters].DetailLevel = PERF_DETAIL_NOVICE;
+ obj->counters[obj->NumCounters].ByteLength = sizeof(PERF_COUNTER_DEFINITION);
+ success = _reg_perfcount_get_counter_info(block, ps, num, obj, names);
+ obj->NumCounters += 1;
+ start = stop + 1;
+ }
+
+ /* Handle case of Objects/Counters without any counter data, which would suggest
+ that the required instances are not there yet, so change NumInstances from
+ PERF_NO_INSTANCES to 0 */
+
+ return True;
+}
+
+BOOL _reg_perfcount_get_instance_info(PERF_INSTANCE_DEFINITION *inst,
+ prs_struct *ps,
+ int instId,
+ PERF_OBJECT_TYPE *obj,
+ TDB_CONTEXT *names)
+{
+ TDB_DATA key, data;
+ char buf[PERFCOUNT_MAX_LEN], temp[PERFCOUNT_MAX_LEN];
+ wpstring name;
+ int pad;
+
+ /* First grab the instance data from the data file */
+ memset(temp, 0, PERFCOUNT_MAX_LEN);
+ snprintf(temp, PERFCOUNT_MAX_LEN, "i%d", instId);
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
+ _reg_perfcount_get_counter_data(key, &data);
+ if(data.dptr == NULL)
+ {
+ DEBUG(3, ("_reg_perfcount_get_instance_info: No instance data for instance [%s].\n",
+ buf));
+ return False;
+ }
+ inst->counter_data.ByteLength = data.dsize + sizeof(inst->counter_data.ByteLength);
+ inst->counter_data.data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ inst->counter_data.data,
+ uint8,
+ data.dsize);
+ if(inst->counter_data.data == NULL)
+ return False;
+ memset(inst->counter_data.data, 0, data.dsize);
+ memcpy(inst->counter_data.data, data.dptr, data.dsize);
+ free(data.dptr);
+
+ /* Fetch instance name */
+ memset(temp, 0, PERFCOUNT_MAX_LEN);
+ snprintf(temp, PERFCOUNT_MAX_LEN, "i%dname", instId);
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp);
+ data = tdb_fetch(names, key);
+ if(data.dptr == NULL)
+ {
+ /* Not actually an error, but possibly unintended? -- just logging FYI */
+ DEBUG(3, ("_reg_perfcount_get_instance_info: No instance name for instance [%s].\n",
+ buf));
+ inst->NameLength = 0;
+ }
+ else
+ {
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ rpcstr_push((void *)name, buf, sizeof(name), STR_TERMINATE);
+ inst->NameLength = (strlen_w(name) * 2) + 2;
+ inst->data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ inst->data,
+ uint8,
+ inst->NameLength);
+ memcpy(inst->data, name, inst->NameLength);
+ free(data.dptr);
+ }
+
+ inst->ParentObjectTitleIndex = 0;
+ inst->ParentObjectTitlePointer = 0;
+ inst->UniqueID = PERF_NO_UNIQUE_ID;
+ inst->NameOffset = 6 * sizeof(uint32);
+
+ inst->ByteLength = inst->NameOffset + inst->NameLength;
+ /* Need to be aligned on a 64-bit boundary here for counter_data */
+ if((pad = (inst->ByteLength % 8)))
+ {
+ pad = 8 - pad;
+ inst->data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ inst->data,
+ uint8,
+ inst->NameLength + pad);
+ memset(inst->data + inst->NameLength, 0, pad);
+ inst->ByteLength += pad;
+ }
+
+ return True;
+}
+
+BOOL _reg_perfcount_add_instance(PERF_OBJECT_TYPE *obj,
+ prs_struct *ps,
+ int instInd,
+ TDB_CONTEXT *names)
+{
+ BOOL success;
+ PERF_INSTANCE_DEFINITION *inst;
+
+ success = False;
+
+ if(obj->instances == NULL)
+ {
+ obj->instances = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ obj->instances,
+ PERF_INSTANCE_DEFINITION,
+ obj->NumInstances);
+ }
+ if(obj->instances == NULL)
+ return False;
+
+ memset(&(obj->instances[instInd]), 0, sizeof(PERF_INSTANCE_DEFINITION));
+ inst = &(obj->instances[instInd]);
+ success = _reg_perfcount_get_instance_info(inst, ps, instInd, obj, names);
+
+ return True;
+}
+
+static int _reg_perfcount_assemble_global(PERF_DATA_BLOCK *block,
+ prs_struct *ps,
+ int base_index,
+ TDB_CONTEXT *names)
+{
+ BOOL success;
+ int i, j, retval = 0;
+ char keybuf[PERFCOUNT_MAX_LEN];
+ TDB_DATA key, data;
+
+ for(i = 1; i <= base_index; i++)
+ {
+ j = i*2;
+ _reg_perfcount_make_key(&key, keybuf, PERFCOUNT_MAX_LEN, j, "rel");
+ data = tdb_fetch(names, key);
+ if(data.dptr != NULL)
+ {
+ if(_reg_perfcount_isparent(data))
+ success = _reg_perfcount_add_object(block, ps, j, data, names);
+ else if(_reg_perfcount_ischild(data))
+ success = _reg_perfcount_add_counter(block, ps, j, data, names);
+ else
+ {
+ DEBUG(3, ("Bogus relationship [%s] for counter [%d].\n", data.dptr, j));
+ success = False;
+ }
+ if(success == False)
+ {
+ DEBUG(3, ("_reg_perfcount_assemble_global: Failed to add new relationship for counter [%d].\n", j));
+ retval = -1;
+ }
+ free(data.dptr);
+ }
+ else
+ DEBUG(3, ("NULL relationship for counter [%d] using key [%s].\n", j, keybuf));
+ }
+ return retval;
+}
+
+static BOOL _reg_perfcount_get_64(unsigned long long *retval,
+ TDB_CONTEXT *tdb,
+ int key_part1,
+ const char *key_part2)
+{
+ TDB_DATA key, data;
+ char buf[PERFCOUNT_MAX_LEN];
+
+ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, key_part1, key_part2);
+
+ data = tdb_fetch(tdb, key);
+ if(data.dptr == NULL)
+ {
+ DEBUG(3,("_reg_perfcount_get_64: No data found for key [%s].\n", key.dptr));
+ return False;
+ }
+
+ memset(buf, 0, PERFCOUNT_MAX_LEN);
+ memcpy(buf, data.dptr, data.dsize);
+ free(data.dptr);
+
+ *retval = strtoll(buf, NULL, 0);
+
+ return True;
+}
+
+static BOOL _reg_perfcount_init_data_block_perf(PERF_DATA_BLOCK *block,
+ TDB_CONTEXT *names)
+{
+ unsigned long long PerfFreq, PerfTime, PerfTime100nSec;
+ TDB_CONTEXT *counters;
+ BOOL status;
+ pstring fname;
+
+ status = False;
+
+ pstrcpy(fname, lp_counters_dir());
+ pstrcat(fname, "/data.tdb");
+
+ counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if(counters == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_init_data_block_perf: unable to open [%s].\n", fname));
+ return False;
+ }
+
+ status = _reg_perfcount_get_64(&PerfFreq, names, 0, "PerfFreq");
+ if(status == False)
+ {
+ tdb_close(counters);
+ return status;
+ }
+ memcpy((void *)&(block->PerfFreq), (const void *)&PerfFreq, sizeof(PerfFreq));
+
+ status = _reg_perfcount_get_64(&PerfTime, counters, 0, "PerfTime");
+ if(status == False)
+ {
+ tdb_close(counters);
+ return status;
+ }
+ memcpy((void *)&(block->PerfTime), (const void *)&PerfTime, sizeof(PerfTime));
+
+ status = _reg_perfcount_get_64(&PerfTime100nSec, counters, 0, "PerfTime100nSec");
+ if(status == False)
+ {
+ tdb_close(counters);
+ return status;
+ }
+ memcpy((void *)&(block->PerfTime100nSec), (const void *)&PerfTime100nSec, sizeof(PerfTime100nSec));
+
+ tdb_close(counters);
+ return True;
+}
+
+static void _reg_perfcount_init_data_block(PERF_DATA_BLOCK *block, prs_struct *ps, TDB_CONTEXT *names)
+{
+ wpstring temp;
+ time_t tm;
+
+ memset(temp, 0, sizeof(temp));
+ rpcstr_push((void *)temp, "PERF", sizeof(temp), STR_TERMINATE);
+ memcpy(block->Signature, temp, strlen_w(temp) *2);
+
+ if(ps->bigendian_data == RPC_BIG_ENDIAN)
+ block->LittleEndian = 0;
+ else
+ block->LittleEndian = 1;
+ block->Version = 1;
+ block->Revision = 1;
+ block->TotalByteLength = 0;
+ block->NumObjectTypes = 0;
+ block->DefaultObject = -1;
+ block->objects = NULL;
+ tm = time(NULL);
+ make_systemtime(&(block->SystemTime), gmtime(&tm));
+ _reg_perfcount_init_data_block_perf(block, names);
+ memset(temp, 0, sizeof(temp));
+ rpcstr_push((void *)temp, global_myname(), sizeof(temp), STR_TERMINATE);
+ block->SystemNameLength = (strlen_w(temp) * 2) + 2;
+ block->data = TALLOC_ZERO_ARRAY(ps->mem_ctx, uint8, block->SystemNameLength + (8 - (block->SystemNameLength % 8)));
+ memcpy(block->data, temp, block->SystemNameLength);
+ block->SystemNameOffset = sizeof(PERF_DATA_BLOCK) - sizeof(block->objects) - sizeof(block->data);
+ block->HeaderLength = block->SystemNameOffset + block->SystemNameLength;
+ /* Make sure to adjust for 64-bit alignment for when we finish writing the system name,
+ so that the PERF_OBJECT_TYPE struct comes out 64-bit aligned */
+ block->HeaderLength += 8 - (block->HeaderLength % 8);
+
+ return;
+}
+
+static uint32 _reg_perfcount_perf_data_block_fixup(PERF_DATA_BLOCK *block, prs_struct *ps)
+{
+ int obj, cnt, inst, pad, i;
+ PERF_OBJECT_TYPE *object;
+ PERF_INSTANCE_DEFINITION *instance;
+ PERF_COUNTER_DEFINITION *counter;
+ PERF_COUNTER_BLOCK *counter_data;
+ char *temp = NULL, *src_addr, *dst_addr;
+
+ block->TotalByteLength = 0;
+ object = block->objects;
+ for(obj = 0; obj < block->NumObjectTypes; obj++)
+ {
+ object[obj].TotalByteLength = 0;
+ object[obj].DefinitionLength = 0;
+ instance = object[obj].instances;
+ counter = object[obj].counters;
+ for(cnt = 0; cnt < object[obj].NumCounters; cnt++)
+ {
+ object[obj].TotalByteLength += counter[cnt].ByteLength;
+ object[obj].DefinitionLength += counter[cnt].ByteLength;
+ }
+ if(object[obj].NumInstances != PERF_NO_INSTANCES)
+ {
+ for(inst = 0; inst < object[obj].NumInstances; inst++)
+ {
+ instance = &(object[obj].instances[inst]);
+ object[obj].TotalByteLength += instance->ByteLength;
+ counter_data = &(instance->counter_data);
+ counter = &(object[obj].counters[object[obj].NumCounters - 1]);
+ counter_data->ByteLength = counter->CounterOffset + counter->CounterSize + sizeof(counter_data->ByteLength);
+ temp = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ temp,
+ uint8,
+ counter_data->ByteLength- sizeof(counter_data->ByteLength));
+ memset(temp, 0, counter_data->ByteLength - sizeof(counter_data->ByteLength));
+ src_addr = counter_data->data;
+ for(i = 0; i < object[obj].NumCounters; i++)
+ {
+ counter = &(object[obj].counters[i]);
+ dst_addr = temp + counter->CounterOffset - sizeof(counter_data->ByteLength);
+ memcpy(dst_addr, src_addr, counter->CounterSize);
+ src_addr += counter->CounterSize;
+ }
+ /* Make sure to be 64-bit aligned */
+ if((pad = (counter_data->ByteLength % 8)))
+ {
+ pad = 8 - pad;
+ }
+ counter_data->data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ counter_data->data,
+ uint8,
+ counter_data->ByteLength - sizeof(counter_data->ByteLength) + pad);
+ memset(counter_data->data, 0, counter_data->ByteLength - sizeof(counter_data->ByteLength) + pad);
+ memcpy(counter_data->data, temp, counter_data->ByteLength - sizeof(counter_data->ByteLength));
+ counter_data->ByteLength += pad;
+ object[obj].TotalByteLength += counter_data->ByteLength;
+ }
+ }
+ else
+ {
+ /* Need to be 64-bit aligned at the end of the counter_data block, so pad counter_data to a 64-bit boundary,
+ so that the next PERF_OBJECT_TYPE can start on a 64-bit alignment */
+ if((pad = (object[obj].counter_data.ByteLength % 8)))
+ {
+ pad = 8 - pad;
+ object[obj].counter_data.data = TALLOC_REALLOC_ARRAY(ps->mem_ctx,
+ object[obj].counter_data.data,
+ uint8,
+ object[obj].counter_data.ByteLength + pad);
+ memset((void *)(object[obj].counter_data.data + object[obj].counter_data.ByteLength), 0, pad);
+ object[obj].counter_data.ByteLength += pad;
+ }
+ object[obj].TotalByteLength += object[obj].counter_data.ByteLength;
+ }
+ object[obj].HeaderLength = sizeof(*object) - (sizeof(counter) + sizeof(instance) + sizeof(PERF_COUNTER_BLOCK));
+ object[obj].TotalByteLength += object[obj].HeaderLength;
+ object[obj].DefinitionLength += object[obj].HeaderLength;
+
+ block->TotalByteLength += object[obj].TotalByteLength;
+ }
+
+ return block->TotalByteLength;
+}
+
+uint32 reg_perfcount_get_perf_data_block(uint32 base_index,
+ prs_struct *ps,
+ PERF_DATA_BLOCK *block,
+ char *object_ids)
+{
+ uint32 buffer_size = 0, last_counter;
+ pstring fname;
+ TDB_CONTEXT *names;
+ int retval;
+
+ pstrcpy(fname, lp_counters_dir());
+ pstrcat(fname, "/names.tdb");
+
+ names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
+
+ if(names == NULL)
+ {
+ DEBUG(1, ("reg_perfcount_get_perf_data_block: unable to open [%s].\n", fname));
+ return 0;
+ }
+
+ _reg_perfcount_init_data_block(block, ps, names);
+
+ last_counter = reg_perfcount_get_last_counter(base_index);
+
+ if(object_ids == NULL)
+ {
+ /* we're getting a request for "Global" here */
+ retval = _reg_perfcount_assemble_global(block, ps, base_index, names);
+ }
+ else
+ {
+ /* we're getting a request for a specific set of PERF_OBJECT_TYPES */
+ retval = _reg_perfcount_assemble_global(block, ps, base_index, names);
+ }
+ buffer_size = _reg_perfcount_perf_data_block_fixup(block, ps);
+
+ tdb_close(names);
+
+ return buffer_size + block->HeaderLength;
+}
+
+static BOOL _reg_perfcount_marshall_perf_data_block(prs_struct *ps, PERF_DATA_BLOCK block, int depth)
+{
+ int i;
+ prs_debug(ps, depth, "", "_reg_perfcount_marshall_perf_data_block");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+ for(i = 0; i < 4; i++)
+ {
+ if(!prs_uint16("Signature", ps, depth, &block.Signature[i]))
+ return False;
+ }
+ if(!prs_uint32("Little Endian", ps, depth, &block.LittleEndian))
+ return False;
+ if(!prs_uint32("Version", ps, depth, &block.Version))
+ return False;
+ if(!prs_uint32("Revision", ps, depth, &block.Revision))
+ return False;
+ if(!prs_uint32("TotalByteLength", ps, depth, &block.TotalByteLength))
+ return False;
+ if(!prs_uint32("HeaderLength", ps, depth, &block.HeaderLength))
+ return False;
+ if(!prs_uint32("NumObjectTypes", ps, depth, &block.NumObjectTypes))
+ return False;
+ if(!prs_uint32("DefaultObject", ps, depth, &block.DefaultObject))
+ return False;
+ if(!spoolss_io_system_time("SystemTime", ps, depth, &block.SystemTime))
+ return False;
+ if(!prs_uint32("Padding", ps, depth, &block.Padding))
+ return False;
+ if(!prs_align_uint64(ps))
+ return False;
+ if(!prs_uint64("PerfTime", ps, depth, &block.PerfTime))
+ return False;
+ if(!prs_uint64("PerfFreq", ps, depth, &block.PerfFreq))
+ return False;
+ if(!prs_uint64("PerfTime100nSec", ps, depth, &block.PerfTime100nSec))
+ return False;
+ if(!prs_uint32("SystemNameLength", ps, depth, &block.SystemNameLength))
+ return False;
+ if(!prs_uint32("SystemNameOffset", ps, depth, &block.SystemNameOffset))
+ return False;
+ /* hack to make sure we're 64-bit aligned at the end of this whole mess */
+ if(!prs_uint8s(False, "SystemName", ps, depth, block.data,
+ block.HeaderLength - block.SystemNameOffset))
+ return False;
+
+ return True;
+}
+
+static BOOL _reg_perfcount_marshall_perf_counters(prs_struct *ps,
+ PERF_OBJECT_TYPE object,
+ int depth)
+{
+ int cnt;
+ PERF_COUNTER_DEFINITION counter;
+
+ prs_debug(ps, depth, "", "_reg_perfcount_marshall_perf_counters");
+ depth++;
+
+ for(cnt = 0; cnt < object.NumCounters; cnt++)
+ {
+ counter = object.counters[cnt];
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ByteLength", ps, depth, &counter.ByteLength))
+ return False;
+ if(!prs_uint32("CounterNameTitleIndex", ps, depth, &counter.CounterNameTitleIndex))
+ return False;
+ if(!prs_uint32("CounterNameTitlePointer", ps, depth, &counter.CounterNameTitlePointer))
+ return False;
+ if(!prs_uint32("CounterHelpTitleIndex", ps, depth, &counter.CounterHelpTitleIndex))
+ return False;
+ if(!prs_uint32("CounterHelpTitlePointer", ps, depth, &counter.CounterHelpTitlePointer))
+ return False;
+ if(!prs_uint32("DefaultScale", ps, depth, &counter.DefaultScale))
+ return False;
+ if(!prs_uint32("DetailLevel", ps, depth, &counter.DetailLevel))
+ return False;
+ if(!prs_uint32("CounterType", ps, depth, &counter.CounterType))
+ return False;
+ if(!prs_uint32("CounterSize", ps, depth, &counter.CounterSize))
+ return False;
+ if(!prs_uint32("CounterOffset", ps, depth, &counter.CounterOffset))
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL _reg_perfcount_marshall_perf_counter_data(prs_struct *ps,
+ PERF_COUNTER_BLOCK counter_data,
+ int depth)
+{
+ prs_debug(ps, depth, "", "_reg_perfcount_marshall_perf_counter_data");
+ depth++;
+
+ if(!prs_align_uint64(ps))
+ return False;
+
+ if(!prs_uint32("ByteLength", ps, depth, &counter_data.ByteLength))
+ return False;
+ if(!prs_uint8s(False, "CounterData", ps, depth, counter_data.data, counter_data.ByteLength - sizeof(uint32)))
+ return False;
+ if(!prs_align_uint64(ps))
+ return False;
+
+ return True;
+}
+
+static BOOL _reg_perfcount_marshall_perf_instances(prs_struct *ps,
+ PERF_OBJECT_TYPE object,
+ int depth)
+{
+ PERF_INSTANCE_DEFINITION instance;
+ int inst;
+
+ prs_debug(ps, depth, "", "_reg_perfcount_marshall_perf_instances");
+ depth++;
+
+ for(inst = 0; inst < object.NumInstances; inst++)
+ {
+ instance = object.instances[inst];
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ByteLength", ps, depth, &instance.ByteLength))
+ return False;
+ if(!prs_uint32("ParentObjectTitleIndex", ps, depth, &instance.ParentObjectTitleIndex))
+ return False;
+ if(!prs_uint32("ParentObjectTitlePointer", ps, depth, &instance.ParentObjectTitlePointer))
+ return False;
+ if(!prs_uint32("UniqueID", ps, depth, &instance.UniqueID))
+ return False;
+ if(!prs_uint32("NameOffset", ps, depth, &instance.NameOffset))
+ return False;
+ if(!prs_uint32("NameLength", ps, depth, &instance.NameLength))
+ return False;
+ if(!prs_uint8s(False, "InstanceName", ps, depth, instance.data,
+ instance.ByteLength - instance.NameOffset))
+ return False;
+ if(_reg_perfcount_marshall_perf_counter_data(ps, instance.counter_data, depth) == False)
+ return False;
+ }
+
+ return True;
+}
+
+static BOOL _reg_perfcount_marshall_perf_objects(prs_struct *ps, PERF_DATA_BLOCK block, int depth)
+{
+ int obj;
+
+ PERF_OBJECT_TYPE object;
+
+ prs_debug(ps, depth, "", "_reg_perfcount_marshall_perf_objects");
+ depth++;
+
+ for(obj = 0; obj < block.NumObjectTypes; obj++)
+ {
+ object = block.objects[obj];
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("TotalByteLength", ps, depth, &object.TotalByteLength))
+ return False;
+ if(!prs_uint32("DefinitionLength", ps, depth, &object.DefinitionLength))
+ return False;
+ if(!prs_uint32("HeaderLength", ps, depth, &object.HeaderLength))
+ return False;
+ if(!prs_uint32("ObjectNameTitleIndex", ps, depth, &object.ObjectNameTitleIndex))
+ return False;
+ if(!prs_uint32("ObjectNameTitlePointer", ps, depth, &object.ObjectNameTitlePointer))
+ return False;
+ if(!prs_uint32("ObjectHelpTitleIndex", ps, depth, &object.ObjectHelpTitleIndex))
+ return False;
+ if(!prs_uint32("ObjectHelpTitlePointer", ps, depth, &object.ObjectHelpTitlePointer))
+ return False;
+ if(!prs_uint32("DetailLevel", ps, depth, &object.DetailLevel))
+ return False;
+ if(!prs_uint32("NumCounters", ps, depth, &object.NumCounters))
+ return False;
+ if(!prs_uint32("DefaultCounter", ps, depth, &object.DefaultCounter))
+ return False;
+ if(!prs_uint32("NumInstances", ps, depth, &object.NumInstances))
+ return False;
+ if(!prs_uint32("CodePage", ps, depth, &object.CodePage))
+ return False;
+ if(!prs_align_uint64(ps))
+ return False;
+ if(!prs_uint64("PerfTime", ps, depth, &object.PerfTime))
+ return False;
+ if(!prs_uint64("PerfFreq", ps, depth, &object.PerfFreq))
+ return False;
+
+ /* Now do the counters */
+ /* If no instances, encode counter_data */
+ /* If instances, encode instace plus counter data for each instance */
+ if(_reg_perfcount_marshall_perf_counters(ps, object, depth) == False)
+ return False;
+ if(object.NumInstances == PERF_NO_INSTANCES)
+ {
+ if(_reg_perfcount_marshall_perf_counter_data(ps, object.counter_data, depth) == False)
+ return False;
+ }
+ else
+ {
+ if(_reg_perfcount_marshall_perf_instances(ps, object, depth) == False)
+ return False;
+ }
+ }
+
+ return True;
+}
+
+static BOOL _reg_perfcount_marshall_hkpd(prs_struct *ps, PERF_DATA_BLOCK block)
+{
+ int depth = 0;
+ if(_reg_perfcount_marshall_perf_data_block(ps, block, depth) == True)
+ {
+ if(_reg_perfcount_marshall_perf_objects(ps, block, depth) == True)
+ return True;
+ }
+ return False;
+}
+WERROR reg_perfcount_get_hkpd(prs_struct *ps, uint32 max_buf_size, uint32 *outbuf_len, char *object_ids)
+{
+ /*
+ * For a detailed description of the layout of this structure,
+ * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/performance_data_format.asp
+ */
+ PERF_DATA_BLOCK block;
+ uint32 buffer_size, base_index;
+
+ buffer_size = 0;
+ base_index = reg_perfcount_get_base_index();
+ ZERO_STRUCT(block);
+
+ buffer_size = reg_perfcount_get_perf_data_block(base_index, ps, &block, object_ids);
+
+ if(buffer_size < max_buf_size)
+ {
+ *outbuf_len = buffer_size;
+ if(_reg_perfcount_marshall_hkpd(ps, block) == True)
+ return WERR_OK;
+ else
+ return WERR_NOMEM;
+ }
+ else
+ {
+ *outbuf_len = max_buf_size;
+ _reg_perfcount_marshall_perf_data_block(ps, block, 0);
+ return WERR_INSUFFICIENT_BUFFER;
+ }
+}
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index d0f7daa926..b07c8e9644 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -55,34 +55,6 @@ struct reg_dyn_tree {
*********************************************************************
*********************************************************************/
-/**********************************************************************
- move to next non-delimter character
-*********************************************************************/
-
-static char* remaining_path( const char *key )
-{
- static pstring new_path;
- char *p;
-
- if ( !key || !*key )
- return NULL;
-
- pstrcpy( new_path, key );
- /* normalize_reg_path( new_path ); */
-
- if ( !(p = strchr( new_path, '\\' )) )
- {
- if ( !(p = strchr( new_path, '/' )) )
- p = new_path;
- else
- p++;
- }
- else
- p++;
-
- return p;
-}
-
/***********************************************************************
simple function to prune a pathname down to the basename of a file
**********************************************************************/
@@ -107,7 +79,7 @@ static char* dos_basename ( char *path )
static int key_forms_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
{
- char *p = remaining_path( key + strlen(KEY_FORMS) );
+ char *p = reg_remaining_path( key + strlen(KEY_FORMS) );
/* no keys below Forms */
@@ -204,9 +176,9 @@ static char* strip_printers_prefix( const char *key )
/* normalizing the path does not change length, just key delimiters and case */
if ( strncmp( path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS) ) == 0 )
- subkeypath = remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
+ subkeypath = reg_remaining_path( key + strlen(KEY_WINNT_PRINTERS) );
else
- subkeypath = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
+ subkeypath = reg_remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
return subkeypath;
}
@@ -445,7 +417,7 @@ static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *
/* use a prs_struct for converting the devmode and security
descriptor to REG_BINARY */
- prs_init( &prs, MAX_PDU_FRAG_LEN, values, MARSHALL);
+ prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL);
/* stream the device mode */
@@ -754,7 +726,7 @@ static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" ));
- keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) );
+ keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) );
/* list all possible architectures */
@@ -1044,7 +1016,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values )
/* no values in the Environments key */
- if ( !(keystr = remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
+ if ( !(keystr = reg_remaining_path( key + strlen(KEY_ENVIRONMENTS) )) )
return 0;
pstrcpy( subkey, keystr);
diff --git a/source3/registry/reg_util.c b/source3/registry/reg_util.c
index 165292cf2f..9f19db2646 100644
--- a/source3/registry/reg_util.c
+++ b/source3/registry/reg_util.c
@@ -97,3 +97,31 @@ void normalize_reg_path( pstring keyname )
strupper_m( keyname );
}
+/**********************************************************************
+ move to next non-delimter character
+*********************************************************************/
+
+char* reg_remaining_path( const char *key )
+{
+ static pstring new_path;
+ char *p;
+
+ if ( !key || !*key )
+ return NULL;
+
+ pstrcpy( new_path, key );
+ /* normalize_reg_path( new_path ); */
+
+ if ( !(p = strchr( new_path, '\\' )) )
+ {
+ if ( !(p = strchr( new_path, '/' )) )
+ p = new_path;
+ else
+ p++;
+ }
+ else
+ p++;
+
+ return p;
+}
+
diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c
index e7b8cdc8bb..954f4ae7bd 100644
--- a/source3/registry/regfio.c
+++ b/source3/registry/regfio.c
@@ -561,7 +561,7 @@ static REGF_HBIN* lookup_hbin_block( REGF_FILE *file, uint32 offset )
/* start with the open list */
for ( hbin=file->block_list; hbin; hbin=hbin->next ) {
- DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%x]\n", hbin->file_off, (uint32)hbin ));
+ DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%lx]\n", hbin->file_off, (unsigned long)hbin ));
if ( hbin_contains_offset( hbin, offset ) )
return hbin;
}
diff --git a/source3/rpc_client/cli_dfs.c b/source3/rpc_client/cli_dfs.c
index 7933519118..78df220ac2 100644
--- a/source3/rpc_client/cli_dfs.c
+++ b/source3/rpc_client/cli_dfs.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
RPC pipe client
Copyright (C) Tim Potter 2000-2001,
+ Copyright (C) Jeremy Allison 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,7 +23,7 @@
/* Query DFS support */
-NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_dfs_exist(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
BOOL *dfs_exists)
{
prs_struct qbuf, rbuf;
@@ -33,25 +34,16 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_dfs_q_dfs_exist(&q);
- if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETDFS, DFS_EXIST, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_NETDFS, DFS_EXIST,
+ q, r,
+ qbuf, rbuf,
+ dfs_io_q_dfs_exist,
+ dfs_io_r_dfs_exist,
+ NT_STATUS_UNSUCCESSFUL);
/* Return result */
@@ -59,14 +51,10 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = NT_STATUS_OK;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_dfs_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *entrypath, const char *servername,
const char *sharename, const char *comment, uint32 flags)
{
@@ -78,39 +66,26 @@ NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment,
flags);
- if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETDFS, DFS_ADD, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_NETDFS, DFS_ADD,
+ q, r,
+ qbuf, rbuf,
+ dfs_io_q_dfs_add,
+ dfs_io_r_dfs_add,
+ NT_STATUS_UNSUCCESSFUL);
/* Return result */
result = werror_to_ntstatus(r.status);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_dfs_remove(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *entrypath, const char *servername,
const char *sharename)
{
@@ -122,38 +97,25 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_dfs_q_dfs_remove(&q, entrypath, servername, sharename);
- if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETDFS, DFS_REMOVE, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_NETDFS, DFS_REMOVE,
+ q, r,
+ qbuf, rbuf,
+ dfs_io_q_dfs_remove,
+ dfs_io_r_dfs_remove,
+ NT_STATUS_UNSUCCESSFUL);
/* Return result */
result = werror_to_ntstatus(r.status);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_dfs_get_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *entrypath, const char *servername,
const char *sharename, uint32 info_level,
DFS_INFO_CTR *ctr)
@@ -167,42 +129,29 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename,
info_level);
- if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETDFS, DFS_GET_INFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_NETDFS, DFS_GET_INFO,
+ q, r,
+ qbuf, rbuf,
+ dfs_io_q_dfs_get_info,
+ dfs_io_r_dfs_get_info,
+ NT_STATUS_UNSUCCESSFUL);
/* Return result */
result = werror_to_ntstatus(r.status);
*ctr = r.ctr;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Enumerate dfs shares */
-NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_dfs_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 info_level, DFS_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -213,35 +162,22 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_dfs_q_dfs_enum(&q, info_level, ctr);
- if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETDFS, DFS_ENUM, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
r.ctr = ctr;
- if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_NETDFS, DFS_ENUM,
+ q, r,
+ qbuf, rbuf,
+ dfs_io_q_dfs_enum,
+ dfs_io_r_dfs_enum,
+ NT_STATUS_UNSUCCESSFUL);
/* Return result */
result = werror_to_ntstatus(r.status);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
diff --git a/source3/rpc_client/cli_ds.c b/source3/rpc_client/cli_ds.c
index 41063a5d7f..8d1945f769 100644
--- a/source3/rpc_client/cli_ds.c
+++ b/source3/rpc_client/cli_ds.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
RPC pipe client
Copyright (C) Gerald Carter 2002,
+ Copyright (C) Jeremy Allison 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
@@ -38,30 +39,14 @@ NTSTATUS rpccli_ds_getprimarydominfo(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
q.level = level;
- if (!ds_io_q_getprimdominfo("", &qbuf, 0, &q)
- || !rpc_api_pipe_req_int(cli, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!ds_io_r_getprimdominfo("", &rbuf, 0, &r)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC_DS, DS_GETPRIMDOMINFO,
+ q, r,
+ qbuf, rbuf,
+ ds_io_q_getprimdominfo,
+ ds_io_r_getprimdominfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return basic info - if we are requesting at info != 1 then
there could be trouble. */
@@ -76,20 +61,10 @@ NTSTATUS rpccli_ds_getprimarydominfo(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint16 level, DS_DOMINFO_CTR *ctr)
-{
- return rpccli_ds_getprimarydominfo(&cli->pipes[PI_LSARPC_DS], mem_ctx,
- level, ctr);
-}
-
-
/********************************************************************
Enumerate trusted domains in an AD forest
********************************************************************/
@@ -108,30 +83,14 @@ NTSTATUS rpccli_ds_enum_domain_trusts(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
init_q_ds_enum_domain_trusts( &q, server, flags );
- if (!ds_io_q_enum_domain_trusts("", &qbuf, 0, &q)
- || !rpc_api_pipe_req_int(cli, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!ds_io_r_enum_domain_trusts("", &rbuf, 0, &r)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC_DS, DS_ENUM_DOM_TRUSTS,
+ q, r,
+ qbuf, rbuf,
+ ds_io_q_enum_domain_trusts,
+ ds_io_r_enum_domain_trusts,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
@@ -168,19 +127,5 @@ NTSTATUS rpccli_ds_enum_domain_trusts(struct rpc_pipe_client *cli,
}
}
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-
-NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *server, uint32 flags,
- struct ds_domain_trust **trusts,
- uint32 *num_domains)
-{
- return rpccli_ds_enum_domain_trusts(&cli->pipes[PI_NETLOGON], mem_ctx,
- server, flags, trusts,
- num_domains);
-}
diff --git a/source3/rpc_client/cli_echo.c b/source3/rpc_client/cli_echo.c
index cd7e21f918..89de6cec94 100644
--- a/source3/rpc_client/cli_echo.c
+++ b/source3/rpc_client/cli_echo.c
@@ -4,6 +4,7 @@
RPC pipe client
Copyright (C) Tim Potter 2003
+ Copyright (C) Jeremy Allison 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,7 +23,7 @@
#include "includes.h"
-NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_echo_add_one(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 request, uint32 *response)
{
prs_struct qbuf, rbuf;
@@ -33,42 +34,26 @@ NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
/* Marshall data and send request */
init_echo_q_add_one(&q, request);
- if (!echo_io_q_add_one("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_ECHO, ECHO_ADD_ONE, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!echo_io_r_add_one("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC( cli, mem_ctx, PI_ECHO, ECHO_ADD_ONE,
+ q, r,
+ qbuf, rbuf,
+ echo_io_q_add_one,
+ echo_io_r_add_one,
+ NT_STATUS_UNSUCCESSFUL);
if (response)
*response = r.response;
result = True;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_echo_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 size, char *in_data, char **out_data)
{
prs_struct qbuf, rbuf;
@@ -79,28 +64,16 @@ NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
/* Marshall data and send request */
init_echo_q_echo_data(&q, size, in_data);
- if (!echo_io_q_echo_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_ECHO, ECHO_DATA, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!echo_io_r_echo_data("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC( cli, mem_ctx, PI_ECHO, ECHO_DATA,
+ q, r,
+ qbuf, rbuf,
+ echo_io_q_echo_data,
+ echo_io_r_echo_data,
+ NT_STATUS_UNSUCCESSFUL);
result = True;
@@ -109,14 +82,10 @@ NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
memcpy(*out_data, r.data, size);
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_echo_sink_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 size, char *in_data)
{
prs_struct qbuf, rbuf;
@@ -127,41 +96,23 @@ NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
/* Marshall data and send request */
init_echo_q_sink_data(&q, size, in_data);
- if (!echo_io_q_sink_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_ECHO, ECHO_SINK_DATA, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!echo_io_r_sink_data("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_ECHO, ECHO_SINK_DATA,
+ q, r,
+ qbuf, rbuf,
+ echo_io_q_sink_data,
+ echo_io_r_sink_data,
+ NT_STATUS_UNSUCCESSFUL);
result = True;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_echo_source_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 size, char **out_data)
{
prs_struct qbuf, rbuf;
@@ -172,36 +123,18 @@ NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- if (!prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!prs_init(&rbuf, 0, mem_ctx, UNMARSHALL)) {
- prs_mem_free(&qbuf);
- return NT_STATUS_NO_MEMORY;
- }
-
/* Marshall data and send request */
init_echo_q_source_data(&q, size);
- if (!echo_io_q_source_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_ECHO, ECHO_SOURCE_DATA, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!echo_io_r_source_data("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_ECHO, ECHO_SOURCE_DATA,
+ q, r,
+ qbuf, rbuf,
+ echo_io_q_source_data,
+ echo_io_r_source_data,
+ NT_STATUS_UNSUCCESSFUL);
result = True;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 26f82cdfbe..d7dcda72e3 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -3,10 +3,8 @@
RPC pipe client
Copyright (C) Tim Potter 2000-2001,
Copyright (C) Andrew Tridgell 1992-1997,2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
- Copyright (C) Paul Ashton 1997,2000,
- Copyright (C) Elrond 2000,
Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Jeremy Allison 2005.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,7 +22,6 @@
*/
#include "includes.h"
-#include "rpc_client.h"
/** @defgroup lsa LSA - Local Security Architecture
* @ingroup rpc_client
@@ -54,16 +51,9 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
LSA_SEC_QOS qos;
NTSTATUS result;
- SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
if (sec_qos) {
@@ -75,18 +65,12 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
/* Marshall data and send request */
- if (!lsa_io_q_open_pol("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_open_pol,
+ lsa_io_r_open_pol,
+ NT_STATUS_UNSUCCESSFUL );
/* Return output parameters */
@@ -97,20 +81,9 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
-{
- return rpccli_lsa_open_policy(&cli->pipes[PI_LSARPC], mem_ctx,
- sec_qos, des_access, pol);
-}
-
/** Open a LSA policy handle
*
* @param cli Handle on an initialised SMB connection
@@ -125,40 +98,24 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
LSA_R_OPEN_POL2 r;
LSA_SEC_QOS qos;
NTSTATUS result;
+ char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Initialise input parameters */
-
if (sec_qos) {
init_lsa_sec_qos(&qos, 2, 1, 0);
- init_q_open_pol2(&q, cli->cli->srv_name_slash, 0, des_access,
- &qos);
+ init_q_open_pol2(&q, srv_name_slash, 0, des_access, &qos);
} else {
- init_q_open_pol2(&q, cli->cli->srv_name_slash, 0, des_access,
- NULL);
+ init_q_open_pol2(&q, srv_name_slash, 0, des_access, NULL);
}
- /* Marshall data and send request */
-
- if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENPOLICY2,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_open_pol2,
+ lsa_io_r_open_pol2,
+ NT_STATUS_UNSUCCESSFUL );
/* Return output parameters */
@@ -169,21 +126,9 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- BOOL sec_qos, uint32 des_access, POLICY_HND *pol)
-{
- return rpccli_lsa_open_policy2(&cli->pipes[PI_LSARPC], mem_ctx,
- sec_qos, des_access, pol);
-}
-
-
/** Close a LSA policy handle */
NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
@@ -194,32 +139,17 @@ NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
LSA_R_CLOSE r;
NTSTATUS result;
- SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_lsa_q_close(&q, pol);
- if (!lsa_io_q_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_CLOSE, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_close("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CLOSE,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_close,
+ lsa_io_r_close,
+ NT_STATUS_UNSUCCESSFUL );
/* Return output parameters */
@@ -230,19 +160,9 @@ NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
*pol = r.pol;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol)
-{
- return rpccli_lsa_close(&cli->pipes[PI_LSARPC], mem_ctx, pol);
-}
-
/** Lookup a list of sids */
NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
@@ -256,46 +176,32 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
LSA_R_LOOKUP_SIDS r;
DOM_R_REF ref;
LSA_TRANS_NAME_ENUM t_names;
- NTSTATUS result;
+ NTSTATUS result = NT_STATUS_OK;
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
- if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
ZERO_STRUCT(ref);
ZERO_STRUCT(t_names);
r.dom_ref = &ref;
r.names = &t_names;
- if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_lookup_sids,
+ lsa_io_r_lookup_sids,
+ NT_STATUS_UNSUCCESSFUL );
- if (!NT_STATUS_IS_OK(result) &&
- NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
+ if (!NT_STATUS_IS_OK(r.status) &&
+ NT_STATUS_V(r.status) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
/* An actual error occured */
+ result = r.status;
goto done;
}
@@ -356,22 +262,10 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_sids,
- const DOM_SID *sids,
- char ***domains, char ***names, uint32 **types)
-{
- return rpccli_lsa_lookup_sids(&cli->pipes[PI_LSARPC], mem_ctx,
- pol, num_sids, sids,
- domains, names, types);
-}
-
/** Lookup a list of names */
NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
@@ -390,30 +284,17 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
- init_q_lookup_names(mem_ctx, &q, pol, num_names, names);
-
- if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
ZERO_STRUCT(ref);
r.dom_ref = &ref;
- if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ init_q_lookup_names(mem_ctx, &q, pol, num_names, names);
+
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_lookup_names,
+ lsa_io_r_lookup_names,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
@@ -468,21 +349,10 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, int num_names,
- const char **names, DOM_SID **sids,
- uint32 **types)
-{
- return rpccli_lsa_lookup_names(&cli->pipes[PI_LSARPC], mem_ctx,
- pol, num_names, names, sids, types);
-}
-
/** Query info policy
*
* @param domain_sid - returned remote server's domain sid */
@@ -497,32 +367,17 @@ NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
LSA_R_QUERY_INFO r;
NTSTATUS result;
- SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_q_query(&q, pol, info_class);
- if (!lsa_io_q_query("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_QUERYINFOPOLICY,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query,
+ lsa_io_r_query,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -570,21 +425,10 @@ NTSTATUS rpccli_lsa_query_info_policy(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint16 info_class,
- char **domain_name, DOM_SID **domain_sid)
-{
- return rpccli_lsa_query_info_policy(&cli->pipes[PI_LSARPC], mem_ctx,
- pol, info_class, domain_name,
- domain_sid);
-}
-
/** Query info policy2
*
* @param domain_name - returned remote server's domain name
@@ -612,27 +456,14 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_q_query2(&q, pol, info_class);
- if (!lsa_io_q_query_info2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, LSA_QUERYINFO2, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_info2("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYINFO2,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query_info2,
+ lsa_io_r_query_info2,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -674,25 +505,10 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint16 info_class,
- char **domain_name, char **dns_name,
- char **forest_name,
- struct uuid **domain_guid,
- DOM_SID **domain_sid)
-{
- return rpccli_lsa_query_info_policy2(&cli->pipes[PI_LSARPC], mem_ctx,
- pol, info_class, domain_name,
- dns_name, forest_name,
- domain_guid, domain_sid);
-}
-
/**
* Enumerate list of trusted domains
*
@@ -720,7 +536,6 @@ NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
int i;
fstring tmp;
-
ZERO_STRUCT(in);
ZERO_STRUCT(out);
@@ -728,7 +543,7 @@ NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
init_q_enum_trust_dom(&in, pol, *enum_ctx, 0x10000);
- CLI_DO_RPC_EX( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM,
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMTRUSTDOM,
in, out,
qbuf, rbuf,
lsa_io_q_enum_trust_dom,
@@ -779,19 +594,9 @@ NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
return out.status;
}
-NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *enum_ctx,
- uint32 *num_domains,
- char ***domain_names, DOM_SID **domain_sids)
-{
- return rpccli_lsa_enum_trust_dom(&cli->pipes[PI_LSARPC], mem_ctx,
- pol, enum_ctx, num_domains,
- domain_names, domain_sids);
-}
-
/** Enumerate privileges*/
-NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_enum_privilege(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length,
uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low)
{
@@ -804,27 +609,14 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
- if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUM_PRIVS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_PRIVS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_enum_privs,
+ lsa_io_r_enum_privs,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -865,15 +657,13 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/** Get privilege name */
-NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_get_dispname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, const char *name,
uint16 lang_id, uint16 lang_id_sys,
fstring description, uint16 *lang_id_desc)
@@ -886,27 +676,14 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
- if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_PRIV_GET_DISPNAME,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_priv_get_dispname,
+ lsa_io_r_priv_get_dispname,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -918,15 +695,13 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*lang_id_desc = r.lang_id;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/** Enumerate list of SIDs */
-NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length,
uint32 *num_sids, DOM_SID **sids)
{
@@ -939,27 +714,14 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- /* Marshall data and send request */
-
init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
- if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_enum_accounts,
+ lsa_io_r_enum_accounts,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
@@ -989,8 +751,6 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*enum_ctx = r.enum_context;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
@@ -1004,7 +764,7 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*
* */
-NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_create_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access,
POLICY_HND *user_pol)
{
@@ -1016,29 +776,16 @@ NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
- /* Marshall data and send request */
-
- if (!lsa_io_q_create_account("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_CREATEACCOUNT, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_create_account("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_CREATEACCOUNT,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_create_account,
+ lsa_io_r_create_account,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1046,10 +793,6 @@ NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*user_pol = r.pol;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -1057,7 +800,7 @@ NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*
* @param cli Handle on an initialised SMB connection */
-NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_open_account(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access,
POLICY_HND *user_pol)
{
@@ -1069,29 +812,16 @@ NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
init_lsa_q_open_account(&q, dom_pol, sid, des_access);
- /* Marshall data and send request */
-
- if (!lsa_io_q_open_account("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENACCOUNT, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_open_account("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENACCOUNT,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_open_account,
+ lsa_io_r_open_account,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1099,10 +829,6 @@ NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*user_pol = r.pol;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -1110,7 +836,7 @@ NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*
* @param cli Handle on an initialised SMB connection */
-NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *count, LUID_ATTR **set)
{
prs_struct qbuf, rbuf;
@@ -1122,29 +848,16 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
init_lsa_q_enum_privsaccount(&q, pol);
- /* Marshall data and send request */
-
- if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_enum_privsaccount,
+ lsa_io_r_enum_privsaccount,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1169,15 +882,13 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*count=r.count;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/** Get a privilege value given its name */
-NTSTATUS cli_lsa_lookup_priv_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, const char *name, LUID *luid)
{
prs_struct qbuf, rbuf;
@@ -1188,27 +899,16 @@ NTSTATUS cli_lsa_lookup_priv_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_lsa_q_lookup_priv_value(&q, pol, name);
- if (!lsa_io_q_lookup_priv_value("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_LOOKUPPRIVVALUE, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_lookup_priv_value("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_lookup_priv_value,
+ lsa_io_r_lookup_priv_value,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1220,15 +920,13 @@ NTSTATUS cli_lsa_lookup_priv_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
(*luid).high=r.luid.high;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/** Query LSA security object */
-NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_query_secobj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 sec_info,
SEC_DESC_BUF **psdb)
{
@@ -1240,27 +938,16 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_q_query_sec_obj(&q, pol, sec_info);
- if (!lsa_io_q_query_sec_obj("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYSECOBJ, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_sec_obj("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYSECOBJ,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query_sec_obj,
+ lsa_io_r_query_sec_obj,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1272,8 +959,6 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*psdb = r.buf;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
@@ -1283,7 +968,7 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
takes a SID directly, avoiding the open_account call.
*/
-NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID *sid,
uint32 *count, char ***priv_names)
{
@@ -1298,24 +983,15 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_q_enum_acct_rights(&q, pol, 2, sid);
- if (!lsa_io_q_enum_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if (!lsa_io_r_enum_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_enum_acct_rights,
+ lsa_io_r_enum_acct_rights,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1353,10 +1029,9 @@ done:
/* add account rights to an account. */
-NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID sid,
-
-uint32 count, const char **privs_name)
+ uint32 count, const char **privs_name)
{
prs_struct qbuf, rbuf;
LSA_Q_ADD_ACCT_RIGHTS q;
@@ -1364,26 +1039,17 @@ uint32 count, const char **privs_name)
NTSTATUS result;
ZERO_STRUCT(q);
-
- /* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ ZERO_STRUCT(r);
/* Marshall data and send request */
init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
- if (!lsa_io_q_add_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ADDACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_add_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_add_acct_rights,
+ lsa_io_r_add_acct_rights,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1396,7 +1062,7 @@ done:
/* remove account rights for an account. */
-NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID sid, BOOL removeall,
uint32 count, const char **privs_name)
{
@@ -1406,26 +1072,17 @@ NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ct
NTSTATUS result;
ZERO_STRUCT(q);
-
- /* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ ZERO_STRUCT(r);
/* Marshall data and send request */
init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
- if (!lsa_io_q_remove_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_REMOVEACCTRIGHTS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_remove_acct_rights("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_remove_acct_rights,
+ lsa_io_r_remove_acct_rights,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1539,7 +1196,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
#endif
-NTSTATUS cli_lsa_open_trusted_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask,
POLICY_HND *trustdom_pol)
{
@@ -1551,29 +1208,18 @@ NTSTATUS cli_lsa_open_trusted_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask);
/* Marshall data and send request */
- if (!lsa_io_q_open_trusted_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENTRUSTDOM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_open_trusted_domain("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOM,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_open_trusted_domain,
+ lsa_io_r_open_trusted_domain,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1581,14 +1227,10 @@ NTSTATUS cli_lsa_open_trusted_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*trustdom_pol = r.handle;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_lsa_query_trusted_domain_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, DOM_SID *dom_sid,
LSA_TRUSTED_DOMAIN_INFO **info)
@@ -1601,27 +1243,16 @@ NTSTATUS cli_lsa_query_trusted_domain_info(struct cli_state *cli, TALLOC_CTX *me
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_q_query_trusted_domain_info(&q, pol, info_class);
- if (!lsa_io_q_query_trusted_domain_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFO, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFO,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query_trusted_domain_info,
+ lsa_io_r_query_trusted_domain_info,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1630,14 +1261,11 @@ NTSTATUS cli_lsa_query_trusted_domain_info(struct cli_state *cli, TALLOC_CTX *me
*info = r.info;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_lsa_query_trusted_domain_info_by_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, DOM_SID *dom_sid,
LSA_TRUSTED_DOMAIN_INFO **info)
@@ -1650,27 +1278,16 @@ NTSTATUS cli_lsa_query_trusted_domain_info_by_sid(struct cli_state *cli, TALLOC_
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid);
- if (!lsa_io_q_query_trusted_domain_info_by_sid("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query_trusted_domain_info_by_sid,
+ lsa_io_r_query_trusted_domain_info,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1679,13 +1296,11 @@ NTSTATUS cli_lsa_query_trusted_domain_info_by_sid(struct cli_state *cli, TALLOC_
*info = r.info;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_lsa_query_trusted_domain_info_by_name(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, const char *domain_name,
LSA_TRUSTED_DOMAIN_INFO **info)
@@ -1698,27 +1313,16 @@ NTSTATUS cli_lsa_query_trusted_domain_info_by_name(struct cli_state *cli, TALLOC
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name);
- if (!lsa_io_q_query_trusted_domain_info_by_name("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME,
+ q, r,
+ qbuf, rbuf,
+ lsa_io_q_query_trusted_domain_info_by_name,
+ lsa_io_r_query_trusted_domain_info,
+ NT_STATUS_UNSUCCESSFUL);
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
@@ -1727,11 +1331,6 @@ NTSTATUS cli_lsa_query_trusted_domain_info_by_name(struct cli_state *cli, TALLOC
*info = r.info;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-
-/** @} **/
-
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index fad60dbc20..88b6c792eb 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -2,12 +2,9 @@
Unix SMB/CIFS implementation.
NT Domain Authentication SMB / MSRPC client
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Tim Potter 2001
- Copyright (C) Paul Ashton 1997.
Copyright (C) Jeremy Allison 1998.
- Copyright (C) Andrew Bartlett 2001.
-
+ Largely re-written by Jeremy Allison (C) 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
@@ -26,104 +23,52 @@
#include "includes.h"
/* LSA Request Challenge. Sends our challenge to server, then gets
- server response. These are used to generate the credentials. */
-
-NTSTATUS cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
- DOM_CHAL *srv_chal)
-{
- prs_struct qbuf, rbuf;
- NET_Q_REQ_CHAL q;
- NET_R_REQ_CHAL r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_REQCHAL */
-
- DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
- global_myname(), cli->desthost, credstr(clnt_chal->data)));
-
- /* store the parameters */
- init_q_req_chal(&q, cli->srv_name_slash, global_myname(), clnt_chal);
-
- /* Marshall data and send request */
-
- if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_REQCHAL, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarhall response */
-
- if (!net_io_r_req_chal("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = r.status;
-
- /* Return result */
-
- if (NT_STATUS_IS_OK(result)) {
- memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data));
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
-}
+ server response. These are used to generate the credentials.
+ The sent and received challenges are stored in the netlog pipe
+ private data. Only call this via rpccli_netlogon_setup_creds(). JRA.
+*/
-NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli,
- const char *server_name,
- const char *computer_name,
- DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
+static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *server_name,
+ const char *clnt_name,
+ const DOM_CHAL *clnt_chal_in,
+ DOM_CHAL *srv_chal_out)
{
- prs_struct qbuf, rbuf;
- NET_Q_REQ_CHAL q;
- NET_R_REQ_CHAL r;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ prs_struct qbuf, rbuf;
+ NET_Q_REQ_CHAL q;
+ NET_R_REQ_CHAL r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_REQCHAL */
+ /* create and send a MSRPC command with api NET_REQCHAL */
- DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
- computer_name, server_name));
-
- /* store the parameters */
- init_q_req_chal(&q, server_name, computer_name, clnt_chal);
+ DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n",
+ clnt_name, server_name));
- /* Marshall data and send request */
+ /* store the parameters */
+ init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in);
- if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, NET_REQCHAL, &qbuf, &rbuf)) {
- goto done;
- }
+ /* Marshall data and send request */
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_req_chal,
+ net_io_r_req_chal,
+ NT_STATUS_UNSUCCESSFUL);
- /* Unmarhall response */
+ result = r.status;
- if (!net_io_r_req_chal("", &r, &rbuf, 0)) {
- goto done;
- }
+ /* Return result */
- result = r.status;
-
- /* Return result */
+ if (NT_STATUS_IS_OK(result)) {
+ /* Store the returned server challenge. */
+ *srv_chal_out = r.srv_chal;
+ }
- if (NT_STATUS_IS_OK(result)) {
- memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data));
- }
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return result;
+ return result;
}
+#if 0
/****************************************************************************
LSA Authenticate 2
@@ -132,7 +77,7 @@ Ensure that the server credential returned matches the session key
encrypt of the server challenge originally received. JRA.
****************************************************************************/
-NTSTATUS cli_net_auth2(struct cli_state *cli,
+ NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
uint16 sec_chan,
uint32 *neg_flags, DOM_CHAL *srv_chal)
{
@@ -142,9 +87,6 @@ NTSTATUS cli_net_auth2(struct cli_state *cli,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring machine_acct;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
if ( sec_chan == SEC_CHAN_DOMAIN )
fstr_sprintf( machine_acct, "%s$", lp_workgroup() );
else
@@ -164,16 +106,12 @@ NTSTATUS cli_net_auth2(struct cli_state *cli,
/* turn parameters into data stream */
- if (!net_io_q_auth_2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_AUTH2, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_auth_2("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_auth_2,
+ net_io_r_auth_2,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
@@ -186,259 +124,257 @@ NTSTATUS cli_net_auth2(struct cli_state *cli,
*/
zerotime.time = 0;
- if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal,
- zerotime) == 0) {
+ if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
/*
* Server replied with bad credential. Fail.
*/
DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- result = NT_STATUS_ACCESS_DENIED;
- goto done;
+password ?).\n", cli->cli->desthost ));
+ return NT_STATUS_ACCESS_DENIED;
}
*neg_flags = r.srv_flgs.neg_flags;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
+#endif
+
+/****************************************************************************
+ LSA Authenticate 2
-NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
- const char *server_name,
- const char *account_name,
- uint16 sec_chan_type,
- const char *computer_name,
- const DOM_CHAL *credentials,
- uint32 *neg_flags,
- DOM_CHAL *srv_chal)
+ Send the client credential, receive back a server credential.
+ The caller *must* ensure that the server credential returned matches the session key
+ encrypt of the server challenge originally received. JRA.
+****************************************************************************/
+
+static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *server_name,
+ const char *account_name,
+ uint16 sec_chan_type,
+ const char *computer_name,
+ uint32 *neg_flags_inout,
+ const DOM_CHAL *clnt_chal_in,
+ DOM_CHAL *srv_chal_out)
{
prs_struct qbuf, rbuf;
NET_Q_AUTH_2 q;
NET_R_AUTH_2 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
/* create and send a MSRPC command with api NET_AUTH2 */
DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
server_name, account_name, sec_chan_type, computer_name,
- *neg_flags));
+ *neg_flags_inout));
/* store the parameters */
init_q_auth_2(&q, server_name, account_name, sec_chan_type,
- computer_name, credentials, *neg_flags);
+ computer_name, clnt_chal_in, *neg_flags_inout);
/* turn parameters into data stream */
- if (!net_io_q_auth_2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, NET_AUTH2, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_auth_2("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_auth_2,
+ net_io_r_auth_2,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
if (NT_STATUS_IS_OK(result)) {
- *srv_chal = r.srv_chal;
- *neg_flags = r.srv_flgs.neg_flags;
+ *srv_chal_out = r.srv_chal;
+ *neg_flags_inout = r.srv_flgs.neg_flags;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
+#if 0 /* not currebntly used */
/****************************************************************************
-LSA Authenticate 3
+ LSA Authenticate 3
-Send the client credential, receive back a server credential.
-Ensure that the server credential returned matches the session key
-encrypt of the server challenge originally received. JRA.
+ Send the client credential, receive back a server credential.
+ The caller *must* ensure that the server credential returned matches the session key
+ encrypt of the server challenge originally received. JRA.
****************************************************************************/
-NTSTATUS cli_net_auth3(struct cli_state *cli,
- uint16 sec_chan,
- uint32 *neg_flags, DOM_CHAL *srv_chal)
+static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *server_name,
+ const char *account_name,
+ uint16 sec_chan_type,
+ const char *computer_name,
+ uint32 *neg_flags_inout,
+ const DOM_CHAL *clnt_chal_in,
+ DOM_CHAL *srv_chal_out)
{
prs_struct qbuf, rbuf;
NET_Q_AUTH_3 q;
NET_R_AUTH_3 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
/* create and send a MSRPC command with api NET_AUTH2 */
DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname(),
- credstr(cli->clnt_cred.challenge.data), *neg_flags));
+ server_name, account_name, sec_chan_type, computer_name,
+ credstr(clnt_chal_in->data), *neg_flags_inout));
/* store the parameters */
- init_q_auth_3(&q, cli->srv_name_slash, cli->mach_acct,
- sec_chan, global_myname(), &cli->clnt_cred.challenge,
- *neg_flags);
+ init_q_auth_3(&q, server_name, account_name, sec_chan_type,
+ computer_name, clnt_chal_in, *neg_flags_inout);
/* turn parameters into data stream */
- if (!net_io_q_auth_3("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_AUTH3, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_auth_3("", &r, &rbuf, 0)) {
- goto done;
- }
-
- result = r.status;
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_auth_3,
+ net_io_r_auth_3,
+ NT_STATUS_UNSUCCESSFUL);
if (NT_STATUS_IS_OK(result)) {
- UTIME zerotime;
-
- /*
- * Check the returned value using the initial
- * server received challenge.
- */
-
- zerotime.time = 0;
- if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal,
- zerotime) == 0) {
-
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_auth3: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- result = NT_STATUS_ACCESS_DENIED;
- goto done;
- }
- *neg_flags = r.srv_flgs.neg_flags;
+ *srv_chal_out = r.srv_chal;
+ *neg_flags_inout = r.srv_flgs.neg_flags;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
+#endif /* not currebntly used */
-/* Initialize domain session credentials */
+/****************************************************************************
+ Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
+ credentials chain. Stores the credentials in the struct dcinfo in the
+ netlogon pipe struct.
+****************************************************************************/
-NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
- uint16 sec_chan,
- const unsigned char mach_pwd[16], uint32 *neg_flags, int level)
+NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli,
+ const char *server_name,
+ const char *domain,
+ const char *machine_account,
+ const char machine_pwd[16],
+ uint32 sec_chan_type,
+ uint32 *neg_flags_inout)
{
- DOM_CHAL clnt_chal;
- DOM_CHAL srv_chal;
- UTIME zerotime;
- NTSTATUS result;
+ NTSTATUS result;
+ DOM_CHAL clnt_chal_send;
+ DOM_CHAL srv_chal_recv;
+ struct dcinfo *dc;
- /******************* Request Challenge ********************/
+ SMB_ASSERT(cli->pipe_idx == PI_NETLOGON);
- generate_random_buffer(clnt_chal.data, 8);
-
- /* send a client challenge; receive a server challenge */
- result = cli_net_req_chal(cli, &clnt_chal, &srv_chal);
+ dc = cli->dc;
+ if (!dc) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
- return result;
- }
-
- /**************** Long-term Session key **************/
+ /* Ensure we don't reuse any of this state. */
+ ZERO_STRUCTP(dc);
+
+ /* Store the machine account password we're going to use. */
+ memcpy(dc->mach_pw, machine_pwd, 16);
- /* calculate the session key */
- cred_session_key(&clnt_chal, &srv_chal, mach_pwd,
- cli->sess_key);
- memset((char *)cli->sess_key+8, '\0', 8);
+ fstrcpy(dc->remote_machine, "\\\\");
+ fstrcat(dc->remote_machine, server_name);
- /******************* Authenticate 2/3 ********************/
+ fstrcpy(dc->domain, domain);
- /* calculate auth-2/3 credentials */
- zerotime.time = 0;
- cred_create(cli->sess_key, &clnt_chal, zerotime, &cli->clnt_cred.challenge);
+ fstr_sprintf( dc->mach_acct, "%s$", machine_account);
+
+ /* Create the client challenge. */
+ generate_random_buffer(clnt_chal_send.data, 8);
+
+ /* Get the server challenge. */
+ result = rpccli_net_req_chal(cli,
+ cli->mem_ctx,
+ dc->remote_machine,
+ machine_account,
+ &clnt_chal_send,
+ &srv_chal_recv);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ return result;
+ }
+
+ /* Calculate the session key and client credentials */
+ creds_client_init(dc,
+ &clnt_chal_send,
+ &srv_chal_recv,
+ machine_pwd,
+ &clnt_chal_send);
/*
- * Send client auth-2/3 challenge.
- * Receive an auth-2/3 challenge response and check it.
+ * Send client auth-2 challenge and receive server repy.
*/
- switch (level) {
- case 2:
- result = cli_net_auth2(cli, sec_chan, neg_flags, &srv_chal);
- break;
- case 3:
- result = cli_net_auth3(cli, sec_chan, neg_flags, &srv_chal);
- break;
- default:
- DEBUG(1,("cli_nt_setup_creds: unsupported auth level: %d\n", level));
- break;
+
+ result = rpccli_net_auth2(cli,
+ cli->mem_ctx,
+ dc->remote_machine,
+ dc->mach_acct,
+ sec_chan_type,
+ machine_account,
+ neg_flags_inout,
+ &clnt_chal_send, /* input. */
+ &srv_chal_recv); /* output */
+
+ if (!NT_STATUS_IS_OK(result)) {
+ return result;
}
- if (!NT_STATUS_IS_OK(result))
- DEBUG(3,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result)));
+ /*
+ * Check the returned value using the initial
+ * server received challenge.
+ */
- return result;
+ if (!creds_client_check(dc, &srv_chal_recv)) {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("rpccli_netlogon_setup_creds: server %s "
+ "replied with bad credential\n",
+ cli->cli->desthost ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(5,("rpccli_netlogon_setup_creds: server %s credential "
+ "chain established.\n",
+ cli->cli->desthost ));
+
+ return NT_STATUS_OK;
}
/* Logon Control 2 */
-NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 query_level)
{
prs_struct qbuf, rbuf;
NET_Q_LOGON_CTRL2 q;
NET_R_LOGON_CTRL2 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ init_net_q_logon_ctrl2(&q, server, query_level);
/* Marshall data and send request */
- if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_logon_ctrl2,
+ net_io_r_logon_ctrl2,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -456,72 +392,29 @@ NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
init_net_q_getdcname(&q, mydcname, domainname);
/* Marshall data and send request */
- if (!net_io_q_getdcname("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, NET_GETDCNAME, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_getdcname("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = r.status;
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_getdcname,
+ net_io_r_getdcname,
+ NT_STATUS_UNSUCCESSFUL);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ }
return result;
}
-NTSTATUS cli_netlogon_getdcname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *domainname, fstring dcname)
-{
- return rpccli_netlogon_getdcname(&cli->pipes[PI_NETLOGON], mem_ctx,
- cli->srv_name_slash, domainname,
- dcname);
-}
-
-/****************************************************************************
-Generate the next creds to use.
-****************************************************************************/
-
-static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
-{
- /*
- * Create the new client credentials.
- */
-
- cli->clnt_cred.timestamp.time = time(NULL);
-
- memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
-
- /* Calculate the new credentials. */
- cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
- new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
-}
-
/* Sam synchronisation */
-NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds,
+NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 database_id, uint32 next_rid, uint32 *num_deltas,
SAM_DELTA_HDR **hdr_deltas,
SAM_DELTA_CTR **deltas)
@@ -531,36 +424,31 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_C
NET_R_SAM_SYNC r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_CRED clnt_creds;
+ DOM_CRED ret_creds;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ ZERO_STRUCT(ret_creds);
/* Initialise input parameters */
- gen_next_creds(cli, &clnt_creds);
+ creds_client_step(cli->dc, &clnt_creds);
- init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2,
- &clnt_creds, ret_creds, database_id, next_rid);
+ prs_set_session_key(&qbuf, cli->dc->sess_key);
+ prs_set_session_key(&rbuf, cli->dc->sess_key);
- /* Marshall data and send request */
-
- if (!net_io_q_sam_sync("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAM_SYNC, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(),
+ &clnt_creds, &ret_creds, database_id, next_rid);
- /* Unmarshall response */
+ /* Marshall data and send request */
- if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_sam_sync,
+ net_io_r_sam_sync,
+ NT_STATUS_UNSUCCESSFUL);
/* Return results */
@@ -569,18 +457,20 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_C
*hdr_deltas = r.hdr_deltas;
*deltas = r.deltas;
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (!NT_STATUS_IS_ERR(result)) {
+ /* Check returned credentials. */
+ if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
+ DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
return result;
}
/* Sam synchronisation */
-NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 database_id, UINT64_S seqnum,
uint32 *num_deltas,
SAM_DELTA_HDR **hdr_deltas,
@@ -595,33 +485,22 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- gen_next_creds(cli, &clnt_creds);
+ creds_client_step(cli->dc, &clnt_creds);
- init_net_q_sam_deltas(&q, cli->srv_name_slash,
- cli->clnt_name_slash + 2, &clnt_creds,
+ init_net_q_sam_deltas(&q, cli->dc->remote_machine,
+ global_myname(), &clnt_creds,
database_id, seqnum);
/* Marshall data and send request */
- if (!net_io_q_sam_deltas("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAM_DELTAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_sam_deltas,
+ net_io_r_sam_deltas,
+ NT_STATUS_UNSUCCESSFUL);
/* Return results */
@@ -630,47 +509,49 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*hdr_deltas = r.hdr_deltas;
*deltas = r.deltas;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (!NT_STATUS_IS_ERR(result)) {
+ /* Check returned credentials. */
+ if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
+ DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
return result;
}
/* Logon domain user */
-NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- DOM_CRED *ret_creds,
- const char *username, const char *password,
+NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *domain,
+ const char *username,
+ const char *password,
int logon_type)
{
prs_struct qbuf, rbuf;
NET_Q_SAM_LOGON q;
NET_R_SAM_LOGON r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED clnt_creds, dummy_rtn_creds;
+ DOM_CRED clnt_creds;
+ DOM_CRED ret_creds;
NET_ID_INFO_CTR ctr;
NET_USER_INFO_3 user;
int validation_level = 3;
+ fstring clnt_name_slash;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- ZERO_STRUCT(dummy_rtn_creds);
-
- /* Initialise parse structures */
+ ZERO_STRUCT(ret_creds);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() );
/* Initialise input parameters */
- gen_next_creds(cli, &clnt_creds);
+ creds_client_step(cli->dc, &clnt_creds);
q.validation_level = validation_level;
- if (ret_creds == NULL)
- ret_creds = &dummy_rtn_creds;
-
ctr.switch_value = logon_type;
switch (logon_type) {
@@ -679,11 +560,11 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
- init_id_info1(&ctr.auth.id1, lp_workgroup(),
+ init_id_info1(&ctr.auth.id1, domain,
0, /* param_ctrl */
0xdead, 0xbeef, /* LUID? */
- username, cli->clnt_name_slash,
- (const char *)cli->sess_key, lm_owf_user_pwd,
+ username, clnt_name_slash,
+ cli->dc->sess_key, lm_owf_user_pwd,
nt_owf_user_pwd);
break;
@@ -698,46 +579,45 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SMBencrypt(password, chal, local_lm_response);
SMBNTencrypt(password, chal, local_nt_response);
- init_id_info2(&ctr.auth.id2, lp_workgroup(),
+ init_id_info2(&ctr.auth.id2, domain,
0, /* param_ctrl */
0xdead, 0xbeef, /* LUID? */
- username, cli->clnt_name_slash, chal,
+ username, clnt_name_slash, chal,
local_lm_response, 24, local_nt_response, 24);
break;
}
default:
DEBUG(0, ("switch value %d not supported\n",
ctr.switch_value));
- goto done;
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname(),
- &clnt_creds, ret_creds, logon_type,
+ r.user = &user;
+
+ init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(),
+ &clnt_creds, &ret_creds, logon_type,
&ctr);
/* Marshall data and send request */
- if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAMLOGON, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- r.user = &user;
-
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_sam_logon,
+ net_io_r_sam_logon,
+ NT_STATUS_UNSUCCESSFUL);
/* Return results */
result = r.status;
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (r.buffer_creds) {
+ /* Check returned credentials if present. */
+ if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
+ DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
return result;
}
@@ -751,52 +631,55 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
- const char *server_name_slash,
- DOM_CRED *clnt_creds,
- DOM_CRED *ret_creds,
+ const char *server,
const char *username,
const char *domain,
const char *workstation,
const uint8 chal[8],
DATA_BLOB lm_response,
DATA_BLOB nt_response,
- NET_USER_INFO_3 *info3,
- const uint8 *session_key)
+ NET_USER_INFO_3 *info3)
{
prs_struct qbuf, rbuf;
NET_Q_SAM_LOGON q;
NET_R_SAM_LOGON r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED dummy_rtn_creds;
NET_ID_INFO_CTR ctr;
int validation_level = 3;
- char *workstation_name_slash;
- uint8 netlogon_sess_key[16];
+ const char *workstation_name_slash;
+ const char *server_name_slash;
static uint8 zeros[16];
+ DOM_CRED clnt_creds;
+ DOM_CRED ret_creds;
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- ZERO_STRUCT(dummy_rtn_creds);
+ ZERO_STRUCT(ret_creds);
- workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
- if (!workstation_name_slash) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ creds_client_step(cli->dc, &clnt_creds);
+
+ if (server[0] != '\\' && server[1] != '\\') {
+ server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server);
+ } else {
+ server_name_slash = server;
}
- /* Initialise parse structures */
+ if (workstation[0] != '\\' && workstation[1] != '\\') {
+ workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
+ } else {
+ workstation_name_slash = workstation;
+ }
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ if (!workstation_name_slash || !server_name_slash) {
+ DEBUG(0, ("talloc_asprintf failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
/* Initialise input parameters */
q.validation_level = validation_level;
- if (ret_creds == NULL)
- ret_creds = &dummy_rtn_creds;
-
ctr.switch_value = NET_LOGON_TYPE;
init_id_info2(&ctr.auth.id2, domain,
@@ -806,35 +689,28 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
lm_response.data, lm_response.length, nt_response.data, nt_response.length);
init_sam_info(&q.sam_id, server_name_slash, global_myname(),
- clnt_creds, ret_creds, NET_LOGON_TYPE,
+ &clnt_creds, &ret_creds, NET_LOGON_TYPE,
&ctr);
- /* Marshall data and send request */
-
- if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
r.user = info3;
- if (!net_io_r_sam_logon("", &r, &rbuf, 0)) {
- goto done;
- }
+ /* Marshall data and send request */
+
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_sam_logon,
+ net_io_r_sam_logon,
+ NT_STATUS_UNSUCCESSFUL);
- ZERO_STRUCT(netlogon_sess_key);
- memcpy(netlogon_sess_key, session_key, 8);
-
if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
- SamOEMhash(info3->user_sess_key, netlogon_sess_key, 16);
+ SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16);
} else {
memset(info3->user_sess_key, '\0', 16);
}
if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
- SamOEMhash(info3->lm_sess_key, netlogon_sess_key, 8);
+ SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8);
} else {
memset(info3->lm_sess_key, '\0', 8);
}
@@ -847,108 +723,62 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
/* Return results */
result = r.status;
- memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds));
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ if (r.buffer_creds) {
+ /* Check returned credentials if present. */
+ if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) {
+ DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
return result;
}
-NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- DOM_CRED *ret_creds,
- const char *username,
- const char *domain,
- const char *workstation,
- const uint8 chal[8],
- DATA_BLOB lm_response,
- DATA_BLOB nt_response,
- NET_USER_INFO_3 *info3)
-{
- DOM_CRED clnt_creds;
-
- gen_next_creds(cli, &clnt_creds);
-
- return rpccli_netlogon_sam_network_logon(&cli->pipes[PI_NETLOGON],
- mem_ctx, cli->srv_name_slash,
- &clnt_creds,
- ret_creds, username,
- domain, workstation, chal,
- lm_response, nt_response,
- info3, cli->sess_key);
-}
-
/***************************************************************************
LSA Server Password Set.
****************************************************************************/
-NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *machine_name, uint8 hashed_mach_pwd[16])
{
prs_struct rbuf;
prs_struct qbuf;
- DOM_CRED new_clnt_cred;
- NET_Q_SRV_PWSET q_s;
+ DOM_CRED clnt_creds;
+ NET_Q_SRV_PWSET q;
+ NET_R_SRV_PWSET r;
uint16 sec_chan_type = 2;
- NTSTATUS nt_status;
+ NTSTATUS result;
- gen_next_creds( cli, &new_clnt_cred);
-
- prs_init(&qbuf , 1024, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ creds_client_step(cli->dc, &clnt_creds);
- DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan_type, machine_name,
- credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
+ DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n",
+ cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name));
/* store the parameters */
- init_q_srv_pwset(&q_s, cli->srv_name_slash, (const char *)cli->sess_key,
- cli->mach_acct, sec_chan_type, machine_name,
- &new_clnt_cred, hashed_mach_pwd);
-
- /* turn parameters into data stream */
- if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) {
- DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key,
+ cli->dc->mach_acct, sec_chan_type, machine_name,
+ &clnt_creds, hashed_mach_pwd);
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, PI_NETLOGON, NET_SRVPWSET, &qbuf, &rbuf))
- {
- NET_R_SRV_PWSET r_s;
-
- if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) {
- nt_status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- nt_status = r_s.status;
+ CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_srv_pwset,
+ net_io_r_srv_pwset,
+ NT_STATUS_UNSUCCESSFUL);
- if (!NT_STATUS_IS_OK(r_s.status))
- {
- /* report error code */
- DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status)));
- }
+ result = r.status;
- /* Update the credentials. */
- if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
- {
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- nt_status = NT_STATUS_UNSUCCESSFUL;
- }
+ if (!NT_STATUS_IS_OK(result)) {
+ /* report error code */
+ DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result)));
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
- return nt_status;
-}
+ /* Always check returned credentials. */
+ if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) {
+ DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return result;
+}
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 230750817a..df34b1c3d9 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -1,11 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1998.
- * Copyright (C) Jeremy Allison 1999.
- * Copyright (C) Andrew Bartlett 2003.
+ * Largely rewritten by Jeremy Allison 2005.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,23 +25,37 @@
extern struct pipe_id_info pipe_names[];
-/* convert pipe auth flags into the RPC auth type and level */
+/********************************************************************
+ Map internal value to wire value.
+ ********************************************************************/
-void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level)
+static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
{
- *auth_type = 0;
- *auth_level = 0;
- if (pipe_auth_flags & AUTH_PIPE_SEAL) {
- *auth_level = RPC_PIPE_AUTH_SEAL_LEVEL;
- } else if (pipe_auth_flags & AUTH_PIPE_SIGN) {
- *auth_level = RPC_PIPE_AUTH_SIGN_LEVEL;
- }
-
- if (pipe_auth_flags & AUTH_PIPE_NETSEC) {
- *auth_type = NETSEC_AUTH_TYPE;
- } else if (pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- *auth_type = NTLMSSP_AUTH_TYPE;
+ switch (auth_type) {
+
+ case PIPE_AUTH_TYPE_NONE:
+ return RPC_ANONYMOUS_AUTH_TYPE;
+
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ return RPC_NTLMSSP_AUTH_TYPE;
+
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_KRB5:
+ return RPC_SPNEGO_AUTH_TYPE;
+
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ return RPC_SCHANNEL_AUTH_TYPE;
+
+ case PIPE_AUTH_TYPE_KRB5:
+ return RPC_KRB5_AUTH_TYPE;
+
+ default:
+ DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
+ "auth type %u\n",
+ (unsigned int)auth_type ));
+ break;
}
+ return -1;
}
/********************************************************************
@@ -60,55 +70,81 @@ static uint32 get_rpc_call_id(void)
/*******************************************************************
Use SMBreadX to get rest of one fragment's worth of rpc data.
+ Will expand the current_pdu struct to the correct size.
********************************************************************/
-static BOOL rpc_read(struct rpc_pipe_client *cli, prs_struct *rdata,
- uint32 data_to_read, uint32 *rdata_offset)
+static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
+ prs_struct *current_pdu,
+ uint32 data_to_read,
+ uint32 *current_pdu_offset)
{
size_t size = (size_t)cli->max_recv_frag;
- int stream_offset = 0;
- int num_read;
+ uint32 stream_offset = 0;
+ ssize_t num_read;
char *pdata;
- int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata);
+ ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu);
- DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n",
- (int)data_to_read, (unsigned int)*rdata_offset, extra_data_size));
+ DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n",
+ (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size ));
/*
* Grow the buffer if needed to accommodate the data to be read.
*/
if (extra_data_size > 0) {
- if(!prs_force_grow(rdata, (uint32)extra_data_size)) {
- DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", extra_data_size ));
- return False;
+ if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) {
+ DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size ));
+ return NT_STATUS_NO_MEMORY;
}
- DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) ));
+ DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) ));
}
- pdata = prs_data_p(rdata) + *rdata_offset;
+ pdata = prs_data_p(current_pdu) + *current_pdu_offset;
- do /* read data using SMBreadX */
- {
- uint32 ecode;
- uint8 eclass;
-
- if (size > (size_t)data_to_read)
+ do {
+ /* read data using SMBreadX */
+ if (size > (size_t)data_to_read) {
size = (size_t)data_to_read;
+ }
- num_read = (int)cli_read(cli->cli, cli->fnum, pdata,
+ num_read = cli_read(cli->cli, cli->fnum, pdata,
(off_t)stream_offset, size);
- DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
- num_read, stream_offset, data_to_read));
+ DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n",
+ (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read));
+ /*
+ * A dos error of ERRDOS/ERRmoredata is not an error.
+ */
if (cli_is_dos_error(cli->cli)) {
- cli_dos_error(cli->cli, &eclass, &ecode);
- if (eclass != ERRDOS && ecode != ERRmoredata) {
- DEBUG(0,("rpc_read: Error %d/%u in cli_read\n",
- eclass, (unsigned int)ecode));
- return False;
- }
+ uint32 ecode;
+ uint8 eclass;
+ cli_dos_error(cli->cli, &eclass, &ecode);
+ if (eclass != ERRDOS && ecode != ERRmoredata) {
+ DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n",
+ eclass, (unsigned int)ecode,
+ cli_errstr(cli->cli),
+ cli->pipe_name ));
+ return dos_to_ntstatus(eclass, ecode);
+ }
+ }
+
+ /*
+ * Likewise for NT_STATUS_BUFFER_TOO_SMALL
+ */
+ if (cli_is_nt_error(cli->cli)) {
+ if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) {
+ DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n",
+ nt_errstr(cli_nt_error(cli->cli)),
+ cli->pipe_name ));
+ return cli_nt_error(cli->cli);
+ }
+ }
+
+ if (num_read == -1) {
+ DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n",
+ cli->pipe_name ));
+ return cli_get_nt_error(cli->cli);
}
data_to_read -= num_read;
@@ -119,262 +155,565 @@ static BOOL rpc_read(struct rpc_pipe_client *cli, prs_struct *rdata,
/* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
/*
- * Update the current offset into rdata by the amount read.
+ * Update the current offset into current_pdu by the amount read.
*/
- *rdata_offset += stream_offset;
-
- return True;
+ *current_pdu_offset += stream_offset;
+ return NT_STATUS_OK;
}
/****************************************************************************
- Checks the header. This will set the endian bit in the rdata prs_struct. JRA.
+ Try and get a PDU's worth of data from current_pdu. If not, then read more
+ from the wire.
****************************************************************************/
-static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
- BOOL *first, BOOL *last, uint32 *len)
+static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
{
- DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) ));
-
- /* Next call sets endian bit. */
+ NTSTATUS ret = NT_STATUS_OK;
+ uint32 current_pdu_len = prs_data_size(current_pdu);
+
+ /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
+ if (current_pdu_len < RPC_HEADER_LEN) {
+ /* rpc_read expands the current_pdu struct as neccessary. */
+ ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, &current_pdu_len);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
- if(!smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0)) {
- DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n"));
- return False;
+ /* This next call sets the endian bit correctly in current_pdu. */
+ /* We will propagate this to rbuf later. */
+ if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
+ DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
- if (prs_offset(rdata) != RPC_HEADER_LEN) {
- DEBUG(0,("rpc_check_hdr: offset was %x, should be %x.\n", prs_offset(rdata), RPC_HEADER_LEN));
- return False;
+ /* Ensure we have frag_len bytes of data. */
+ if (current_pdu_len < prhdr->frag_len) {
+ /* rpc_read expands the current_pdu struct as neccessary. */
+ ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, &current_pdu_len);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
}
- (*first) = ((rhdr->flags & RPC_FLG_FIRST) != 0);
- (*last) = ((rhdr->flags & RPC_FLG_LAST ) != 0);
- (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata);
+ if (current_pdu_len < prhdr->frag_len) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- return (rhdr->pkt_type != RPC_FAULT);
+ return NT_STATUS_OK;
}
/****************************************************************************
- Verify data on an rpc pipe.
- The VERIFY & SEAL code is only executed on packets that look like this :
+ NTLMSSP specific sign/seal.
+ Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
+ In fact I should probably abstract these into identical pieces of code... JRA.
+ ****************************************************************************/
- Request/Response PDU's look like the following...
+static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
+ prs_struct *current_pdu,
+ uint8 *p_ss_padding_len)
+{
+ RPC_HDR_AUTH auth_info;
+ uint32 save_offset = prs_offset(current_pdu);
+ uint32 auth_len = prhdr->auth_len;
+ NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state;
+ unsigned char *data = NULL;
+ size_t data_len;
+ unsigned char *full_packet_data = NULL;
+ size_t full_packet_data_len;
+ DATA_BLOB auth_blob;
+ NTSTATUS status;
+
+ if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
+ return NT_STATUS_OK;
+ }
- |<------------------PDU len----------------------------------------------->|
- |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
+ if (!ntlmssp_state) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- +------------+-----------------+-------------+---------------+-------------+
- | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
- +------------+-----------------+-------------+---------------+-------------+
+ /* Ensure there's enough data for an authenticated response. */
+ if ((auth_len > RPC_MAX_SIGN_SIZE) ||
+ (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
+ DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
+ (unsigned int)auth_len ));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- Never on bind requests/responses.
- ****************************************************************************/
+ /*
+ * We need the full packet data + length (minus auth stuff) as well as the packet data + length
+ * after the RPC header.
+ * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
+ * functions as NTLMv2 checks the rpc headers also.
+ */
+
+ data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
+ data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
+
+ full_packet_data = prs_data_p(current_pdu);
+ full_packet_data_len = prhdr->frag_len - auth_len;
+
+ /* Pull the auth header and the following data into a blob. */
+ if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
+ DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
+ (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
+ DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ auth_blob.data = prs_data_p(current_pdu) + prs_offset(current_pdu);
+ auth_blob.length = auth_len;
+
+ switch (cli->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ /* Data is encrypted. */
+ status = ntlmssp_unseal_packet(ntlmssp_state,
+ data, data_len,
+ full_packet_data,
+ full_packet_data_len,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
+ "packet from remote machine %s on pipe %s "
+ "fnum 0x%x. Error was %s.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ nt_errstr(status) ));
+ return status;
+ }
+ break;
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ /* Data is signed. */
+ status = ntlmssp_check_packet(ntlmssp_state,
+ data, data_len,
+ full_packet_data,
+ full_packet_data_len,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
+ "packet from remote machine %s on pipe %s "
+ "fnum 0x%x. Error was %s.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ nt_errstr(status) ));
+ return status;
+ }
+ break;
+ default:
+ DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n",
+ cli->auth.auth_level ));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
-static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata,
- uint32 fragment_start, int len, int auth_len, uint8 pkt_type,
- int *pauth_padding_len)
-{
-
/*
- * The following is that length of the data we must sign or seal.
- * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
- * preceeding the auth_data.
+ * Return the current pointer to the data offset.
*/
- int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
+ if(!prs_set_offset(current_pdu, save_offset)) {
+ DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
+ (unsigned int)save_offset ));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
/*
- * The start of the data to sign/seal is just after the RPC headers.
+ * Remember the padding length. We must remove it from the real data
+ * stream once the sign/seal is done.
*/
- char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
- RPC_HDR_AUTH rhdr_auth;
+ *p_ss_padding_len = auth_info.auth_pad_len;
- char *dp = prs_data_p(rdata) + fragment_start + len -
- RPC_HDR_AUTH_LEN - auth_len;
- prs_struct auth_verf;
+ return NT_STATUS_OK;
+}
- *pauth_padding_len = 0;
+/****************************************************************************
+ schannel specific sign/seal.
+ ****************************************************************************/
- if (auth_len == 0) {
- if (cli->pipe_auth_flags == 0) {
- /* move along, nothing to see here */
- return True;
- }
+static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
+ prs_struct *current_pdu,
+ uint8 *p_ss_padding_len)
+{
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_SCHANNEL_CHK schannel_chk;
+ uint32 auth_len = prhdr->auth_len;
+ uint32 save_offset = prs_offset(current_pdu);
+ struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth;
+ uint32 data_len;
+
+ if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
+ return NT_STATUS_OK;
+ }
- DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n"));
- return False;
+ if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
+ DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
+ return NT_STATUS_INVALID_PARAMETER;
}
- DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n",
- pkt_type, len, auth_len,
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN),
- BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL)));
+ if (!schannel_auth) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
- DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
- return False;
+ /* Ensure there's enough data for an authenticated response. */
+ if ((auth_len > RPC_MAX_SIGN_SIZE) ||
+ (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
+ DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
+ (unsigned int)auth_len ));
+ return NT_STATUS_INVALID_PARAMETER;
}
- DEBUG(10,("rpc_auth_pipe: packet:\n"));
- dump_data(100, dp, auth_len);
+ data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
- prs_init(&auth_verf, 0, cli->cli->mem_ctx, UNMARSHALL);
-
- /* The endinness must be preserved. JRA. */
- prs_set_endian_data( &auth_verf, rdata->bigendian_data);
-
- /* Point this new parse struct at the auth section of the main
- parse struct - rather than copying it. Avoids needing to
- free it on every error
- */
- prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */);
- prs_set_offset(&auth_verf, 0);
+ if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
+ DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
+ (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
+ DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- {
- int auth_type;
- int auth_level;
- if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
- DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n"));
- return False;
- }
+ if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
+ DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
+ auth_info.auth_type));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- /* Let the caller know how much padding at the end of the data */
- *pauth_padding_len = rhdr_auth.auth_pad_len;
-
- /* Check it's the type of reply we were expecting to decode */
+ if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
+ &schannel_chk, current_pdu, 0)) {
+ DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
- if (rhdr_auth.auth_type != auth_type) {
- DEBUG(0, ("BAD auth type %d (should be %d)\n",
- rhdr_auth.auth_type, auth_type));
- return False;
- }
-
- if (rhdr_auth.auth_level != auth_level) {
- DEBUG(0, ("BAD auth level %d (should be %d)\n",
- rhdr_auth.auth_level, auth_level));
- return False;
- }
+ if (!schannel_decode(schannel_auth,
+ cli->auth.auth_level,
+ SENDER_IS_ACCEPTOR,
+ &schannel_chk,
+ prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN,
+ data_len)) {
+ DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
+ "Connection to remote machine %s "
+ "pipe %s fnum 0x%x.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum ));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* The sequence number gets incremented on both send and receive. */
+ schannel_auth->seq_num++;
+
+ /*
+ * Return the current pointer to the data offset.
+ */
+
+ if(!prs_set_offset(current_pdu, save_offset)) {
+ DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
+ (unsigned int)save_offset ));
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
- if (pkt_type == RPC_BINDACK) {
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- /* copy the next auth_len bytes into a buffer for
- later use */
+ /*
+ * Remember the padding length. We must remove it from the real data
+ * stream once the sign/seal is done.
+ */
+
+ *p_ss_padding_len = auth_info.auth_pad_len;
- DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
- BOOL store_ok;
+ return NT_STATUS_OK;
+}
- /* save the reply away, for use a little later */
- prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
+/****************************************************************************
+ Do the authentication checks on an incoming pdu. Check sign and unseal etc.
+ ****************************************************************************/
- store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state,
- ntlmssp_verf)));
+static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
+ prs_struct *current_pdu,
+ uint8 *p_ss_padding_len)
+{
+ NTSTATUS ret = NT_STATUS_OK;
- data_blob_free(&ntlmssp_verf);
- return store_ok;
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- /* nothing to do here - we don't seem to be able to
- validate the bindack based on VL's comments */
- return True;
+ /* Paranioa checks for auth_len. */
+ if (prhdr->auth_len) {
+ if (prhdr->auth_len > prhdr->frag_len) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len ||
+ prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) {
+ /* Integer wrap attempt. */
+ return NT_STATUS_INVALID_PARAMETER;
}
}
-
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- NTSTATUS nt_status;
- DATA_BLOB sig;
- if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) ||
- (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) {
- if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) {
- DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len));
- return False;
+
+ /*
+ * Now we have a complete RPC request PDU fragment, try and verify any auth data.
+ */
+
+ switch(cli->auth.auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ if (prhdr->auth_len) {
+ DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
+ "pipe %s fnum 0x%x - got non-zero auth len %u.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ (unsigned int)prhdr->auth_len ));
+ return NT_STATUS_INVALID_PARAMETER;
}
- sig = data_blob(NULL, auth_len);
- prs_copy_data_out((char *)sig.data, &auth_verf, auth_len);
- }
-
- /*
- * Unseal any sealed data in the PDU, not including the
- * 8 byte auth_header or the auth_data.
- */
+ break;
- /*
- * Now unseal and check the auth verifier in the auth_data at
- * the end of the packet.
- */
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ break;
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
- if (data_len < 0) {
- DEBUG(1, ("Can't unseal - data_len < 0!!\n"));
- return False;
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
}
- nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state,
- (unsigned char *)reply_data, data_len,
- &sig);
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state,
- (const unsigned char *)reply_data, data_len,
- &sig);
- }
+ break;
+
+ case PIPE_AUTH_TYPE_KRB5:
+ case PIPE_AUTH_TYPE_SPNEGO_KRB5:
+ default:
+ DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s "
+ "pipe %s fnum %x - unknown internal auth type %u.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ cli->auth.auth_type ));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
- data_blob_free(&sig);
+ return NT_STATUS_OK;
+}
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("rpc_auth_pipe: could not validate "
- "incoming NTLMSSP packet!\n"));
- return False;
- }
+/****************************************************************************
+ Do basic authentication checks on an incoming pdu.
+ ****************************************************************************/
+
+static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
+ prs_struct *current_pdu,
+ uint8 expected_pkt_type,
+ char **ppdata,
+ uint32 *pdata_len,
+ prs_struct *return_data)
+{
+
+ NTSTATUS ret = NT_STATUS_OK;
+ uint32 current_pdu_len = prs_data_size(current_pdu);
+
+ if (current_pdu_len != prhdr->frag_len) {
+ DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
+ (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
+ return NT_STATUS_INVALID_PARAMETER;
}
- if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- RPC_AUTH_NETSEC_CHK chk;
+ /*
+ * Point the return values at the real data including the RPC
+ * header. Just in case the caller wants it.
+ */
+ *ppdata = prs_data_p(current_pdu);
+ *pdata_len = current_pdu_len;
- if ( (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN)
- && (auth_len != RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN) )
- {
- DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
- return False;
- }
+ /* Ensure we have the correct type. */
+ switch (prhdr->pkt_type) {
+ case RPC_ALTCONTRESP:
+ case RPC_BINDACK:
+
+ /* Alter context and bind ack share the same packet definitions. */
+ break;
- /* can't seal with no nonce */
- if ( (cli->pipe_auth_flags & AUTH_PIPE_SEAL)
- && (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) )
+
+ case RPC_RESPONSE:
{
- DEBUG(0,("rpc_auth_pipe: sealing not supported with schannel auth len %d\n", auth_len));
- return False;
+ RPC_HDR_RESP rhdr_resp;
+ uint8 ss_padding_len = 0;
+
+ if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
+ DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Here's where we deal with incoming sign/seal. */
+ ret = cli_pipe_validate_rpc_response(cli, prhdr,
+ current_pdu, &ss_padding_len);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+
+ /* Point the return values at the NDR data. Remember to remove any ss padding. */
+ *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
+
+ if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
+
+ /* Remember to remove the auth footer. */
+ if (prhdr->auth_len) {
+ /* We've already done integer wrap tests on auth_len in
+ cli_pipe_validate_rpc_response(). */
+ if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
+ }
+
+ DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
+ current_pdu_len, *pdata_len, ss_padding_len ));
+
+ /*
+ * If this is the first reply, and the allocation hint is reasonably, try and
+ * set up the return_data parse_struct to the correct size.
+ */
+
+ if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
+ if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
+ DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
+ "too large to allocate\n",
+ (unsigned int)rhdr_resp.alloc_hint ));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ break;
}
-
- if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", auth_len, &chk, &auth_verf, 0))
+ case RPC_BINDNACK:
+ DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s "
+ "pipe %s fnum 0x%x!\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+ /* Use this for now... */
+ return NT_STATUS_NETWORK_ACCESS_DENIED;
+
+ case RPC_FAULT:
{
- DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
- "RPC_AUTH_NETSECK_CHK failed\n"));
- return False;
- }
+ RPC_HDR_RESP rhdr_resp;
+ RPC_HDR_FAULT fault_resp;
+
+ if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
+ DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- if (!netsec_decode(&cli->auth_info,
- cli->pipe_auth_flags,
- SENDER_IS_ACCEPTOR,
- &chk, reply_data, data_len)) {
- DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
- return False;
+ if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
+ DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s "
+ "pipe %s fnum 0x%x!\n",
+ nt_errstr(fault_resp.status),
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+ if (NT_STATUS_IS_OK(fault_resp.status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ return fault_resp.status;
+ }
+
}
- cli->auth_info.seq_num++;
+ default:
+ DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
+ "from remote machine %s pipe %s fnum 0x%x!\n",
+ (unsigned int)prhdr->pkt_type,
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ if (prhdr->pkt_type != expected_pkt_type) {
+ DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s "
+ "pipe %s fnum %x got an unexpected RPC packet "
+ "type - %u, not %u\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ prhdr->pkt_type,
+ expected_pkt_type));
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- return True;
+
+ /* Do this just before return - we don't want to modify any rpc header
+ data before now as we may have needed to do cryptographic actions on
+ it before. */
+
+ if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) {
+ DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
+ "setting fragment first/last ON.\n"));
+ prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST;
+ }
+
+ return NT_STATUS_OK;
}
+/****************************************************************************
+ Ensure we eat the just processed pdu from the current_pdu prs_struct.
+ Normally the frag_len and buffer size will match, but on the first trans
+ reply there is a theoretical chance that buffer size > frag_len, so we must
+ deal with that.
+ ****************************************************************************/
+
+static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
+{
+ uint32 current_pdu_len = prs_data_size(current_pdu);
+
+ if (current_pdu_len < prhdr->frag_len) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Common case. */
+ if (current_pdu_len == (uint32)prhdr->frag_len) {
+ prs_mem_free(current_pdu);
+ prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL);
+ /* Make current_pdu dynamic with no memory. */
+ prs_give_memory(current_pdu, 0, 0, True);
+ return NT_STATUS_OK;
+ }
+
+ /*
+ * Oh no ! More data in buffer than we processed in current pdu.
+ * Cheat. Move the data down and shrink the buffer.
+ */
+
+ memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
+ current_pdu_len - prhdr->frag_len);
+
+ /* Remember to set the read offset back to zero. */
+ prs_set_offset(current_pdu, 0);
+
+ /* Shrink the buffer. */
+ if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ return NT_STATUS_OK;
+}
/****************************************************************************
- Send data on an rpc pipe via trans, which *must* be the last fragment.
- receive response data from an rpc pipe, which may be large...
+ Send data on an rpc pipe via trans. The prs_struct data must be the last
+ pdu fragment of an NDR data stream.
+
+ Receive response data from an rpc pipe, which may be large...
Read the first fragment: unfortunately have to use SMBtrans for the first
bit, then SMBreadX for subsequent bits.
@@ -391,41 +730,50 @@ static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata,
| RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
+------------+-----------------+-------------+---------------+-------------+
- Where the presence of the AUTH_HDR and AUTH are dependent on the
+ Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
signing & sealing being negotiated.
****************************************************************************/
-static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_struct *rdata,
- uint8 expected_pkt_type)
+static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli,
+ prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */
+ prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */
+ uint8 expected_pkt_type)
{
- uint32 len;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
char *rparam = NULL;
uint32 rparam_len = 0;
uint16 setup[2];
- BOOL first = True;
- BOOL last = True;
- RPC_HDR rhdr;
char *pdata = data ? prs_data_p(data) : NULL;
uint32 data_len = data ? prs_offset(data) : 0;
char *prdata = NULL;
uint32 rdata_len = 0;
- uint32 current_offset = 0;
- uint32 fragment_start = 0;
uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024;
- int auth_padding_len = 0;
+ uint32 current_rbuf_offset = 0;
+ prs_struct current_pdu;
+
+#ifdef DEVELOPER
+ /* Ensure we're not sending too much. */
+ SMB_ASSERT(data_len <= max_data);
+#endif
- /* Create setup parameters - must be in native byte order. */
+ /* Set up the current pdu parse struct. */
+ prs_init(&current_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL);
+ /* Create setup parameters - must be in native byte order. */
setup[0] = TRANSACT_DCERPCCMD;
setup[1] = cli->fnum; /* Pipe file handle. */
- DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->fnum));
+ DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum ));
- /* Send the RPC request and receive a response. For short RPC
- calls (about 1024 bytes or so) the RPC request and response
- appears in a SMBtrans request and response. Larger RPC
- responses are received further on. */
+ /*
+ * Send the last (or only) fragment of an RPC request. For small
+ * amounts of data (about 1024 bytes or so) the RPC request and response
+ * appears in a SMBtrans request and response.
+ */
if (!cli_api_pipe(cli->cli, "\\PIPE\\",
setup, 2, 0, /* Setup, length, max */
@@ -434,9 +782,14 @@ static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_stru
&rparam, &rparam_len, /* return params, len */
&prdata, &rdata_len)) /* return data, len */
{
- DEBUG(0, ("cli_pipe: return critical error. Error was %s\n",
- cli_errstr(cli->cli)));
- return False;
+ DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x"
+ "returned critical error. Error was %s\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ cli_errstr(cli->cli)));
+ ret = cli_get_nt_error(cli->cli);
+ goto err;
}
/* Throw away returned params - we know we won't use them. */
@@ -444,327 +797,343 @@ static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_stru
SAFE_FREE(rparam);
if (prdata == NULL) {
- DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n",
- (int)cli->fnum));
- return False;
+ DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s "
+ "fnum 0x%x failed to return data.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+ /* Yes - some calls can truely return no data... */
+ prs_mem_free(&current_pdu);
+ return NT_STATUS_OK;
}
/*
- * Give this memory as dynamically allocated to the return parse
- * struct.
+ * Give this memory as dynamic to the current pdu.
*/
- prs_give_memory(rdata, prdata, rdata_len, True);
- current_offset = rdata_len;
+ prs_give_memory(&current_pdu, prdata, rdata_len, True);
- /* This next call sets the endian bit correctly in rdata. */
+ /* Ensure we can mess with the return prs_struct. */
+ SMB_ASSERT(UNMARSHALLING(rbuf));
+ SMB_ASSERT(prs_data_size(rbuf) == 0);
- if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
- prs_mem_free(rdata);
- return False;
- }
+ /* Make rbuf dynamic with no memory. */
+ prs_give_memory(rbuf, 0, 0, True);
- if (rhdr.pkt_type == RPC_BINDACK) {
- if (!last && !first) {
- DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n"));
- first = True;
- last = True;
- }
- }
+ while(1) {
+ RPC_HDR rhdr;
+ char *ret_data;
+ uint32 ret_data_len;
- if (rhdr.pkt_type == RPC_BINDNACK) {
- DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->fnum));
- prs_mem_free(rdata);
- return False;
- }
-
- if (rhdr.pkt_type == RPC_RESPONSE) {
- RPC_HDR_RESP rhdr_resp;
- if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
- DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n"));
- prs_mem_free(rdata);
- return False;
+ /* Ensure we have enough data for a pdu. */
+ ret = cli_pipe_get_current_pdu(cli, &rhdr, &current_pdu);
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto err;
}
- }
- if (rhdr.pkt_type != expected_pkt_type) {
- DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet "
- "type - %d, not %d\n", (int)cli->fnum,
- rhdr.pkt_type, expected_pkt_type));
- prs_mem_free(rdata);
- return False;
- }
+ /* We pass in rbuf here so if the alloc hint is set correctly
+ we can set the output size and avoid reallocs. */
- DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
- (unsigned int)len, (unsigned int)rdata_len ));
+ ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
+ &ret_data, &ret_data_len, rbuf);
- /* check if data to be sent back was too large for one SMBtrans */
- /* err status is only informational: the _real_ check is on the
- length */
+ DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
+ prs_data_size(&current_pdu), current_rbuf_offset ));
- if (len > 0) {
- /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto err;
+ }
- /* Read the remaining part of the first response fragment */
+ if ((rhdr.flags & RPC_FLG_FIRST)) {
+ if (rhdr.pack_type[0] == 0) {
+ /* Set the data type correctly for big-endian data on the first packet. */
+ DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x "
+ "PDU data format is big-endian.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+
+ prs_set_endian_data(rbuf, RPC_BIG_ENDIAN);
+ } else {
+ /* Check endianness on subsequent packets. */
+ if (current_pdu.bigendian_data != rbuf->bigendian_data) {
+ DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
+ rbuf->bigendian_data ? "big" : "little",
+ current_pdu.bigendian_data ? "big" : "little" ));
+ ret = NT_STATUS_INVALID_PARAMETER;
+ goto err;
+ }
+ }
+ }
+
+ /* Now copy the data portion out of the pdu into rbuf. */
+ if (!prs_force_grow(rbuf, ret_data_len)) {
+ ret = NT_STATUS_NO_MEMORY;
+ goto err;
+ }
+ memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len);
+ current_rbuf_offset += ret_data_len;
+
+ /* See if we've finished with all the data in current_pdu yet ? */
+ ret = cli_pipe_reset_current_pdu(cli, &rhdr, &current_pdu);
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto err;
+ }
- if (!rpc_read(cli, rdata, len, &current_offset)) {
- prs_mem_free(rdata);
- return False;
+ if (rhdr.flags & RPC_FLG_LAST) {
+ break; /* We're done. */
}
}
- /*
- * Now we have a complete PDU, check the auth struct if any was sent.
- */
+ DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum,
+ (unsigned int)prs_data_size(rbuf) ));
- if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
- rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
- prs_mem_free(rdata);
- return False;
- }
+ prs_mem_free(&current_pdu);
+ return NT_STATUS_OK;
- if (rhdr.auth_len != 0) {
- /*
- * Drop the auth footers from the current offset.
- * We need this if there are more fragments.
- * The auth footers consist of the auth_data and the
- * preceeding 8 byte auth_header.
- */
- current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
- }
-
- /*
- * Only one rpc fragment, and it has been read.
- */
+ err:
- if (first && last) {
- DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
- return True;
- }
+ prs_mem_free(&current_pdu);
+ prs_mem_free(rbuf);
+ return ret;
+}
- /*
- * Read more fragments using SMBreadX until we get one with the
- * last bit set.
- */
+/*******************************************************************
+ Creates krb5 auth bind.
+ ********************************************************************/
- while (!last) {
- RPC_HDR_RESP rhdr_resp;
- int num_read;
- char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN];
- prs_struct hps;
- uint8 eclass;
- uint32 ecode;
-
- /*
- * First read the header of the next PDU.
- */
+static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
+ enum pipe_auth_level auth_level,
+ RPC_HDR_AUTH *pauth_out,
+ prs_struct *auth_data)
+{
+#ifdef HAVE_KRB5
+ int ret;
+ struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth;
+ DATA_BLOB tkt = data_blob(NULL, 0);
+ DATA_BLOB tkt_wrapped = data_blob(NULL, 0);
- prs_init(&hps, 0, cli->cli->mem_ctx, UNMARSHALL);
- prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
+ /* We may change the pad length before marshalling. */
+ init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1);
- num_read = cli_read(cli->cli, cli->fnum, hdr_data, 0,
- RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
- if (cli_is_dos_error(cli->cli)) {
- cli_dos_error(cli->cli, &eclass, &ecode);
- if (eclass != ERRDOS && ecode != ERRmoredata) {
- DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode));
- return False;
- }
- }
+ DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
+ a->service_principal ));
- DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
+ /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
- if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) {
- DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n",
- RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read ));
- return False;
- }
+ ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
+ &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED);
- /* This call sets the endianness in hps. */
+ if (ret) {
+ DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
+ "failed with %s\n",
+ a->service_principal,
+ error_message(ret) ));
- if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
- return False;
+ data_blob_free(&tkt);
+ prs_mem_free(auth_data);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /* Ensure the endianness in rdata is set correctly - must be same as hps. */
+ /* wrap that up in a nice GSS-API wrapping */
+ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
- if (hps.bigendian_data != rdata->bigendian_data) {
- DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n",
- rdata->bigendian_data ? "big" : "little",
- hps.bigendian_data ? "big" : "little" ));
- return False;
- }
+ data_blob_free(&tkt);
- if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) {
- DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n"));
- return False;
- }
+ /* Auth len in the rpc header doesn't include auth_header. */
+ if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
+ data_blob_free(&tkt_wrapped);
+ prs_mem_free(auth_data);
+ return NT_STATUS_NO_MEMORY;
+ }
- if (first) {
- DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n"));
- return False;
- }
+ DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
+ dump_data(5, (const char *)tkt_wrapped.data, tkt_wrapped.length);
- /*
- * Now read the rest of the PDU.
- */
+ data_blob_free(&tkt_wrapped);
+ return NT_STATUS_OK;
+#else
+ return NT_STATUS_INVALID_PARAMETER;
+#endif
+}
- if (!rpc_read(cli, rdata, len, &current_offset)) {
- prs_mem_free(rdata);
- return False;
- }
+/*******************************************************************
+ Creates SPNEGO NTLMSSP auth bind.
+ ********************************************************************/
- fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
+ enum pipe_auth_level auth_level,
+ RPC_HDR_AUTH *pauth_out,
+ prs_struct *auth_data)
+{
+ NTSTATUS nt_status;
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB request = data_blob(NULL, 0);
+ DATA_BLOB spnego_msg = data_blob(NULL, 0);
- /*
- * Verify any authentication footer.
- */
+ /* We may change the pad length before marshalling. */
+ init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
-
- if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len,
- rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) {
- prs_mem_free(rdata);
- return False;
- }
-
- if (rhdr.auth_len != 0 ) {
-
- /*
- * Drop the auth footers from the current offset.
- * The auth footers consist of the auth_data and the
- * preceeding 8 byte auth_header.
- * We need this if there are more fragments.
- */
- current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len);
- }
+ DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
+ nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
+ null_blob,
+ &request);
+
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ data_blob_free(&request);
+ prs_mem_free(auth_data);
+ return nt_status;
}
- return True;
-}
+ /* Wrap this in SPNEGO. */
+ spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
-/*******************************************************************
- creates a DCE/RPC bind request
+ data_blob_free(&request);
+
+ /* Auth len in the rpc header doesn't include auth_header. */
+ if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
+ data_blob_free(&spnego_msg);
+ prs_mem_free(auth_data);
+ return NT_STATUS_NO_MEMORY;
+ }
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
+ DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
+ dump_data(5, (const char *)spnego_msg.data, spnego_msg.length);
+ data_blob_free(&spnego_msg);
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Creates NTLMSSP auth bind.
********************************************************************/
-static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
- prs_struct *rpc_out,
- uint32 rpc_call_id,
- RPC_IFACE *abstract, RPC_IFACE *transfer,
- const char *my_name, const char *domain)
+static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
+ enum pipe_auth_level auth_level,
+ RPC_HDR_AUTH *pauth_out,
+ prs_struct *auth_data)
{
- RPC_HDR hdr;
- RPC_HDR_RB hdr_rb;
- RPC_HDR_AUTH hdr_auth;
- RPC_CONTEXT rpc_ctx;
- int auth_len = 0;
- int auth_type, auth_level;
- size_t saved_hdr_offset = 0;
+ NTSTATUS nt_status;
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB request = data_blob(NULL, 0);
- prs_struct auth_info;
- prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */
- prs_get_mem_context(rpc_out), MARSHALL);
-
- if (cli->pipe_auth_flags) {
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
-
- /*
- * Create the auth structs we will marshall.
- */
-
- init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1);
-
- /*
- * Now marshall the data into the temporary parse_struct.
- */
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
- }
- saved_hdr_offset = prs_offset(&auth_info);
- }
-
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
+ /* We may change the pad length before marshalling. */
+ init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1);
- NTSTATUS nt_status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB request;
+ DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
+ nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
+ null_blob,
+ &request);
- DEBUG(5, ("Processing NTLMSSP Negotiate\n"));
- nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
- null_blob,
- &request);
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ data_blob_free(&request);
+ prs_mem_free(auth_data);
+ return nt_status;
+ }
- if (!NT_STATUS_EQUAL(nt_status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- prs_mem_free(&auth_info);
- return nt_status;
- }
+ /* Auth len in the rpc header doesn't include auth_header. */
+ if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
+ data_blob_free(&request);
+ prs_mem_free(auth_data);
+ return NT_STATUS_NO_MEMORY;
+ }
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = request.length;
- prs_copy_data_in(&auth_info, (char *)request.data, request.length);
+ DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
+ dump_data(5, (const char *)request.data, request.length);
- DEBUG(5, ("NTLMSSP Negotiate:\n"));
- dump_data(5, (const char *)request.data, request.length);
+ data_blob_free(&request);
+ return NT_STATUS_OK;
+}
- data_blob_free(&request);
+/*******************************************************************
+ Creates schannel auth bind.
+ ********************************************************************/
- } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- RPC_AUTH_NETSEC_NEG netsec_neg;
+static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
+ enum pipe_auth_level auth_level,
+ RPC_HDR_AUTH *pauth_out,
+ prs_struct *auth_data)
+{
+ RPC_AUTH_SCHANNEL_NEG schannel_neg;
- /* Use lp_workgroup() if domain not specified */
+ /* We may change the pad length before marshalling. */
+ init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1);
- if (!domain || !domain[0]) {
- DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n"));
- domain = lp_workgroup();
- }
+ /* Use lp_workgroup() if domain not specified */
- init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);
+ if (!cli->domain || !cli->domain[0]) {
+ cli->domain = lp_workgroup();
+ }
- /*
- * Now marshall the data into the temporary parse_struct.
- */
+ init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname());
- if(!smb_io_rpc_auth_netsec_neg("netsec_neg",
- &netsec_neg, &auth_info, 0)) {
- DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n"));
- prs_mem_free(&auth_info);
- return NT_STATUS_NO_MEMORY;
- }
+ /*
+ * Now marshall the data into the auth parse_struct.
+ */
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = prs_offset(&auth_info) - saved_hdr_offset;
+ if(!smb_io_rpc_auth_schannel_neg("schannel_neg",
+ &schannel_neg, auth_data, 0)) {
+ DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n"));
+ prs_mem_free(auth_data);
+ return NT_STATUS_NO_MEMORY;
}
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Creates the internals of a DCE/RPC bind request or alter context PDU.
+ ********************************************************************/
+
+static NTSTATUS create_bind_or_alt_ctx_internal(uint8 pkt_type,
+ prs_struct *rpc_out,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract,
+ RPC_IFACE *transfer,
+ RPC_HDR_AUTH *phdr_auth,
+ prs_struct *pauth_info)
+{
+ RPC_HDR hdr;
+ RPC_HDR_RB hdr_rb;
+ RPC_CONTEXT rpc_ctx;
+ uint16 auth_len = prs_offset(pauth_info);
+ uint8 ss_padding_len = 0;
+ uint16 frag_len = 0;
+
/* create the RPC context. */
- init_rpc_context(&rpc_ctx, 0 /* context id */,
- abstract, transfer);
+ init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
/* create the bind request RPC_HDR_RB */
- init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
+ init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
+
+ /* Start building the frag length. */
+ frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
+
+ /* Do we need to pad ? */
+ if (auth_len) {
+ uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
+ if (data_len % 8) {
+ ss_padding_len = 8 - (data_len % 8);
+ phdr_auth->auth_pad_len = ss_padding_len;
+ }
+ frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
+ }
/* Create the request RPC_HDR */
- init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id,
- RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb) + prs_offset(&auth_info),
- auth_len);
+ init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len);
/* Marshall the RPC header */
if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n"));
- prs_mem_free(&auth_info);
+ DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
return NT_STATUS_NO_MEMORY;
}
/* Marshall the bind request data */
if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n"));
- prs_mem_free(&auth_info);
+ DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -773,363 +1142,453 @@ static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
*/
if(auth_len != 0) {
- if(!prs_append_prs_data( rpc_out, &auth_info)) {
- DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- prs_mem_free(&auth_info);
+ if (ss_padding_len) {
+ unsigned char pad[8];
+ memset(pad, '\0', 8);
+ if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
+ DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
+ DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+
+ if(!prs_append_prs_data( rpc_out, pauth_info)) {
+ DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
return NT_STATUS_NO_MEMORY;
}
}
- prs_mem_free(&auth_info);
+
return NT_STATUS_OK;
}
/*******************************************************************
- Creates a DCE/RPC bind authentication response.
- This is the packet that is sent back to the server once we
- have received a BIND-ACK, to finish the third leg of
- the authentication handshake.
+ Creates a DCE/RPC bind request.
********************************************************************/
-static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli,
- uint32 rpc_call_id,
- prs_struct *rpc_out)
+static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
+ prs_struct *rpc_out,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract, RPC_IFACE *transfer,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level)
{
- NTSTATUS nt_status;
- RPC_HDR hdr;
RPC_HDR_AUTH hdr_auth;
- RPC_HDR_AUTHA hdr_autha;
- DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0);
- DATA_BLOB ntlmssp_reply;
- int auth_type, auth_level;
-
- /* The response is picked up from the internal cache,
- where it was placed by the rpc_auth_pipe() code */
- nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
- ntlmssp_null_response,
- &ntlmssp_reply);
-
- if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- return nt_status;
- }
+ prs_struct auth_info;
+ NTSTATUS ret = NT_STATUS_OK;
- /* Create the request RPC_HDR */
- init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
- RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + ntlmssp_reply.length,
- ntlmssp_reply.length );
-
- /* Marshall it. */
- if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
- }
+ ZERO_STRUCT(hdr_auth);
+ prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
-
- /* Create the request RPC_HDR_AUTHA */
- init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0, 0x0014a0c0);
- init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, &hdr_auth);
+ switch (auth_type) {
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&auth_info);
+ return ret;
+ }
+ break;
- if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
- }
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&auth_info);
+ return ret;
+ }
+ break;
- /*
- * Append the auth data to the outgoing buffer.
- */
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&auth_info);
+ return ret;
+ }
+ break;
- if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) {
- DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_NO_MEMORY;
+ case PIPE_AUTH_TYPE_KRB5:
+ ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&auth_info);
+ return ret;
+ }
+ break;
+
+ case PIPE_AUTH_TYPE_NONE:
+ break;
+
+ default:
+ /* "Can't" happen. */
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- data_blob_free(&ntlmssp_reply);
- return NT_STATUS_OK;
-}
+ ret = create_bind_or_alt_ctx_internal(RPC_BIND,
+ rpc_out,
+ rpc_call_id,
+ abstract,
+ transfer,
+ &hdr_auth,
+ &auth_info);
+ prs_mem_free(&auth_info);
+ return ret;
+}
/*******************************************************************
- Creates a DCE/RPC request.
+ Create and add the NTLMSSP sign/seal auth header and data.
********************************************************************/
-static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len, uint8 flags, uint32 oldid, uint32 data_left)
+static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
+ RPC_HDR *phdr,
+ uint32 ss_padding_len,
+ prs_struct *outgoing_pdu)
{
- uint32 alloc_hint;
- RPC_HDR hdr;
- RPC_HDR_REQ hdr_req;
- uint32 callid = oldid ? oldid : get_rpc_call_id();
+ RPC_HDR_AUTH auth_info;
+ NTSTATUS status;
+ DATA_BLOB auth_blob = data_blob(NULL, 0);
+ uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
- DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len));
+ if (!cli->auth.a_u.ntlmssp_state) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /* create the rpc header RPC_HDR */
- init_rpc_hdr(&hdr, RPC_REQUEST, flags,
- callid, data_len, auth_len);
+ /* Init and marshall the auth header. */
+ init_rpc_hdr_auth(&auth_info,
+ map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
+ cli->auth.auth_level,
+ ss_padding_len,
+ 1 /* context id. */);
- /*
- * The alloc hint should be the amount of data, not including
- * RPC headers & footers.
- */
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
+ DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
+ data_blob_free(&auth_blob);
+ return NT_STATUS_NO_MEMORY;
+ }
- if (auth_len != 0)
- alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len;
- else
- alloc_hint = data_len - RPC_HEADER_LEN;
+ switch (cli->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ /* Data portion is encrypted. */
+ status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
+ prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+ data_and_pad_len,
+ prs_data_p(outgoing_pdu),
+ (size_t)prs_offset(outgoing_pdu),
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&auth_blob);
+ return status;
+ }
+ break;
+
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ /* Data is signed. */
+ status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
+ prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+ data_and_pad_len,
+ prs_data_p(outgoing_pdu),
+ (size_t)prs_offset(outgoing_pdu),
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&auth_blob);
+ return status;
+ }
+ break;
+
+ default:
+ /* Can't happen. */
+ smb_panic("bad auth level");
+ /* Notreached. */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Finally marshall the blob. */
+
+ if (!prs_copy_data_in(outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) {
+ DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
+ (unsigned int)NTLMSSP_SIG_SIZE));
+ data_blob_free(&auth_blob);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ data_blob_free(&auth_blob);
+ return NT_STATUS_OK;
+}
- DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
- data_len, auth_len, alloc_hint));
+/*******************************************************************
+ Create and add the schannel sign/seal auth header and data.
+ ********************************************************************/
- /* Create the rpc request RPC_HDR_REQ */
- init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
+static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
+ RPC_HDR *phdr,
+ uint32 ss_padding_len,
+ prs_struct *outgoing_pdu)
+{
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_SCHANNEL_CHK verf;
+ struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth;
+ char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
+ size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+
+ if (!sas) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /* stream-time... */
- if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0))
- return 0;
+ /* Init and marshall the auth header. */
+ init_rpc_hdr_auth(&auth_info,
+ map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
+ cli->auth.auth_level,
+ ss_padding_len,
+ 1 /* context id. */);
- if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0))
- return 0;
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
+ DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
- if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN)
- return 0;
+ switch (cli->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
+ sas->seq_num));
+
+ schannel_encode(sas,
+ cli->auth.auth_level,
+ SENDER_IS_INITIATOR,
+ &verf,
+ data_p,
+ data_and_pad_len);
+
+ sas->seq_num++;
+ break;
+
+ default:
+ /* Can't happen. */
+ smb_panic("bad auth level");
+ /* Notreached. */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- return callid;
+ /* Finally marshall the blob. */
+ smb_io_rpc_auth_schannel_chk("",
+ RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
+ &verf,
+ outgoing_pdu,
+ 0);
+
+ return NT_STATUS_OK;
}
/*******************************************************************
- Puts an auth header into an rpc request.
+ Calculate how much data we're going to send in this packet, also
+ work out any sign/seal padding length.
********************************************************************/
-static BOOL create_auth_hdr(prs_struct *outgoing_packet,
- int auth_type,
- int auth_level, int padding)
+static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
+ uint32 data_left,
+ uint16 *p_frag_len,
+ uint16 *p_auth_len,
+ uint32 *p_ss_padding)
{
- RPC_HDR_AUTH hdr_auth;
+ uint32 data_space, data_len;
+
+ switch (cli->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_NONE:
+ case PIPE_AUTH_LEVEL_CONNECT:
+ data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
+ data_len = MIN(data_space, data_left);
+ *p_ss_padding = 0;
+ *p_auth_len = 0;
+ *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
+ return data_len;
+
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ /* Treat the same for all authenticated rpc requests. */
+ switch(cli->auth.auth_type) {
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ *p_auth_len = NTLMSSP_SIG_SIZE;
+ break;
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
+ break;
+ default:
+ smb_panic("bad auth type");
+ break;
+ }
- init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level,
- padding, 1);
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth,
- outgoing_packet, 0)) {
- DEBUG(0,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n"));
- return False;
+ data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
+ RPC_HDR_AUTH_LEN - *p_auth_len;
+
+ data_len = MIN(data_space, data_left);
+ if (data_len % 8) {
+ *p_ss_padding = 8 - (data_len % 8);
+ }
+ *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
+ data_len + *p_ss_padding + /* data plus padding. */
+ RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
+ return data_len;
+
+ default:
+ smb_panic("bad auth level");
+ /* Notreached. */
+ return 0;
}
- return True;
}
-/**
- * Send a request on an RPC pipe and get a response.
- *
- * @param data NDR contents of the request to be sent.
- * @param rdata Unparsed NDR response data.
-**/
+/*******************************************************************
+ External interface.
+ Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
+ Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
+ and deals with signing/sealing details.
+ ********************************************************************/
-BOOL rpc_api_pipe_req_int(struct rpc_pipe_client *cli, uint8 op_num,
- prs_struct *data, prs_struct *rdata)
+NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
+ uint8 op_num,
+ prs_struct *in_data,
+ prs_struct *out_data)
{
- uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent;
- NTSTATUS nt_status;
- BOOL ret = False;
- uint32 callid = 0;
- fstring dump_name;
-
- auth_len = 0;
- real_auth_len = 0;
- auth_hdr_len = 0;
+ NTSTATUS ret;
+ uint32 data_left = prs_offset(in_data);
+ uint32 alloc_hint = prs_offset(in_data);
+ uint32 data_sent_thistime = 0;
+ uint32 current_data_offset = 0;
+ uint32 call_id = get_rpc_call_id();
+ char pad[8];
+ prs_struct outgoing_pdu;
+
+ memset(pad, '\0', 8);
+
+ if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
+ /* Server is screwed up ! */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
- }
- if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
- }
- auth_hdr_len = RPC_HDR_AUTH_LEN;
+ if (data_left == 0) {
+ /* Caller is screwed up ! */
+ return NT_STATUS_INVALID_PARAMETER;
}
- /*
- * calc how much actual data we can send in a PDU fragment
- */
- max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- auth_hdr_len - auth_len - 8;
-
- for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) {
- prs_struct outgoing_packet;
- prs_struct sec_blob;
- uint32 data_len, send_size;
+ prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL);
+
+ while (1) {
+ RPC_HDR hdr;
+ RPC_HDR_REQ hdr_req;
+ uint16 auth_len = 0;
+ uint16 frag_len = 0;
uint8 flags = 0;
- uint32 auth_padding = 0;
- DATA_BLOB sign_blob;
+ uint32 ss_padding = 0;
- /*
- * how much will we send this time
- */
- send_size = MIN(data_left, max_data);
+ data_sent_thistime = calculate_data_len_tosend(cli, data_left,
+ &frag_len, &auth_len, &ss_padding);
- if (!prs_init(&sec_blob, send_size, /* will need at least this much */
- cli->cli->mem_ctx, MARSHALL)) {
- DEBUG(0,("Could not malloc %u bytes",
- send_size+auth_padding));
- return False;
+ if (current_data_offset == 0) {
+ flags = RPC_FLG_FIRST;
}
- if(!prs_append_some_prs_data(&sec_blob, data,
- data_sent, send_size)) {
- DEBUG(0,("Failed to append data to netsec blob\n"));
- prs_mem_free(&sec_blob);
- return False;
+ if (data_sent_thistime == data_left) {
+ flags |= RPC_FLG_LAST;
}
- /*
- * NT expects the data that is sealed to be 8-byte
- * aligned. The padding must be encrypted as well and
- * taken into account when generating the
- * authentication verifier. The amount of padding must
- * be stored in the auth header.
- */
+ /* Create and marshall the header and request header. */
+ init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len);
- if (cli->pipe_auth_flags) {
- size_t data_and_padding_size;
- int auth_type;
- int auth_level;
- prs_align_uint64(&sec_blob);
+ if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) {
+ prs_mem_free(&outgoing_pdu);
+ return NT_STATUS_NO_MEMORY;
+ }
- get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level);
+ /* Create the rpc request RPC_HDR_REQ */
+ init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
- data_and_padding_size = prs_offset(&sec_blob);
- auth_padding = data_and_padding_size - send_size;
+ if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
+ prs_mem_free(&outgoing_pdu);
+ return NT_STATUS_NO_MEMORY;
+ }
- /* insert the auth header */
-
- if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) {
- prs_mem_free(&sec_blob);
- return False;
+ /* Copy in the data, plus any ss padding. */
+ if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) {
+ prs_mem_free(&outgoing_pdu);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Copy the sign/seal padding data. */
+ if (ss_padding) {
+ if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) {
+ prs_mem_free(&outgoing_pdu);
+ return NT_STATUS_NO_MEMORY;
}
-
- /* create an NTLMSSP signature */
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- /*
- * Seal the outgoing data if requested.
- */
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
-
- nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state,
- (unsigned char*)prs_data_p(&sec_blob),
- data_and_padding_size,
- &sign_blob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- prs_mem_free(&sec_blob);
- return False;
+ }
+
+ /* Generate any auth sign/seal and add the auth footer. */
+ if (auth_len) {
+ switch (cli->auth.auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ break;
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&outgoing_pdu);
+ return ret;
}
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-
- nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state,
- (unsigned char*)prs_data_p(&sec_blob),
- data_and_padding_size, &sign_blob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- prs_mem_free(&sec_blob);
- return False;
+ break;
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
+ if (!NT_STATUS_IS_OK(ret)) {
+ prs_mem_free(&outgoing_pdu);
+ return ret;
}
- }
-
-
- /* write auth footer onto the packet */
- real_auth_len = sign_blob.length;
-
- prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length);
- data_blob_free(&sign_blob);
-
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- size_t parse_offset_marker;
- RPC_AUTH_NETSEC_CHK verf;
- DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
-
- netsec_encode(&cli->auth_info,
- cli->pipe_auth_flags,
- SENDER_IS_INITIATOR,
- &verf,
- prs_data_p(&sec_blob),
- data_and_padding_size);
-
- cli->auth_info.seq_num++;
-
- /* write auth footer onto the packet */
-
- parse_offset_marker = prs_offset(&sec_blob);
- if (!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN,
- &verf, &sec_blob, 0))
- {
- prs_mem_free(&sec_blob);
- return False;
- }
- real_auth_len = prs_offset(&sec_blob) - parse_offset_marker;
+ break;
+ default:
+ smb_panic("bad auth type");
+ break; /* notreached */
}
}
- data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(&sec_blob);
-
- /*
- * Malloc parse struct to hold it (and enough for alignments).
- */
- if(!prs_init(&outgoing_packet, data_len + 8,
- cli->cli->mem_ctx, MARSHALL)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
- return False;
- }
+ /* Actually send the packet. */
+ if (flags & RPC_FLG_LAST) {
+ /* Last packet - send the data, get the reply and return. */
+ ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE);
+ prs_mem_free(&outgoing_pdu);
- if (data_left == prs_offset(data))
- flags |= RPC_FLG_FIRST;
+
+ if (DEBUGLEVEL >= 50) {
+ pstring dump_name;
+ /* Also capture received data */
+ slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d",
+ dyn_LOGFILEBASE, cli->pipe_name, op_num);
+ prs_dump(dump_name, op_num, out_data);
+ }
- if (data_left <= max_data)
- flags |= RPC_FLG_LAST;
- /*
- * Write out the RPC header and the request header.
- */
- if(!(callid = create_rpc_request(&outgoing_packet, op_num,
- data_len, real_auth_len, flags,
- callid, data_left))) {
- DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
- prs_mem_free(&outgoing_packet);
- prs_mem_free(&sec_blob);
- return False;
+ return ret;
+ } else {
+ /* More packets to come - write and continue. */
+ ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */
+ prs_data_p(&outgoing_pdu),
+ (off_t)0,
+ (size_t)hdr.frag_len);
+
+ if (num_written != hdr.frag_len) {
+ prs_mem_free(&outgoing_pdu);
+ return cli_get_nt_error(cli->cli);
+ }
}
- prs_append_prs_data(&outgoing_packet, &sec_blob);
- prs_mem_free(&sec_blob);
-
- DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len,
- prs_offset(&outgoing_packet)));
-
- if (flags & RPC_FLG_LAST)
- ret = rpc_api_pipe(cli, &outgoing_packet,
- rdata, RPC_RESPONSE);
- else {
- cli_write(cli->cli, cli->fnum, 0x0008,
- prs_data_p(&outgoing_packet),
- data_sent, data_len);
+ current_data_offset += data_sent_thistime;
+ data_left -= data_sent_thistime;
+
+ /* Reset the marshalling position back to zero. */
+ if (!prs_set_offset(&outgoing_pdu, 0)) {
+ prs_mem_free(&outgoing_pdu);
+ return NT_STATUS_NO_MEMORY;
}
- prs_mem_free(&outgoing_packet);
- data_sent += send_size;
- data_left -= send_size;
}
- /* Also capture received data */
- slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s",
- cli_pipe_get_name(cli->cli));
- prs_dump(dump_name, op_num, rdata);
-
- return ret;
-}
-
-BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num,
- prs_struct *data, prs_struct *rdata)
-{
- return rpc_api_pipe_req_int(&cli->pipes[pipe_idx], op_num,
- data, rdata);
}
-
-
+#if 0
/****************************************************************************
Set the handle state.
****************************************************************************/
@@ -1174,56 +1633,10 @@ static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
return state_set;
}
+#endif
/****************************************************************************
- check the rpc bind acknowledge response
-****************************************************************************/
-
-int get_pipe_index( const char *pipe_name )
-{
- int pipe_idx = 0;
-
- while (pipe_names[pipe_idx].client_pipe != NULL) {
- if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
- return pipe_idx;
- pipe_idx++;
- };
-
- return -1;
-}
-
-
-/****************************************************************************
- check the rpc bind acknowledge response
-****************************************************************************/
-
-const char* get_pipe_name_from_index( const int pipe_index )
-{
-
- if ( (pipe_index < 0) || (pipe_index >= PI_MAX_PIPES) )
- return NULL;
-
- return pipe_names[pipe_index].client_pipe;
-}
-
-/****************************************************************************
- Check to see if this pipe index points to one of
- the pipes only supported by Win2k
- ****************************************************************************/
-
-BOOL is_win2k_pipe( const int pipe_idx )
-{
- switch ( pipe_idx )
- {
- case PI_LSARPC_DS:
- return True;
- }
-
- return False;
-}
-
-/****************************************************************************
- check the rpc bind acknowledge response
+ Check the rpc bind acknowledge response.
****************************************************************************/
static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer)
@@ -1235,10 +1648,10 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *
}
DEBUG(5,("Bind Abstract Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax),
+ dump_data(5, (char*)&pipe_names[pipe_idx].abstr_syntax,
sizeof(pipe_names[pipe_idx].abstr_syntax));
DEBUG(5,("Bind Transfer Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
+ dump_data(5, (char*)&pipe_names[pipe_idx].trans_syntax,
sizeof(pipe_names[pipe_idx].trans_syntax));
/* copy the required syntaxes out so we can do the right bind */
@@ -1250,7 +1663,7 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *
}
/****************************************************************************
- check the rpc bind acknowledge response
+ Check the rpc bind acknowledge response.
****************************************************************************/
static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer)
@@ -1259,7 +1672,6 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
}
-
# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
!strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
@@ -1284,396 +1696,500 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
return False;
}
- /* lkclXXXX only accept one result: check the result(s) */
if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
hdr_ba->res.num_results, hdr_ba->res.reason));
}
- DEBUG(5,("bind_rpc_pipe: accepted!\n"));
+ DEBUG(5,("check_bind_response: accepted!\n"));
return True;
}
-/****************************************************************************
- Create and send the third packet in an RPC auth.
-****************************************************************************/
+/*******************************************************************
+ Creates a DCE/RPC bind authentication response.
+ This is the packet that is sent back to the server once we
+ have received a BIND-ACK, to finish the third leg of
+ the authentication handshake.
+ ********************************************************************/
-static BOOL rpc_send_auth_reply(struct rpc_pipe_client *cli,
- prs_struct *rdata, uint32 rpc_call_id)
+static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
+ uint32 rpc_call_id,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level,
+ DATA_BLOB *pauth_blob,
+ prs_struct *rpc_out)
{
- prs_struct rpc_out;
- ssize_t ret;
+ RPC_HDR hdr;
+ RPC_HDR_AUTH hdr_auth;
+ uint32 pad = 0;
- prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */
- cli->cli->mem_ctx, MARSHALL);
+ /* Create the request RPC_HDR */
+ init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id,
+ RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
+ pauth_blob->length );
+
+ /* Marshall it. */
+ if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
+ DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
- if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
- &rpc_out))) {
- return False;
+ /*
+ I'm puzzled about this - seems to violate the DCE RPC auth rules,
+ about padding - shouldn't this pad to length 8 ? JRA.
+ */
+
+ /* 4 bytes padding. */
+ if (!prs_uint32("pad", rpc_out, 0, &pad)) {
+ DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
+ return NT_STATUS_NO_MEMORY;
}
- if ((ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out),
- 0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
- DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
- prs_mem_free(&rpc_out);
- return False;
+ /* Create the request RPC_HDR_AUTHA */
+ init_rpc_hdr_auth(&hdr_auth,
+ map_pipe_auth_type_to_rpc_auth_type(auth_type),
+ auth_level, 0, 1);
+
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
+ DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
+ return NT_STATUS_NO_MEMORY;
}
- prs_mem_free(&rpc_out);
- return True;
+ /*
+ * Append the auth data to the outgoing buffer.
+ */
+
+ if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
+ DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
}
/****************************************************************************
- Do an rpc bind.
+ Create and send the third packet in an RPC auth.
****************************************************************************/
-static BOOL rpc_pipe_bind(struct rpc_pipe_client *cli)
+static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
+ RPC_HDR *phdr,
+ prs_struct *rbuf,
+ uint32 rpc_call_id,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level)
{
- RPC_IFACE abstract;
- RPC_IFACE transfer;
+ DATA_BLOB server_response = data_blob(NULL,0);
+ DATA_BLOB client_reply = data_blob(NULL,0);
+ RPC_HDR_AUTH hdr_auth;
+ NTSTATUS nt_status;
prs_struct rpc_out;
- prs_struct rdata;
- uint32 rpc_call_id;
- char buffer[MAX_PDU_FRAG_LEN];
+ ssize_t ret;
- if ( (cli->pipe_idx < 0) || (cli->pipe_idx >= PI_MAX_PIPES) )
- return False;
+ if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->fnum,
- pipe_names[cli->pipe_idx].client_pipe));
+ /* Process the returned NTLMSSP blob first. */
+ if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer))
- return False;
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL);
+ /* TODO - check auth_type/auth_level match. */
- /*
- * Use the MAX_PDU_FRAG_LEN buffer to store the bind request.
- */
+ server_response = data_blob(NULL, phdr->auth_len);
+ prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len);
+
+ nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
+ server_response,
+ &client_reply);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
+ return nt_status;
+ }
- prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
+ prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
- rpc_call_id = get_rpc_call_id();
+ nt_status = create_rpc_bind_auth3(cli, rpc_call_id,
+ auth_type, auth_level,
+ &client_reply, &rpc_out);
- if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
- NTSTATUS nt_status;
- fstring password;
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ prs_mem_free(&rpc_out);
+ data_blob_free(&client_reply);
+ data_blob_free(&server_response);
+ return nt_status;
+ }
- DEBUG(5, ("NTLMSSP authenticated pipe selected\n"));
+ /* 8 here is named pipe message mode. */
+ ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0,
+ (size_t)prs_offset(&rpc_out));
- nt_status = ntlmssp_client_start(&cli->ntlmssp_pipe_state);
-
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
+ if (ret != (ssize_t)prs_offset(&rpc_out)) {
+ DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret));
+ prs_mem_free(&rpc_out);
+ data_blob_free(&client_reply);
+ data_blob_free(&server_response);
+ return cli_get_nt_error(cli->cli);
+ }
- /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */
+ DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s "
+ "fnum 0x%x sent auth3 response ok.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
- cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
+ prs_mem_free(&rpc_out);
+ data_blob_free(&client_reply);
+ data_blob_free(&server_response);
+ return NT_STATUS_OK;
+}
- nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state,
- cli->user_name);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
+/*******************************************************************
+ Creates a DCE/RPC bind alter context authentication request which
+ may contain a spnego auth blobl
+ ********************************************************************/
- nt_status = ntlmssp_set_domain(cli->ntlmssp_pipe_state,
- cli->domain);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
+static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
+ RPC_IFACE *abstract,
+ RPC_IFACE *transfer,
+ enum pipe_auth_level auth_level,
+ const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
+ prs_struct *rpc_out)
+{
+ RPC_HDR_AUTH hdr_auth;
+ prs_struct auth_info;
+ NTSTATUS ret = NT_STATUS_OK;
- if (cli->pwd.null_pwd) {
- nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state,
- NULL);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
- } else {
- pwd_get_cleartext(&cli->pwd, password);
- nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state,
- password);
- if (!NT_STATUS_IS_OK(nt_status))
- return False;
- }
+ ZERO_STRUCT(hdr_auth);
+ prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL);
- if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
- cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
- }
+ /* We may change the pad length before marshalling. */
+ init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
- if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
- cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ if (pauth_blob->length) {
+ if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
+ prs_mem_free(&auth_info);
+ return NT_STATUS_NO_MEMORY;
}
- } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
- cli->auth_info.seq_num = 0;
}
- /* Marshall the outgoing data. */
- create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
- &abstract, &transfer,
- global_myname(), cli->domain);
-
- /* Initialize the incoming data struct. */
- prs_init(&rdata, 0, cli->cli->mem_ctx, UNMARSHALL);
-
- /* send data on \PIPE\. receive a response */
- if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) {
- RPC_HDR_BA hdr_ba;
-
- DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));
-
- if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0)) {
- DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
- prs_mem_free(&rdata);
- return False;
- }
+ ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT,
+ rpc_out,
+ rpc_call_id,
+ abstract,
+ transfer,
+ &hdr_auth,
+ &auth_info);
+ prs_mem_free(&auth_info);
+ return ret;
+}
- if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
- DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
- prs_mem_free(&rdata);
- return False;
- }
+/*******************************************************************
+ Third leg of the SPNEGO bind mechanism - sends alter context PDU
+ and gets a response.
+ ********************************************************************/
- cli->max_xmit_frag = hdr_ba.bba.max_tsize;
- cli->max_recv_frag = hdr_ba.bba.max_rsize;
+static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli,
+ RPC_HDR *phdr,
+ prs_struct *rbuf,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract,
+ RPC_IFACE *transfer,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level)
+{
+ DATA_BLOB server_spnego_response = data_blob(NULL,0);
+ DATA_BLOB server_ntlm_response = data_blob(NULL,0);
+ DATA_BLOB client_reply = data_blob(NULL,0);
+ DATA_BLOB tmp_blob = data_blob(NULL, 0);
+ RPC_HDR_AUTH hdr_auth;
+ NTSTATUS nt_status;
+ prs_struct rpc_out;
- /*
- * If we're doing NTLMSSP auth we need to send a reply to
- * the bind-ack to complete the 3-way challenge response
- * handshake.
- */
+ if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP)
- && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
- DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
- prs_mem_free(&rdata);
- return False;
- }
- prs_mem_free(&rdata);
- return True;
+ /* Process the returned NTLMSSP blob first. */
+ if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- return False;
-}
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
-/****************************************************************************
- Open a session.
- ****************************************************************************/
+ server_spnego_response = data_blob(NULL, phdr->auth_len);
+ prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
+
+ /* The server might give us back two challenges - tmp_blob is for the second. */
+ if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) {
+ data_blob_free(&server_spnego_response);
+ data_blob_free(&server_ntlm_response);
+ data_blob_free(&tmp_blob);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
-BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
-{
- int fnum;
- struct rpc_pipe_client *cli_pipe;
+ /* We're finished with the server spnego response and the tmp_blob. */
+ data_blob_free(&server_spnego_response);
+ data_blob_free(&tmp_blob);
- SMB_ASSERT(cli->pipes[pipe_idx].fnum == 0);
+ nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state,
+ server_ntlm_response,
+ &client_reply);
- /* The pipe index must fall within our array */
+ /* Finished with the server_ntlm response */
+ data_blob_free(&server_ntlm_response);
- SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n"));
+ data_blob_free(&client_reply);
+ return nt_status;
+ }
- if (cli->capabilities & CAP_NT_SMBS) {
- if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -1) {
- DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
- &pipe_names[pipe_idx].client_pipe[5], cli->desthost, cli_errstr(cli)));
- return False;
- }
+ /* SPNEGO wrap the client reply. */
+ tmp_blob = spnego_gen_auth(client_reply);
+ data_blob_free(&client_reply);
+ client_reply = tmp_blob;
+ tmp_blob = data_blob(NULL,0); /* Ensure it's safe to free this just in case. */
- cli->pipes[pipe_idx].fnum = (uint16)fnum;
- } else {
- if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
- DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
- pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli)));
- return False;
- }
+ /* Now prepare the alter context pdu. */
+ prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL);
- cli->pipes[pipe_idx].fnum = (uint16)fnum;
+ nt_status = create_rpc_alter_context(rpc_call_id,
+ abstract,
+ transfer,
+ auth_level,
+ &client_reply,
+ &rpc_out);
- /**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(&cli->pipes[pipe_idx], pipe_names[pipe_idx].client_pipe, 0x4300)) {
- DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
- cli_errstr(cli)));
- cli_close(cli, cli->pipes[pipe_idx].fnum);
- cli->pipes[pipe_idx].fnum = 0;
- return False;
- }
+ data_blob_free(&client_reply);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ prs_mem_free(&rpc_out);
+ return nt_status;
}
- cli_pipe = &cli->pipes[pipe_idx];
- cli_pipe->pipe_idx = pipe_idx;
- cli_pipe->cli = cli;
- cli_pipe->pipe_auth_flags = cli->pipe_auth_flags;
- memcpy(&cli_pipe->auth_info.sess_key,
- cli->sess_key, sizeof(cli->sess_key));
+ /* Initialize the returning data struct. */
+ prs_mem_free(rbuf);
+ prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
+
+ nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ prs_mem_free(&rpc_out);
+ return nt_status;
+ }
- /******************* bind request on pipe *****************/
+ prs_mem_free(&rpc_out);
- if (!rpc_pipe_bind(&cli->pipes[pipe_idx])) {
- DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n",
- get_pipe_name_from_index(pipe_idx)));
- cli_close(cli, cli->pipes[pipe_idx].fnum);
- cli->pipes[pipe_idx].fnum = 0;
- return False;
+ /* Get the auth blob from the reply. */
+ if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) {
+ DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n"));
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
- cli->pipe_idx = pipe_idx;
+ if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /*
- * Setup the remote server name prefixed by \ and the machine account name.
- */
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- fstrcpy(cli->srv_name_slash, "\\\\");
- fstrcat(cli->srv_name_slash, cli->desthost);
- strupper_m(cli->srv_name_slash);
+ server_spnego_response = data_blob(NULL, phdr->auth_len);
+ prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len);
- fstrcpy(cli->clnt_name_slash, "\\\\");
- fstrcat(cli->clnt_name_slash, global_myname());
- strupper_m(cli->clnt_name_slash);
+ /* Check we got a valid auth response. */
+ if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, &tmp_blob)) {
+ data_blob_free(&server_spnego_response);
+ data_blob_free(&tmp_blob);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- fstrcpy(cli->mach_acct, global_myname());
- fstrcat(cli->mach_acct, "$");
- strupper_m(cli->mach_acct);
+ data_blob_free(&server_spnego_response);
+ data_blob_free(&tmp_blob);
- /* Remember which pipe we're talking to */
- fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe);
+ DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
+ "remote machine %s pipe %s fnum 0x%x.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
- return True;
+ return NT_STATUS_OK;
}
-
/****************************************************************************
- Open a session to the NETLOGON pipe using schannel.
-
- (Assumes that the netlogon pipe is already open)
- ****************************************************************************/
+ Do an rpc bind.
+****************************************************************************/
-NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
- const uchar trust_password[16])
+static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level)
{
- NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
-
- cli_nt_netlogon_netsec_session_close(cli);
-
- if (lp_client_schannel() != False)
- neg_flags |= NETLOGON_NEG_SCHANNEL;
+ RPC_HDR hdr;
+ RPC_HDR_BA hdr_ba;
+ RPC_IFACE abstract;
+ RPC_IFACE transfer;
+ prs_struct rpc_out;
+ prs_struct rbuf;
+ uint32 rpc_call_id;
+ NTSTATUS status;
- result = cli_nt_setup_creds(cli, sec_chan, trust_password,
- &neg_flags, 2);
+ DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n",
+ (unsigned int)cli->fnum,
+ cli->pipe_name,
+ (unsigned int)auth_type,
+ (unsigned int)auth_level ));
- if (!NT_STATUS_IS_OK(result)) {
- cli_nt_session_close(cli);
- return result;
+ if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- if ((lp_client_schannel() == True) &&
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+ prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL);
- DEBUG(3, ("Server did not offer schannel\n"));
- cli_nt_session_close(cli);
- return NT_STATUS_UNSUCCESSFUL;
- }
+ rpc_call_id = get_rpc_call_id();
- if ((lp_client_schannel() == False) ||
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
- return NT_STATUS_OK;
-
- /* keep the existing connection to NETLOGON open */
+ /* Marshall the outgoing data. */
+ status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id,
+ &abstract, &transfer,
+ auth_type,
+ auth_level);
+ if (!NT_STATUS_IS_OK(status)) {
+ prs_mem_free(&rpc_out);
+ return status;
}
- cli->netlogon_pipe = cli->pipes[PI_NETLOGON];
- ZERO_STRUCT(cli->pipes[PI_NETLOGON]);
-
- /* Server offered schannel, so try it. */
-
- memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key,
- sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key));
-
- cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+ /* Initialize the incoming data struct. */
+ prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
- return cli_nt_session_open(cli, PI_NETLOGON) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
+ /* send data on \PIPE\. receive a response */
+ status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK);
+ if (!NT_STATUS_IS_OK(status)) {
+ prs_mem_free(&rpc_out);
+ return status;
+ }
+ prs_mem_free(&rpc_out);
-NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags,
- const uchar trust_password[16])
-{
- NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
- cli->pipe_auth_flags = 0;
+ DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s "
+ "fnum 0x%x bind request returned ok.\n",
+ cli->cli->desthost,
+ cli->pipe_name,
+ (unsigned int)cli->fnum));
+
+ /* Unmarshall the RPC header */
+ if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) {
+ DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
+ prs_mem_free(&rbuf);
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
- if (lp_client_schannel() == False) {
- return NT_STATUS_OK;
+ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) {
+ DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
+ prs_mem_free(&rbuf);
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(PI_NETLOGON)));
- return NT_STATUS_UNSUCCESSFUL;
+ if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) {
+ DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n"));
+ prs_mem_free(&rbuf);
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
- neg_flags |= NETLOGON_NEG_SCHANNEL;
+ cli->max_xmit_frag = hdr_ba.bba.max_tsize;
+ cli->max_recv_frag = hdr_ba.bba.max_rsize;
- result = cli_nt_setup_creds(cli, sec_chan, trust_password,
- &neg_flags, 2);
+ /* For authenticated binds we may need to do 3 or 4 leg binds. */
+ switch(auth_type) {
- if (!(neg_flags & NETLOGON_NEG_SCHANNEL)
- && lp_client_schannel() == True) {
- DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
- result = NT_STATUS_UNSUCCESSFUL;
- }
+ case PIPE_AUTH_TYPE_NONE:
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ /* Bind complete. */
+ break;
+
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ /* Need to send AUTH3 packet - no reply. */
+ status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id,
+ auth_type, auth_level);
+ if (!NT_STATUS_IS_OK(status)) {
+ prs_mem_free(&rbuf);
+ return status;
+ }
+ break;
+
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ /* Need to send alter context request and reply. */
+ status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id,
+ &abstract, &transfer,
+ auth_type, auth_level);
+ if (!NT_STATUS_IS_OK(status)) {
+ prs_mem_free(&rbuf);
+ return status;
+ }
+ break;
+
+ case PIPE_AUTH_TYPE_KRB5:
+ /* */
- if (!NT_STATUS_IS_OK(result)) {
- ZERO_STRUCT(cli->pipes[cli->pipe_idx].auth_info.sess_key);
- ZERO_STRUCT(cli->sess_key);
- cli->pipe_auth_flags = 0;
- cli_nt_session_close(cli);
- return result;
+ default:
+ DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
+ (unsigned int)auth_type ));
+ prs_mem_free(&rbuf);
+ return NT_STATUS_INVALID_INFO_CLASS;
}
- memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key,
- sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key));
+ /* Pipe is bound - set up auth_type and auth_level data. */
- cli_close(cli, cli->pipes[PI_NETLOGON].fnum);
- cli->pipes[PI_NETLOGON].fnum = 0;
- cli->pipe_idx = -1;
-
- /* doing schannel, not per-user auth */
- cli->pipe_auth_flags = auth_flags;
+ cli->auth.auth_type = auth_type;
+ cli->auth.auth_level = auth_level;
+ prs_mem_free(&rbuf);
return NT_STATUS_OK;
}
-const char *cli_pipe_get_name(struct cli_state *cli)
-{
- return cli->pipe_name;
-}
+/****************************************************************************
+ Open a named pipe over SMB to a remote server.
+ ****************************************************************************/
-static struct rpc_pipe_client *cli_rpc_open(struct cli_state *cli,
- int pipe_idx)
+static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
{
TALLOC_CTX *mem_ctx;
struct rpc_pipe_client *result;
int fnum;
- /* The pipe index must fall within our array */
+ *perr = NT_STATUS_NO_MEMORY;
+
+ /* The pipe name index must fall within our array */
SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES));
mem_ctx = talloc_init("struct rpc_pipe_client");
- if (mem_ctx == NULL) return NULL;
+ if (mem_ctx == NULL) {
+ return NULL;
+ }
- result = TALLOC_P(mem_ctx, struct rpc_pipe_client);
- if (result == NULL) return NULL;
+ result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
+ if (result == NULL) {
+ return NULL;
+ }
result->mem_ctx = mem_ctx;
- fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5],
- DESIRED_ACCESS_PIPE);
+ result->pipe_name = cli_get_pipe_name(pipe_idx);
+
+ fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE);
if (fnum == -1) {
- DEBUG(0,("cli_rpc_open failed on pipe %s "
+ DEBUG(0,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s "
"to machine %s. Error was %s\n",
- &pipe_names[pipe_idx].client_pipe[5], cli->desthost,
+ result->pipe_name, cli->desthost,
cli_errstr(cli)));
+ *perr = cli_get_nt_error(cli);
talloc_destroy(result->mem_ctx);
return NULL;
}
@@ -1681,91 +2197,440 @@ static struct rpc_pipe_client *cli_rpc_open(struct cli_state *cli,
result->fnum = fnum;
result->cli = cli;
result->pipe_idx = pipe_idx;
+ result->auth.auth_type = PIPE_AUTH_TYPE_NONE;
+ result->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
+
+ if (pipe_idx == PI_NETLOGON) {
+ /* Set up a netlogon credential chain for a netlogon pipe. */
+ result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo);
+ if (result->dc == NULL) {
+ talloc_destroy(result->mem_ctx);
+ return NULL;
+ }
+ }
+
+ DLIST_ADD(cli->pipe_list, result);
+ *perr = NT_STATUS_OK;
return result;
}
-struct rpc_pipe_client *cli_rpc_open_noauth(struct cli_state *cli,
- int pipe_idx)
+/****************************************************************************
+ Open a named pipe to an SMB server and bind anonymously.
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr)
{
struct rpc_pipe_client *result;
- result = cli_rpc_open(cli, pipe_idx);
- if (result == NULL) return NULL;
-
- result->max_xmit_frag = 0;
- result->pipe_auth_flags = 0;
+ result = cli_rpc_pipe_open(cli, pipe_idx, perr);
+ if (result == NULL) {
+ return NULL;
+ }
- if (!rpc_pipe_bind(result)) {
- DEBUG(0, ("rpc_pipe_bind failed\n"));
- talloc_destroy(result->mem_ctx);
+ *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ DEBUG(0, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n",
+ cli_get_pipe_name(pipe_idx), nt_errstr(*perr) ));
+ cli_rpc_pipe_close(result);
return NULL;
}
+ DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n",
+ result->pipe_name, cli->desthost ));
+
return result;
}
-struct rpc_pipe_client *cli_rpc_open_ntlmssp(struct cli_state *cli,
- int pipe_idx,
- const char *domain,
- const char *username,
- const char *password)
+/****************************************************************************
+ Free function for NTLMSSP auth.
+ ****************************************************************************/
+
+static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth)
+{
+ if (auth->a_u.ntlmssp_state) {
+ ntlmssp_end(&auth->a_u.ntlmssp_state);
+ auth->a_u.ntlmssp_state = NULL;
+ }
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
+ ****************************************************************************/
+
+static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_type auth_type,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ NTSTATUS *perr)
{
struct rpc_pipe_client *result;
+ NTLMSSP_STATE *ntlmssp_state = NULL;
- result = cli_rpc_open(cli, pipe_idx);
- if (result == NULL) return NULL;
+ result = cli_rpc_pipe_open(cli, pipe_idx, perr);
+ if (result == NULL) {
+ return NULL;
+ }
- result->max_xmit_frag = 0;
- result->pipe_auth_flags =
- AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL;
+ result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free;
+
result->domain = domain;
result->user_name = username;
pwd_set_cleartext(&result->pwd, password);
- if (!rpc_pipe_bind(result)) {
- DEBUG(0, ("cli_rpc_pipe_bind failed\n"));
- talloc_destroy(result->mem_ctx);
- return NULL;
+ *perr = ntlmssp_client_start(&ntlmssp_state);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ goto err;
+ }
+
+ result->auth.a_u.ntlmssp_state = ntlmssp_state;
+
+ *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ goto err;
+ }
+
+ *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ goto err;
+ }
+
+ if (cli->pwd.null_pwd) {
+ *perr = ntlmssp_set_password(ntlmssp_state, NULL);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ goto err;
+ }
+ } else {
+ *perr = ntlmssp_set_password(ntlmssp_state, password);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ goto err;
+ }
+ }
+
+ /* Turn off sign+seal to allow selected auth level to turn it back on. */
+ ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
+
+ if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
+ }
+
+ *perr = rpc_pipe_bind(result, auth_type, auth_level);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(*perr) ));
+ goto err;
}
+ DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and"
+ "bound NTLMSSP as user %s\\%s.\n",
+ result->pipe_name, cli->desthost,
+ domain, username ));
+
return result;
+
+ err:
+
+ cli_rpc_pipe_close(result);
+ return NULL;
}
-struct rpc_pipe_client *cli_rpc_open_schannel(struct cli_state *cli,
- int pipe_idx,
- const uchar session_key[16],
- const char *domain)
+/****************************************************************************
+ External interface.
+ Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ NTSTATUS *perr)
+{
+ return cli_rpc_pipe_open_ntlmssp_internal(cli,
+ pipe_idx,
+ PIPE_AUTH_TYPE_NTLMSSP,
+ auth_level,
+ domain,
+ username,
+ password,
+ perr);
+}
+
+/****************************************************************************
+ External interface.
+ Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const char *username,
+ const char *password,
+ NTSTATUS *perr)
+{
+ return cli_rpc_pipe_open_ntlmssp_internal(cli,
+ pipe_idx,
+ PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
+ auth_level,
+ domain,
+ username,
+ password,
+ perr);
+}
+
+/****************************************************************************
+ Open a netlogon pipe and get the schannel session key.
+ ****************************************************************************/
+
+static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
+ const char *domain,
+ NTSTATUS *perr)
+{
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ uint32 sec_chan_type = 0;
+ char machine_pwd[16];
+ fstring machine_account;
+
+ netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
+ if (!netlogon_pipe) {
+ return NULL;
+ }
+
+ /* Get the machine account credentials from secrets.tdb. */
+ if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
+ DEBUG(0, ("get_schannel_session_key: could not fetch "
+ "trust account password for domain '%s'\n",
+ domain));
+ cli_rpc_pipe_close(netlogon_pipe);
+ *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ return NULL;
+ }
+
+ if ( IS_DC ) {
+ fstrcpy( machine_account, lp_workgroup() );
+ } else {
+ /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
+ if (strequal(domain, lp_workgroup())) {
+ fstrcpy(machine_account, global_myname());
+ } else {
+ fstrcpy(machine_account, domain);
+ }
+ }
+
+ *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
+ cli->desthost,
+ domain,
+ machine_account,
+ machine_pwd,
+ sec_chan_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(*perr)) {
+ DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds "
+ "failed with result %s\n",
+ nt_errstr(*perr) ));
+ cli_rpc_pipe_close(netlogon_pipe);
+ return NULL;
+ }
+
+ if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) {
+ DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
+ cli->desthost));
+ cli_rpc_pipe_close(netlogon_pipe);
+ *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return NULL;
+ }
+
+ return netlogon_pipe;
+}
+
+/****************************************************************************
+ External interface.
+ Open a named pipe to an SMB server and bind using schannel (bind type 68)
+ using session_key. sign and seal.
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ const struct dcinfo *pdc,
+ NTSTATUS *perr)
{
struct rpc_pipe_client *result;
- result = cli_rpc_open(cli, pipe_idx);
- if (result == NULL) return NULL;
-
- result->max_xmit_frag = 0;
- result->pipe_auth_flags =
- AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
+ result = cli_rpc_pipe_open(cli, pipe_idx, perr);
+ if (result == NULL) {
+ return NULL;
+ }
+
+ result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct);
+ if (!result->auth.a_u.schannel_auth) {
+ cli_rpc_pipe_close(result);
+ *perr = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+
result->domain = domain;
- memcpy(result->auth_info.sess_key, session_key, 16);
+ memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16);
- if (!rpc_pipe_bind(result)) {
- DEBUG(0, ("cli_rpc_pipe_bind failed\n"));
- talloc_destroy(result->mem_ctx);
+ *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(*perr) ));
+ cli_rpc_pipe_close(result);
return NULL;
}
+ /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */
+ if (result->dc) {
+ *result->dc = *pdc;
+ }
+
+ DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
+ "for domain %s "
+ "and bound using schannel.\n",
+ result->pipe_name, cli->desthost, domain ));
+
return result;
}
-void cli_rpc_close(struct rpc_pipe_client *cli_pipe)
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using schannel (bind type 68).
+ Fetch the session key ourselves using a temporary netlogon pipe.
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_level auth_level,
+ const char *domain,
+ NTSTATUS *perr)
{
- if (!cli_close(cli_pipe->cli, cli_pipe->fnum))
- DEBUG(0,("cli_rpc_open failed on pipe %s "
- "to machine %s. Error was %s\n",
- &pipe_names[cli_pipe->pipe_idx].client_pipe[5],
- cli_pipe->cli->desthost,
- cli_errstr(cli_pipe->cli)));
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ struct rpc_pipe_client *result = NULL;
+
+ netlogon_pipe = get_schannel_session_key(cli, domain, perr);
+ if (!netlogon_pipe) {
+ DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
+ "key from server %s for domain %s.\n",
+ cli->desthost, domain ));
+ return NULL;
+ }
+
+ result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx,
+ auth_level,
+ domain, netlogon_pipe->dc, perr);
+
+ /* Now we've bound using the session key we can close the netlog pipe. */
+ cli_rpc_pipe_close(netlogon_pipe);
+
+ return result;
+}
+
+/****************************************************************************
+ Free function for the kerberos spcific data.
+ ****************************************************************************/
+
+static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a)
+{
+ data_blob_free(&a->a_u.kerberos_auth->session_key);
+}
+
+/****************************************************************************
+ Open a named pipe to an SMB server and bind using krb5 (bind type 16).
+ ****************************************************************************/
+
+struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli,
+ int pipe_idx,
+ enum pipe_auth_level auth_level,
+ const char *service_princ,
+ const char *username,
+ const char *password,
+ NTSTATUS *perr)
+{
+#ifdef HAVE_KRB5
+ struct rpc_pipe_client *result;
+
+ result = cli_rpc_pipe_open(cli, pipe_idx, perr);
+ if (result == NULL) {
+ return NULL;
+ }
- talloc_destroy(cli_pipe->mem_ctx);
+ /* Default service principal is "host/server@realm" */
+ if (!service_princ) {
+ service_princ = talloc_asprintf(result->mem_ctx, "host/%s@%s",
+ cli->desthost, lp_realm() );
+ if (!service_princ) {
+ cli_rpc_pipe_close(result);
+ return NULL;
+ }
+ }
+
+ /* Only get a new TGT if username/password are given. */
+ if (username && password) {
+ int ret = kerberos_kinit_password(username, password, 0, NULL, NULL);
+ if (ret) {
+ cli_rpc_pipe_close(result);
+ return NULL;
+ }
+ }
+
+ result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct);
+ if (!result->auth.a_u.kerberos_auth) {
+ cli_rpc_pipe_close(result);
+ *perr = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+
+ result->auth.a_u.kerberos_auth->service_principal = service_princ;
+ result->auth.cli_auth_data_free_func = kerberos_auth_struct_free;
+
+ *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level);
+ if (!NT_STATUS_IS_OK(*perr)) {
+ DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n",
+ nt_errstr(*perr) ));
+ cli_rpc_pipe_close(result);
+ return NULL;
+ }
+
+ return result;
+#else
+ DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
+ return NULL;
+#endif
}
+#if 0 /* Moved to libsmb/clientgen.c */
+/****************************************************************************
+ External interface.
+ Close an open named pipe over SMB. Free any authentication data.
+ ****************************************************************************/
+
+void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
+{
+ if (!cli_close(cli->cli, cli->fnum)) {
+ DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
+ "to machine %s. Error was %s\n",
+ cli->pipe_name),
+ cli->cli->desthost,
+ cli_errstr(cli->cli)));
+ }
+
+ if (cli->auth.cli_auth_data_free_func) {
+ (*cli->auth.cli_auth_data_free_func)(&cli->auth);
+ }
+ DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
+ cli->pipe_name, cli->cli->desthost ));
+
+ DLIST_REMOVE(cli->cli->pipe_list, cli);
+ talloc_destroy(cli->mem_ctx);
+}
+#endif
diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c
index 97ae8b29e7..87ab5dc9da 100644
--- a/source3/rpc_client/cli_reg.c
+++ b/source3/rpc_client/cli_reg.c
@@ -3,9 +3,7 @@
RPC Pipe client
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) Jeremy Allison 1999 - 2005
Copyright (C) Simo Sorce 2001
Copyright (C) Jeremy Cooper 2004
Copyright (C) Gerald (Jerry) Carter 2005
@@ -34,7 +32,7 @@
internal connect to a registry hive root (open a registry policy)
*******************************************************************/
-static WERROR cli_reg_open_hive_int(struct cli_state *cli,
+static WERROR rpccli_reg_open_hive_int(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, uint16 op_code,
const char *op_name,
uint32 access_mask, POLICY_HND *hnd)
@@ -48,7 +46,7 @@ static WERROR cli_reg_open_hive_int(struct cli_state *cli,
init_reg_q_open_hive(&in, access_mask);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, op_code,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, op_code,
in, out,
qbuf, rbuf,
reg_io_q_open_hive,
@@ -67,7 +65,7 @@ static WERROR cli_reg_open_hive_int(struct cli_state *cli,
connect to a registry hive root (open a registry policy)
*******************************************************************/
-WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_reg_connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 reg_type, uint32 access_mask,
POLICY_HND *reg_hnd)
{ uint16 op_code;
@@ -97,7 +95,7 @@ WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return WERR_INVALID_PARAM;
}
- return cli_reg_open_hive_int(cli, mem_ctx, op_code, op_name,
+ return rpccli_reg_open_hive_int(cli, mem_ctx, op_code, op_name,
access_mask, reg_hnd);
}
@@ -105,7 +103,7 @@ WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_reg_shutdown(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *msg, uint32 timeout, BOOL do_reboot,
BOOL force)
{
@@ -123,7 +121,7 @@ WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
init_reg_q_shutdown(&in, msg, timeout, do_reboot, force);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SHUTDOWN,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_SHUTDOWN,
in, out,
qbuf, rbuf,
reg_io_q_shutdown,
@@ -136,7 +134,7 @@ WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+WERROR rpccli_reg_abort_shutdown(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx)
{
REG_Q_ABORT_SHUTDOWN in;
REG_R_ABORT_SHUTDOWN out;
@@ -145,7 +143,7 @@ WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
ZERO_STRUCT (in);
ZERO_STRUCT (out);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ABORT_SHUTDOWN,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_ABORT_SHUTDOWN,
in, out,
qbuf, rbuf,
reg_io_q_abort_shutdown,
@@ -161,7 +159,8 @@ 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,
+
+WERROR rpccli_reg_flush_key(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd)
{
REG_Q_FLUSH_KEY in;
@@ -173,7 +172,7 @@ WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_flush_key(&in, hnd);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_FLUSH_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_FLUSH_KEY,
in, out,
qbuf, rbuf,
reg_io_q_flush_key,
@@ -186,7 +185,8 @@ WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Query Key
****************************************************************************/
-WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_query_key(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd,
char *key_class, uint32 *class_len,
uint32 *num_subkeys, uint32 *max_subkeylen,
@@ -204,7 +204,7 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_query_key( &in, hnd, key_class );
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY,
in, out,
qbuf, rbuf,
reg_io_q_query_key,
@@ -227,7 +227,7 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT (out);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY,
in, out,
qbuf, rbuf,
reg_io_q_query_key,
@@ -255,7 +255,7 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
****************************************************************************/
-WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_reg_getversion(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 *version)
{
REG_Q_GETVERSION in;
@@ -267,7 +267,7 @@ WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_getversion(&in, hnd);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GETVERSION,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_GETVERSION,
in, out,
qbuf, rbuf,
reg_io_q_getversion,
@@ -286,7 +286,8 @@ WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Query Info
****************************************************************************/
-WERROR cli_reg_query_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_query_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *val_name,
uint32 *type, REGVAL_BUFFER *buffer)
{
@@ -299,7 +300,7 @@ WERROR cli_reg_query_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_query_value(&in, hnd, val_name, buffer);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_VALUE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_QUERY_VALUE,
in, out,
qbuf, rbuf,
reg_io_q_query_value,
@@ -319,7 +320,8 @@ WERROR cli_reg_query_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Set Key Security
****************************************************************************/
-WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_set_key_sec(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 sec_info,
size_t secdesc_size, SEC_DESC *sec_desc)
{
@@ -338,7 +340,7 @@ WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_set_key_sec(&in, hnd, sec_info, sec_desc_buf);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_KEY_SEC,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_SET_KEY_SEC,
in, out,
qbuf, rbuf,
reg_io_q_set_key_sec,
@@ -353,7 +355,8 @@ WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Query Key Security
****************************************************************************/
-WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_get_key_sec(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 sec_info,
uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
{
@@ -366,7 +369,7 @@ WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_get_key_sec(&in, hnd, sec_info, *sec_buf_size, sec_buf);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GET_KEY_SEC,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_GET_KEY_SEC,
in, out,
qbuf, rbuf,
reg_io_q_get_key_sec,
@@ -388,7 +391,8 @@ WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Delete Value
****************************************************************************/
-WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_delete_val(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *val_name)
{
REG_Q_DELETE_VALUE in;
@@ -400,7 +404,7 @@ WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_delete_val(&in, hnd, val_name);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_VALUE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_DELETE_VALUE,
in, out,
qbuf, rbuf,
reg_io_q_delete_value,
@@ -413,7 +417,8 @@ WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Delete Key
****************************************************************************/
-WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_delete_key(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *key_name)
{
REG_Q_DELETE_KEY in;
@@ -425,7 +430,7 @@ WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_delete_key(&in, hnd, key_name);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_DELETE_KEY,
in, out,
qbuf, rbuf,
reg_io_q_delete_key,
@@ -438,7 +443,8 @@ WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Create Key
****************************************************************************/
-WERROR cli_reg_create_key_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_create_key_ex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *key_name, char *key_class,
uint32 access_desired, POLICY_HND *key)
{
@@ -453,8 +459,7 @@ WERROR cli_reg_create_key_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT (out);
if ( !(sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE,
- NULL, NULL, NULL, NULL, &sec_len)) )
- {
+ NULL, NULL, NULL, NULL, &sec_len)) ) {
return WERR_GENERAL_FAILURE;
}
@@ -463,7 +468,7 @@ WERROR cli_reg_create_key_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_create_key_ex(&in, hnd, key_name, key_class, access_desired, sec_buf);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY_EX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY_EX,
in, out,
qbuf, rbuf,
reg_io_q_create_key_ex,
@@ -482,7 +487,8 @@ WERROR cli_reg_create_key_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Enum Key
****************************************************************************/
-WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_enum_key(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, int key_index, fstring key_name,
fstring class_name, time_t *mod_time)
{
@@ -495,7 +501,7 @@ WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_enum_key(&in, hnd, key_index);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_ENUM_KEY,
in, out,
qbuf, rbuf,
reg_io_q_enum_key,
@@ -523,7 +529,8 @@ WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Create Value
****************************************************************************/
-WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_set_val(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *val_name, uint32 type,
RPC_DATA_BLOB *data)
{
@@ -536,7 +543,7 @@ WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_set_val(&in, hnd, val_name, type, data);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_VALUE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_SET_VALUE,
in, out,
qbuf, rbuf,
reg_io_q_set_value,
@@ -549,7 +556,8 @@ WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Enum Value
****************************************************************************/
-WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_enum_val(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, int idx,
fstring val_name, uint32 *type, REGVAL_BUFFER *value)
{
@@ -562,7 +570,7 @@ WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_enum_val(&in, hnd, idx, 0x0100, 0x1000);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE,
in, out,
qbuf, rbuf,
reg_io_q_enum_val,
@@ -577,7 +585,7 @@ WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT (out);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE,
in, out,
qbuf, rbuf,
reg_io_q_enum_val,
@@ -598,7 +606,7 @@ WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
****************************************************************************/
-WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_reg_open_entry(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *key_name,
uint32 access_desired, POLICY_HND *key_hnd)
{
@@ -611,7 +619,7 @@ WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_open_entry(&in, hnd, key_name, access_desired);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_OPEN_ENTRY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_OPEN_ENTRY,
in, out,
qbuf, rbuf,
reg_io_q_open_entry,
@@ -629,7 +637,7 @@ WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
****************************************************************************/
-WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_reg_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd)
{
REG_Q_CLOSE in;
@@ -641,7 +649,7 @@ WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_reg_q_close(&in, hnd);
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CLOSE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_CLOSE,
in, out,
qbuf, rbuf,
reg_io_q_close,
@@ -654,7 +662,8 @@ WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
do a REG Query Info
****************************************************************************/
-WERROR cli_reg_save_key( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+WERROR rpccli_reg_save_key(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *filename )
{
REG_Q_SAVE_KEY in;
@@ -666,7 +675,7 @@ WERROR cli_reg_save_key( struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_reg_save_key( &in, hnd, filename );
- CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SAVE_KEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_WINREG, REG_SAVE_KEY,
in, out,
qbuf, rbuf,
reg_io_q_save_key,
@@ -720,5 +729,3 @@ BOOL reg_split_hive(const char *full_keyname, uint32 *reg_type, pstring key_name
return True;
}
-
-
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index 01ec0bd51e..d68c72e20c 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -3,10 +3,8 @@
RPC pipe client
Copyright (C) Tim Potter 2000-2001,
Copyright (C) Andrew Tridgell 1992-1997,2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
- Copyright (C) Paul Ashton 1997,2000,
- Copyright (C) Elrond 2000,
Copyright (C) Rafal Szczesniak 2002.
+ Copyright (C) Jeremy Allison 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
@@ -40,24 +38,16 @@ NTSTATUS rpccli_samr_connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_connect(&q, cli->cli->desthost, access_mask);
- if (!samr_io_q_connect("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_CONNECT, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_connect("", &r, &rbuf, 0))
- goto done;
-
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CONNECT,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_connect,
+ samr_io_r_connect,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
@@ -67,22 +57,12 @@ NTSTATUS rpccli_samr_connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 access_mask, POLICY_HND *connect_pol)
-{
- return rpccli_samr_connect(&cli->pipes[PI_SAMR], mem_ctx,
- access_mask, connect_pol);
-}
/* Connect to SAMR database */
-NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_connect4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 access_mask, POLICY_HND *connect_pol)
{
prs_struct qbuf, rbuf;
@@ -90,28 +70,19 @@ NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CONNECT4 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
-
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
- init_samr_q_connect4(&q, cli->desthost, access_mask);
-
- if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ init_samr_q_connect4(&q, cli->cli->desthost, access_mask);
- if (!samr_io_r_connect4("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CONNECT4,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_connect4,
+ samr_io_r_connect4,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -122,10 +93,6 @@ NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -144,23 +111,16 @@ NTSTATUS rpccli_samr_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_close_hnd(&q, connect_pol);
- if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CLOSE_HND,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_close_hnd,
+ samr_io_r_close_hnd,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -171,19 +131,9 @@ NTSTATUS rpccli_samr_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
*connect_pol = r.pol;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol)
-{
- return rpccli_samr_close(&cli->pipes[PI_SAMR], mem_ctx, connect_pol);
-}
-
/* Open handle on a domain */
NTSTATUS rpccli_samr_open_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
@@ -201,23 +151,16 @@ NTSTATUS rpccli_samr_open_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
- if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_open_domain("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_OPEN_DOMAIN,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_open_domain,
+ samr_io_r_open_domain,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -228,26 +171,9 @@ NTSTATUS rpccli_samr_open_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-/* Open handle on a user */
-
-NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol, uint32 access_mask,
- const DOM_SID *domain_sid,
- POLICY_HND *domain_pol)
-{
- return rpccli_samr_open_domain(&cli->pipes[PI_SAMR], mem_ctx,
- connect_pol, access_mask, domain_sid,
- domain_pol);
-}
-
-
NTSTATUS rpccli_samr_open_user(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol, uint32 access_mask,
@@ -263,23 +189,16 @@ NTSTATUS rpccli_samr_open_user(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
- if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_open_user("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_OPEN_USER,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_open_user,
+ samr_io_r_open_user,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -290,22 +209,9 @@ NTSTATUS rpccli_samr_open_user(struct rpc_pipe_client *cli,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 user_rid, POLICY_HND *user_pol)
-{
- return rpccli_samr_open_user(&cli->pipes[PI_SAMR], mem_ctx, domain_pol,
- access_mask, user_rid, user_pol);
-}
-
-
/* Open handle on a group */
NTSTATUS rpccli_samr_open_group(struct rpc_pipe_client *cli,
@@ -323,23 +229,16 @@ NTSTATUS rpccli_samr_open_group(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
- if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_open_group("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_OPEN_GROUP,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_open_group,
+ samr_io_r_open_group,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -350,25 +249,12 @@ NTSTATUS rpccli_samr_open_group(struct rpc_pipe_client *cli,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 group_rid, POLICY_HND *group_pol)
-{
- return rpccli_samr_open_group(&cli->pipes[PI_SAMR], mem_ctx,
- domain_pol, access_mask, group_rid,
- group_pol);
-}
-
/* Create domain group */
-NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_create_dom_group(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol,
const char *group_name,
uint32 access_mask, POLICY_HND *group_pol)
@@ -383,23 +269,16 @@ NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
- if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CREATE_DOM_GROUP,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_create_dom_group,
+ samr_io_r_create_dom_group,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -408,16 +287,12 @@ NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(result))
*group_pol = r.pol;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Add a domain group member */
-NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_add_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol, uint32 rid)
{
prs_struct qbuf, rbuf;
@@ -430,38 +305,27 @@ NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_add_groupmem(&q, group_pol, rid);
- if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ADD_GROUPMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_add_groupmem,
+ samr_io_r_add_groupmem,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Delete a domain group member */
-NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_del_groupmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol, uint32 rid)
{
prs_struct qbuf, rbuf;
@@ -474,32 +338,21 @@ NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_del_groupmem(&q, group_pol, rid);
- if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DEL_GROUPMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_del_groupmem,
+ samr_io_r_del_groupmem,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -520,47 +373,28 @@ NTSTATUS rpccli_samr_query_userinfo(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_userinfo(&q, user_pol, switch_value);
- if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_userinfo,
+ samr_io_r_query_userinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
*ctr = r.ctr;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR **ctr)
-{
- return rpccli_samr_query_userinfo(&cli->pipes[PI_SAMR], mem_ctx,
- user_pol, switch_value, ctr);
-}
-
/* Set group info */
-NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_set_groupinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -573,38 +407,27 @@ NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_set_groupinfo(&q, group_pol, ctr);
- if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_GROUPINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_set_groupinfo,
+ samr_io_r_set_groupinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Query group info */
-NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_query_groupinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol, uint32 info_level,
GROUP_INFO_CTR **ctr)
{
@@ -618,23 +441,16 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_groupinfo(&q, group_pol, info_level);
- if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_GROUPINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_groupinfo,
+ samr_io_r_query_groupinfo,
+ NT_STATUS_UNSUCCESSFUL);
*ctr = r.ctr;
@@ -642,10 +458,6 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -667,23 +479,16 @@ NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_usergroups(&q, user_pol);
- if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERGROUPS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_usergroups,
+ samr_io_r_query_usergroups,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -692,24 +497,12 @@ NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
*gid = r.gid;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint32 *num_groups,
- DOM_GID **gid)
-{
- return rpccli_samr_query_usergroups(&cli->pipes[PI_SAMR], mem_ctx,
- user_pol, num_groups, gid);
-}
-
/* Set alias info */
-NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_set_aliasinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -722,32 +515,21 @@ NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
- if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_ALIASINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_set_aliasinfo,
+ samr_io_r_set_aliasinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -771,11 +553,6 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
if (sid_ptrs == NULL)
return NT_STATUS_NO_MEMORY;
@@ -787,14 +564,12 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
- if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_USERALIASES,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_useraliases,
+ samr_io_r_query_useraliases,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -803,25 +578,9 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
*als_rids = r.rid;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_query_useraliases(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- POLICY_HND *dom_pol, uint32 num_sids,
- DOM_SID2 *sid,
- uint32 *num_aliases, uint32 **als_rids)
-{
- return rpccli_samr_query_useraliases(&cli->pipes[PI_SAMR], mem_ctx,
- dom_pol, num_sids, sid,
- num_aliases, als_rids);
-}
-
-
/* Query user groups */
NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
@@ -839,23 +598,16 @@ NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_groupmem(&q, group_pol);
- if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_GROUPMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_groupmem,
+ samr_io_r_query_groupmem,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -865,22 +617,9 @@ NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
*attr = r.attr;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *group_pol, uint32 *num_mem,
- uint32 **rid, uint32 **attr)
-{
- return rpccli_samr_query_groupmem(&cli->pipes[PI_SAMR], mem_ctx,
- group_pol, num_mem, rid, attr);
-}
-
-
/**
* Enumerate domain users
*
@@ -898,7 +637,8 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*
* @return NTSTATUS returned in rpc response
**/
-NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+
+NTSTATUS rpccli_samr_enum_dom_users(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
uint32 size, char ***dom_users, uint32 **rids,
uint32 *num_dom_users)
@@ -918,25 +658,17 @@ NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* always init this */
*num_dom_users = 0;
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Fill query structure with parameters */
init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
- if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_USERS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_enum_dom_users,
+ samr_io_r_enum_dom_users,
+ NT_STATUS_UNSUCCESSFUL);
- /* unpack received stream */
-
- if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
- goto done;
-
result = r.status;
if (!NT_STATUS_IS_OK(result) &&
@@ -971,9 +703,6 @@ NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -996,23 +725,16 @@ NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
- if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_GROUPS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_enum_dom_groups,
+ samr_io_r_enum_dom_groups,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1051,22 +773,9 @@ NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_groups,
- uint32 *num_dom_groups)
-{
- return rpccli_samr_enum_dom_groups(&cli->pipes[PI_SAMR], mem_ctx,
- pol, start_idx, size, dom_groups,
- num_dom_groups);
-}
-
/* Enumerate domain groups */
NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
@@ -1086,25 +795,16 @@ NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
- if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ENUM_DOM_ALIASES,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_enum_dom_aliases,
+ samr_io_r_enum_dom_aliases,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1144,27 +844,15 @@ NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, uint32 *start_idx,
- uint32 size, struct acct_info **dom_aliases,
- uint32 *num_dom_aliases)
-{
- return rpccli_samr_enum_als_groups(&cli->pipes[PI_SAMR], mem_ctx,
- pol, start_idx, size, dom_aliases,
- num_dom_aliases);
-}
-
/* Query alias members */
-NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *alias_pol, uint32 *num_mem,
- DOM_SID **sids)
+NTSTATUS rpccli_samr_query_aliasmem(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint32 *num_mem,
+ DOM_SID **sids)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_ALIASMEM q;
@@ -1177,25 +865,16 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_aliasmem(&q, alias_pol);
- if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_ALIASMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_aliasmem,
+ samr_io_r_query_aliasmem,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1221,17 +900,15 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Open handle on an alias */
-NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 access_mask,
- uint32 alias_rid, POLICY_HND *alias_pol)
+NTSTATUS rpccli_samr_open_alias(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 alias_rid, POLICY_HND *alias_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_OPEN_ALIAS q;
@@ -1243,27 +920,16 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
- if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_OPEN_ALIAS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_open_alias,
+ samr_io_r_open_alias,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1274,16 +940,12 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
#endif
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Create an alias */
-NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_create_dom_alias(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol, const char *name,
POLICY_HND *alias_pol)
{
@@ -1297,27 +959,16 @@ NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_create_dom_alias(&q, domain_pol, name);
- if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CREATE_DOM_ALIAS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_create_dom_alias,
+ samr_io_r_create_dom_alias,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1325,16 +976,12 @@ NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*alias_pol = r.alias_pol;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Add an alias member */
-NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_add_aliasmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *alias_pol, DOM_SID *member)
{
prs_struct qbuf, rbuf;
@@ -1347,40 +994,25 @@ NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_add_aliasmem(&q, alias_pol, member);
- if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_ADD_ALIASMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_add_aliasmem,
+ samr_io_r_add_aliasmem,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Delete an alias member */
-NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_del_aliasmem(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *alias_pol, DOM_SID *member)
{
prs_struct qbuf, rbuf;
@@ -1393,40 +1025,25 @@ NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_del_aliasmem(&q, alias_pol, member);
- if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DEL_ALIASMEM,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_del_aliasmem,
+ samr_io_r_del_aliasmem,
+ NT_STATUS_UNSUCCESSFUL);
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Query alias info */
-NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_query_alias_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *alias_pol, uint16 switch_value,
ALIAS_INFO_CTR *ctr)
{
@@ -1440,25 +1057,16 @@ NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
- if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_ALIASINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_aliasinfo,
+ samr_io_r_query_aliasinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1468,9 +1076,7 @@ NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*ctr = *r.ctr;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ done:
return result;
}
@@ -1493,27 +1099,18 @@ NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_dom_info(&q, domain_pol, switch_value);
- if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
r.ctr = ctr;
- if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DOMAIN_INFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_dom_info,
+ samr_io_r_query_dom_info,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1522,20 +1119,10 @@ NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint16 switch_value,
- SAM_UNK_CTR *ctr)
-{
- return rpccli_samr_query_dom_info(&cli->pipes[PI_SAMR], mem_ctx,
- domain_pol, switch_value, ctr);
-}
-
/* User change password */
NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
@@ -1559,7 +1146,9 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
uchar new_nt_hash[16];
uchar new_lanman_hash[16];
- DEBUG(10,("cli_samr_query_dom_info\n"));
+ char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
+
+ DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1590,29 +1179,20 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
SamOEMhash( new_nt_password, old_nt_hash, 516);
E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
- init_samr_q_chgpasswd_user(&q, cli->cli->srv_name_slash, username,
+ init_samr_q_chgpasswd_user(&q, srv_name_slash, username,
new_nt_password,
old_nt_hash_enc,
new_lm_password,
old_lanman_hash_enc);
- if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_chgpasswd_user,
+ samr_io_r_chgpasswd_user,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1621,21 +1201,10 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *username,
- const char *newpassword,
- const char *oldpassword )
-{
- return rpccli_samr_chgpasswd_user(&cli->pipes[PI_SAMR], mem_ctx,
- username, newpassword, oldpassword);
-}
-
/* This function returns the bizzare set of (max_entries, max_size) required
for the QueryDisplayInfo RPC to actually work against a domain controller
with large (10k and higher) numbers of users. These values were
@@ -1689,28 +1258,19 @@ NTSTATUS rpccli_samr_query_dispinfo(struct rpc_pipe_client *cli,
*num_entries = 0;
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
*start_idx, max_entries, max_size);
- if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
r.ctr = ctr;
- if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_DISPINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_dispinfo,
+ samr_io_r_query_dispinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1725,23 +1285,9 @@ NTSTATUS rpccli_samr_query_dispinfo(struct rpc_pipe_client *cli,
*start_idx += r.num_entries; /* No next_idx in this structure! */
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 *start_idx,
- uint16 switch_value, uint32 *num_entries,
- uint32 max_entries, uint32 max_size,
- SAM_DISPINFO_CTR *ctr)
-{
- return rpccli_samr_query_dispinfo(&cli->pipes[PI_SAMR], mem_ctx,
- domain_pol, start_idx, switch_value,
- num_entries, max_entries, max_size, ctr);
-}
-
/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
looked up in one packet. */
@@ -1768,25 +1314,16 @@ NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
- if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req_int(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_RIDS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_lookup_rids,
+ samr_io_r_lookup_rids,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1815,26 +1352,13 @@ NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
-NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol,
- uint32 num_rids, uint32 *rids,
- uint32 *num_names, char ***names,
- uint32 **name_types)
-{
- return rpccli_samr_lookup_rids(&cli->pipes[PI_SAMR], mem_ctx,
- domain_pol, num_rids, rids,
- num_names, names, name_types);
-}
-
/* Lookup names */
-NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol, uint32 flags,
uint32 num_names, const char **names,
uint32 *num_rids, uint32 **rids,
@@ -1851,26 +1375,17 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
num_names, names);
- if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_NAMES,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_lookup_names,
+ samr_io_r_lookup_names,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1893,15 +1408,13 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/* Create a domain user */
-NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_create_dom_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol, const char *acct_name,
uint32 acb_info, uint32 unknown,
POLICY_HND *user_pol, uint32 *rid)
@@ -1916,25 +1429,16 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
- if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CREATE_USER,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_create_user,
+ samr_io_r_create_user,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -1949,15 +1453,13 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*rid = r.user_rid;
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/* Set userinfo */
-NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_set_userinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
{
@@ -1978,7 +1480,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise parse structures */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&qbuf, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Marshall data and send request */
@@ -1988,16 +1490,12 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
ctr->info.id);
- if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_USERINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_set_userinfo,
+ samr_io_r_set_userinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -2006,15 +1504,13 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/* Set userinfo2 */
-NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_set_userinfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
{
@@ -2033,25 +1529,16 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
- if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_SET_USERINFO2,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_set_userinfo2,
+ samr_io_r_set_userinfo2,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -2060,15 +1547,13 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
/* Delete domain group */
-NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_delete_dom_group(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol)
{
prs_struct qbuf, rbuf;
@@ -2081,40 +1566,27 @@ NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_delete_dom_group(&q, group_pol);
- if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DELETE_DOM_GROUP,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_delete_dom_group,
+ samr_io_r_delete_dom_group,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Delete domain alias */
-NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_delete_dom_alias(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *alias_pol)
{
prs_struct qbuf, rbuf;
@@ -2127,40 +1599,27 @@ NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_delete_dom_alias(&q, alias_pol);
- if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DELETE_DOM_ALIAS,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_delete_dom_alias,
+ samr_io_r_delete_dom_alias,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Delete domain user */
-NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_delete_dom_user(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol)
{
prs_struct qbuf, rbuf;
@@ -2173,40 +1632,27 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_delete_dom_user(&q, user_pol);
- if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_DELETE_DOM_USER,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_delete_dom_user,
+ samr_io_r_delete_dom_user,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Remove foreign SID */
-NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli,
+NTSTATUS rpccli_samr_remove_sid_foreign_domain(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol,
DOM_SID *sid)
@@ -2221,40 +1667,27 @@ NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
- if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_remove_sid_foreign_domain,
+ samr_io_r_remove_sid_foreign_domain,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Query user security object */
-NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
{
@@ -2268,41 +1701,28 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_query_sec_obj(&q, user_pol, switch_value);
- if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
- goto done;
- }
-
- /* Unmarshall response */
-
- if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
- goto done;
- }
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_QUERY_SEC_OBJECT,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_query_sec_obj,
+ samr_io_r_query_sec_obj,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
result = r.status;
*sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Get domain password info */
-NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint16 *unk_0, uint16 *unk_1)
{
prs_struct qbuf, rbuf;
@@ -2315,23 +1735,16 @@ NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
- init_samr_q_get_dom_pwinfo(&q, cli->desthost);
-
- if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ init_samr_q_get_dom_pwinfo(&q, cli->cli->desthost);
- if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_GET_DOM_PWINFO,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_get_dom_pwinfo,
+ samr_io_r_get_dom_pwinfo,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -2344,16 +1757,12 @@ NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*unk_1 = r.unk_1;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Lookup Domain Name */
-NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_samr_lookup_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, char *domain_name,
DOM_SID *sid)
{
@@ -2367,23 +1776,16 @@ NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Marshall data and send request */
init_samr_q_lookup_domain(&q, user_pol, domain_name);
- if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_LOOKUP_DOMAIN,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_lookup_domain,
+ samr_io_r_lookup_domain,
+ NT_STATUS_UNSUCCESSFUL);
/* Return output parameters */
@@ -2392,9 +1794,5 @@ NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(result))
sid_copy(sid, &r.dom_sid.sid);
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
diff --git a/source3/rpc_client/cli_shutdown.c b/source3/rpc_client/cli_shutdown.c
index c342f255a9..c06586e98a 100644
--- a/source3/rpc_client/cli_shutdown.c
+++ b/source3/rpc_client/cli_shutdown.c
@@ -3,10 +3,7 @@
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) Jeremy Allison 1999,
- Copyright (C) Simo Sorce 2001,
+ Largely rewritten by Jeremy Allison (C) 2005.
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
This program is free software; you can redistribute it and/or modify
@@ -28,119 +25,95 @@
/* Shutdown a server */
-NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_shutdown_init(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *msg, uint32 timeout, BOOL do_reboot,
BOOL force)
{
prs_struct qbuf;
prs_struct rbuf;
- SHUTDOWN_Q_INIT q_s;
- SHUTDOWN_R_INIT r_s;
+ SHUTDOWN_Q_INIT q;
+ SHUTDOWN_R_INIT r;
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);
+ ZERO_STRUCT (q);
+ ZERO_STRUCT (r);
/* Marshall data and send request */
- init_shutdown_q_init(&q_s, msg, timeout, do_reboot, force);
-
- if (!shutdown_io_q_init("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_INIT, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if(shutdown_io_r_init("", &r_s, &rbuf, 0))
- result = r_s.status;
+ init_shutdown_q_init(&q, msg, timeout, do_reboot, force);
-done:
- prs_mem_free(&rbuf);
- prs_mem_free(&qbuf);
+ CLI_DO_RPC(cli, mem_ctx, PI_SHUTDOWN, SHUTDOWN_INIT,
+ q, r,
+ qbuf, rbuf,
+ shutdown_io_q_init,
+ shutdown_io_r_init,
+ NT_STATUS_UNSUCCESSFUL);
+ result = r.status;
return werror_to_ntstatus(result);
}
/* Shutdown a server */
-NTSTATUS cli_shutdown_init_ex(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_shutdown_init_ex(struct rpc_pipe_client *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;
+ SHUTDOWN_Q_INIT_EX q;
+ SHUTDOWN_R_INIT_EX r;
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);
+ ZERO_STRUCT (q);
+ ZERO_STRUCT (r);
/* Marshall data and send request */
- init_shutdown_q_init_ex(&q_s, msg, timeout, do_reboot, force, reason);
+ init_shutdown_q_init_ex(&q, 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);
+ CLI_DO_RPC(cli, mem_ctx, PI_SHUTDOWN, SHUTDOWN_INIT_EX,
+ q, r,
+ qbuf, rbuf,
+ shutdown_io_q_init_ex,
+ shutdown_io_r_init_ex,
+ NT_STATUS_UNSUCCESSFUL);
+ result = r.status;
return werror_to_ntstatus(result);
}
/* Abort a server shutdown */
-NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+NTSTATUS rpccli_shutdown_abort(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx)
{
prs_struct rbuf;
prs_struct qbuf;
- SHUTDOWN_Q_ABORT q_s;
- SHUTDOWN_R_ABORT r_s;
+ SHUTDOWN_Q_ABORT q;
+ SHUTDOWN_R_ABORT r;
WERROR result = WERR_GENERAL_FAILURE;
- ZERO_STRUCT (q_s);
- ZERO_STRUCT (r_s);
+ ZERO_STRUCT (q);
+ ZERO_STRUCT (r);
- 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_abort(&q_s);
-
- if (!shutdown_io_q_abort("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_ABORT, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (shutdown_io_r_abort("", &r_s, &rbuf, 0))
- result = r_s.status;
+ init_shutdown_q_abort(&q);
-done:
- prs_mem_free(&rbuf);
- prs_mem_free(&qbuf );
+ CLI_DO_RPC(cli, mem_ctx, PI_SHUTDOWN, SHUTDOWN_ABORT,
+ q, r,
+ qbuf, rbuf,
+ shutdown_io_q_abort,
+ shutdown_io_r_abort,
+ NT_STATUS_UNSUCCESSFUL);
+ result = r.status;
return werror_to_ntstatus(result);
}
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
index 271382b71f..4322bacfc8 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -5,8 +5,8 @@
Copyright (C) Gerald Carter 2001-2005,
Copyright (C) Tim Potter 2000-2002,
Copyright (C) Andrew Tridgell 1994-2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
Copyright (C) Jean-Francois Micouleau 1999-2000.
+ Copyright (C) Jeremy Allison 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
@@ -301,7 +301,7 @@ static void decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_open_printer_ex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *printername, const char *datatype, uint32 access_required,
const char *station, const char *username, POLICY_HND *pol)
{
@@ -315,7 +315,7 @@ WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_open_printer_ex( &in, printername, datatype,
access_required, station, username );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_OPENPRINTEREX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_OPENPRINTEREX,
in, out,
qbuf, rbuf,
spoolss_io_q_open_printer_ex,
@@ -330,7 +330,7 @@ WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_close_printer(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol)
{
prs_struct qbuf, rbuf;
@@ -342,7 +342,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_closeprinter( &in, pol );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_CLOSEPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_CLOSEPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_closeprinter,
@@ -355,7 +355,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
char *name, uint32 flags, uint32 level,
uint32 *num_printers, PRINTER_INFO_CTR *ctr)
{
@@ -372,7 +372,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinters,
@@ -388,7 +388,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinters,
@@ -422,7 +422,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -435,14 +435,14 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
offered = 0;
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumports( &in, server, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumports,
@@ -458,7 +458,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumports( &in, server, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPORTS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumports,
@@ -486,7 +486,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 level,
PRINTER_INFO_CTR *ctr)
{
@@ -505,7 +505,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinter,
@@ -521,7 +521,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinter,
@@ -556,7 +556,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 level,
PRINTER_INFO_CTR *ctr, uint32 command)
{
@@ -569,7 +569,7 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_setprinter,
@@ -582,7 +582,7 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
+WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 level,
const char *env, int version, PRINTER_DRIVER_CTR *ctr)
@@ -597,7 +597,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- fstrcpy(server, cli->desthost);
+ fstrcpy(server, cli->cli->desthost);
strupper_m(server);
offered = 0;
@@ -605,7 +605,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
make_spoolss_q_getprinterdriver2( &in, pol, env, level,
version, 2, &buffer, offered);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdriver2,
@@ -622,7 +622,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
make_spoolss_q_getprinterdriver2( &in, pol, env, level,
version, 2, &buffer, offered);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdriver2,
@@ -651,7 +651,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
+WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 level, const char *env,
uint32 *num_drivers,
@@ -667,7 +667,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
offered = 0;
@@ -675,7 +675,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
make_spoolss_q_enumprinterdrivers( &in, server, env, level,
&buffer, offered);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterdrivers,
@@ -692,7 +692,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
make_spoolss_q_enumprinterdrivers( &in, server, env, level,
&buffer, offered);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterdrivers,
@@ -727,7 +727,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
+WERROR rpccli_spoolss_getprinterdriverdir (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 level, char *env,
DRIVER_DIRECTORY_CTR *ctr)
@@ -742,7 +742,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
offered = 0;
@@ -750,7 +750,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
make_spoolss_q_getprinterdriverdir( &in, server, env, level,
&buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdriverdir,
@@ -767,7 +767,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
make_spoolss_q_getprinterdriverdir( &in, server, env, level,
&buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdriverdir,
@@ -786,7 +786,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
+WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, uint32 level,
PRINTER_DRIVER_CTR *ctr)
{
@@ -798,12 +798,12 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTERDRIVER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTERDRIVER,
in, out,
qbuf, rbuf,
spoolss_io_q_addprinterdriver,
@@ -816,7 +816,7 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 level, PRINTER_INFO_CTR*ctr)
{
prs_struct qbuf, rbuf;
@@ -827,8 +827,8 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(client, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname());
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(client);
strupper_m(server);
@@ -838,7 +838,7 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_addprinterex( mem_ctx, &in, server, client,
user, level, ctr);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTEREX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDPRINTEREX,
in, out,
qbuf, rbuf,
spoolss_io_q_addprinterex,
@@ -851,7 +851,7 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteprinterdriverex(struct cli_state *cli,
+WERROR rpccli_spoolss_deleteprinterdriverex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, const char *arch,
const char *driver, int version)
{
@@ -863,12 +863,12 @@ WERROR cli_spoolss_deleteprinterdriverex(struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
make_spoolss_q_deleteprinterdriverex( mem_ctx, &in, server, arch, driver, version );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVEREX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVEREX,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteprinterdriverex,
@@ -881,7 +881,7 @@ WERROR cli_spoolss_deleteprinterdriverex(struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
+WERROR rpccli_spoolss_deleteprinterdriver (struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, const char *arch,
const char *driver)
{
@@ -893,12 +893,12 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
ZERO_STRUCT(in);
ZERO_STRUCT(out);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
make_spoolss_q_deleteprinterdriver( mem_ctx, &in, server, arch, driver );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVER,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteprinterdriver,
@@ -911,7 +911,7 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
+WERROR rpccli_spoolss_getprintprocessordirectory(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
char *name, char *environment,
fstring procdir)
@@ -931,7 +931,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
make_spoolss_q_getprintprocessordirectory( &in, name,
environment, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
in, out,
qbuf, rbuf,
spoolss_io_q_getprintprocessordirectory,
@@ -948,7 +948,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
make_spoolss_q_getprintprocessordirectory( &in, name,
environment, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
in, out,
qbuf, rbuf,
spoolss_io_q_getprintprocessordirectory,
@@ -967,7 +967,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, uint32 level, FORM *form)
{
prs_struct qbuf, rbuf;
@@ -979,7 +979,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_addform( &in, handle, level, form );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDFORM,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ADDFORM,
in, out,
qbuf, rbuf,
spoolss_io_q_addform,
@@ -992,7 +992,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, uint32 level,
const char *form_name, FORM *form)
{
@@ -1005,7 +1005,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_setform( &in, handle, level, form_name, form );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETFORM,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETFORM,
in, out,
qbuf, rbuf,
spoolss_io_q_setform,
@@ -1018,7 +1018,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, const char *formname,
uint32 level, FORM_1 *form)
{
@@ -1035,7 +1035,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
in, out,
qbuf, rbuf,
spoolss_io_q_getform,
@@ -1051,7 +1051,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETFORM,
in, out,
qbuf, rbuf,
spoolss_io_q_getform,
@@ -1070,7 +1070,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_deleteform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, const char *form_name)
{
prs_struct qbuf, rbuf;
@@ -1082,7 +1082,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_deleteform( &in, handle, form_name );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEFORM,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEFORM,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteform,
@@ -1095,7 +1095,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle, int level, uint32 *num_forms,
FORM_1 **forms)
{
@@ -1112,7 +1112,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumforms,
@@ -1128,7 +1128,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMFORMS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumforms,
@@ -1149,7 +1149,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 level, uint32 firstjob,
uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
{
@@ -1167,7 +1167,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level,
&buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumjobs,
@@ -1184,7 +1184,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level,
&buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMJOBS,
in, out,
qbuf, rbuf,
spoolss_io_q_enumjobs,
@@ -1215,7 +1215,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 jobid, uint32 level,
uint32 command)
{
@@ -1228,7 +1228,7 @@ WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_setjob( &in, hnd, jobid, level, command );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETJOB,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETJOB,
in, out,
qbuf, rbuf,
spoolss_io_q_setjob,
@@ -1241,7 +1241,7 @@ WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 jobid, uint32 level,
JOB_INFO_CTR *ctr)
{
@@ -1258,7 +1258,7 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
in, out,
qbuf, rbuf,
spoolss_io_q_getjob,
@@ -1274,7 +1274,7 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcbuf_init(&buffer, offered, mem_ctx);
make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETJOB,
in, out,
qbuf, rbuf,
spoolss_io_q_getjob,
@@ -1300,7 +1300,7 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_startpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd)
{
prs_struct qbuf, rbuf;
@@ -1312,7 +1312,7 @@ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_startpageprinter( &in, hnd );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTPAGEPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTPAGEPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_startpageprinter,
@@ -1325,7 +1325,7 @@ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_endpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd)
{
prs_struct qbuf, rbuf;
@@ -1337,7 +1337,7 @@ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_endpageprinter( &in, hnd );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDPAGEPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDPAGEPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_endpageprinter,
@@ -1350,7 +1350,7 @@ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_startdocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *docname,
char *outputfile, char *datatype,
uint32 *jobid)
@@ -1366,7 +1366,7 @@ WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_startdocprinter( &in, hnd, level, docname,
outputfile, datatype );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTDOCPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_STARTDOCPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_startdocprinter,
@@ -1381,7 +1381,7 @@ WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enddocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd)
{
prs_struct qbuf, rbuf;
@@ -1393,7 +1393,7 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enddocprinter( &in, hnd );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDDOCPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENDDOCPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_enddocprinter,
@@ -1406,7 +1406,7 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *valuename,
REGISTRY_VALUE *value)
{
@@ -1421,7 +1421,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
offered = 0;
make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdata,
@@ -1436,7 +1436,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdata,
@@ -1459,7 +1459,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_getprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *keyname,
const char *valuename,
REGISTRY_VALUE *value)
@@ -1474,7 +1474,7 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdataex,
@@ -1489,7 +1489,7 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_getprinterdataex,
@@ -1512,7 +1512,7 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, REGISTRY_VALUE *value)
{
prs_struct qbuf, rbuf;
@@ -1525,7 +1525,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_setprinterdata( &in, hnd, value->valuename,
value->type, (char *)value->data_p, value->size);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATA,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATA,
in, out,
qbuf, rbuf,
spoolss_io_q_setprinterdata,
@@ -1538,7 +1538,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_setprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *keyname,
REGISTRY_VALUE *value)
{
@@ -1552,7 +1552,7 @@ WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_setprinterdataex( &in, hnd, keyname, value->valuename,
value->type, (char *)value->data_p, value->size);
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_SETPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_setprinterdataex,
@@ -1565,7 +1565,7 @@ WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 ndx,
uint32 value_offered, uint32 data_offered,
uint32 *value_needed, uint32 *data_needed,
@@ -1580,7 +1580,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATA,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATA,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterdata,
@@ -1609,7 +1609,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *keyname,
REGVAL_CTR *ctr)
{
@@ -1625,7 +1625,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
offered = 0;
make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterdataex,
@@ -1640,7 +1640,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterdataex,
@@ -1666,7 +1666,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_writeprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 data_size, char *data,
uint32 *num_written)
{
@@ -1679,7 +1679,7 @@ WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_writeprinter( &in, hnd, data_size, data );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_WRITEPRINTER,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_WRITEPRINTER,
in, out,
qbuf, rbuf,
spoolss_io_q_writeprinter,
@@ -1695,7 +1695,7 @@ WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_deleteprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *valuename)
{
prs_struct qbuf, rbuf;
@@ -1707,7 +1707,7 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_deleteprinterdata( &in, hnd, valuename );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATA,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATA,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteprinterdata,
@@ -1720,7 +1720,7 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_deleteprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *keyname,
char *valuename)
{
@@ -1733,7 +1733,7 @@ WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ct
make_spoolss_q_deleteprinterdataex( &in, hnd, keyname, valuename );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATAEX,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATAEX,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteprinterdataex,
@@ -1746,7 +1746,7 @@ WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ct
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, const char *keyname,
uint16 **keylist, uint32 *len)
{
@@ -1760,7 +1760,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterkey,
@@ -1775,7 +1775,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY,
in, out,
qbuf, rbuf,
spoolss_io_q_enumprinterkey,
@@ -1799,7 +1799,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
**********************************************************************/
-WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_deleteprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, char *keyname)
{
prs_struct qbuf, rbuf;
@@ -1811,7 +1811,7 @@ WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
make_spoolss_q_deleteprinterkey( &in, hnd, keyname );
- CLI_DO_RPC( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERKEY,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_DELETEPRINTERKEY,
in, out,
qbuf, rbuf,
spoolss_io_q_deleteprinterkey,
diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c
index d6bcc8ba9c..f8098943db 100644
--- a/source3/rpc_client/cli_spoolss_notify.c
+++ b/source3/rpc_client/cli_spoolss_notify.c
@@ -5,8 +5,8 @@
Copyright (C) Gerald Carter 2001-2002,
Copyright (C) Tim Potter 2000-2002,
Copyright (C) Andrew Tridgell 1994-2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
Copyright (C) Jean-Francois Micouleau 1999-2000.
+ Copyright (C) Jeremy Allison 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
@@ -36,7 +36,7 @@
value) and this rpc establishes a back-channel over which printer
notifications are performed. */
-WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_reply_open_printer(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *printer, uint32 printerlocal, uint32 type,
POLICY_HND *handle)
{
@@ -47,37 +47,28 @@ WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx
/* Initialise input parameters */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type);
/* Marshall data and send request */
- if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0))
- goto done;
-
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_REPLYOPENPRINTER,
+ q, r,
+ qbuf, rbuf,
+ spoolss_io_q_replyopenprinter,
+ spoolss_io_r_replyopenprinter,
+ WERR_GENERAL_FAILURE );
+
/* Return result */
memcpy(handle, &r.handle, sizeof(r.handle));
result = r.status;
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/* Close a back-channel notification connection */
-WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_reply_close_printer(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *handle)
{
prs_struct qbuf, rbuf;
@@ -87,30 +78,20 @@ WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ct
/* Initialise input parameters */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
make_spoolss_q_reply_closeprinter(&q, handle);
/* Marshall data and send request */
- if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0))
- goto done;
-
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_REPLYCLOSEPRINTER,
+ q, r,
+ qbuf, rbuf,
+ spoolss_io_q_replycloseprinter,
+ spoolss_io_r_replycloseprinter,
+ WERR_GENERAL_FAILURE );
+
/* Return result */
result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -121,7 +102,7 @@ done:
Also see cli_spolss_reply_rrpcn()
*********************************************************************/
-WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_routerreplyprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 condition, uint32 change_id)
{
prs_struct qbuf, rbuf;
@@ -131,30 +112,20 @@ WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx
/* Initialise input parameters */
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id);
/* Marshall data and send request */
- if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_ROUTERREPLYPRINTER,
+ q, r,
+ qbuf, rbuf,
+ spoolss_io_q_routerreplyprinter,
+ spoolss_io_r_routerreplyprinter,
+ WERR_GENERAL_FAILURE );
/* Return output parameters */
result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
@@ -165,7 +136,7 @@ done:
Also see cli_spoolss_routereplyprinter()
*********************************************************************/
-WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_rrpcn(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 notify_data_len,
SPOOL_NOTIFY_INFO_DATA *notify_data,
uint32 change_low, uint32 change_high)
@@ -179,11 +150,6 @@ WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
ZERO_STRUCT(notify_info);
/* Initialise input parameters */
@@ -201,14 +167,12 @@ WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
- if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RRPCN, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_RRPCN,
+ q, r,
+ qbuf, rbuf,
+ spoolss_io_q_reply_rrpcn,
+ spoolss_io_r_reply_rrpcn,
+ WERR_GENERAL_FAILURE );
if (r.unknown0 == 0x00080000)
DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
@@ -216,18 +180,13 @@ WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0));
result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
/*********************************************************************
*********************************************************************/
-WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_spoolss_rffpcnex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, uint32 flags, uint32 options,
const char *localmachine, uint32 printerlocal,
SPOOL_NOTIFY_OPTION *option)
@@ -240,11 +199,6 @@ WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
make_spoolss_q_rffpcnex(
@@ -253,20 +207,13 @@ WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
- if(!spoolss_io_q_rffpcnex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SPOOLSS, SPOOLSS_RFFPCNEX,
+ q, r,
+ qbuf, rbuf,
+ spoolss_io_q_rffpcnex,
+ spoolss_io_r_rffpcnex,
+ WERR_GENERAL_FAILURE );
result = r.status;
-
-done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c
index b2449a7903..2c71d6b18e 100644
--- a/source3/rpc_client/cli_srvsvc.c
+++ b/source3/rpc_client/cli_srvsvc.c
@@ -2,10 +2,10 @@
Unix SMB/CIFS implementation.
NT Domain Authentication SMB / MSRPC client
Copyright (C) Andrew Tridgell 1994-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
-
+ Copyright (C) Jeremy Allison 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
@@ -23,7 +23,7 @@
#include "includes.h"
-WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli,
+WERROR rpccli_srvsvc_net_srv_get_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32 switch_value, SRV_INFO_CTR *ctr)
{
@@ -31,42 +31,33 @@ WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli,
SRV_Q_NET_SRV_GET_INFO q;
SRV_R_NET_SRV_GET_INFO r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
+ init_srv_q_net_srv_get_info(&q, server, switch_value);
r.ctr = ctr;
- if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
+ /* Marshall data and send request */
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SRV_GET_INFO,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_srv_get_info,
+ srv_io_r_net_srv_get_info,
+ WERR_GENERAL_FAILURE);
+ result = r.status;
return result;
}
-WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
int preferred_len, ENUM_HND *hnd)
{
@@ -74,31 +65,27 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SRV_Q_NET_SHARE_ENUM q;
SRV_R_NET_SHARE_ENUM r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_share_enum(
- &q, cli->srv_name_slash, info_level, preferred_len, hnd);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- /* Marshall data and send request */
+ init_srv_q_net_share_enum(&q, server, info_level, preferred_len, hnd);
- if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
- goto done;
+ /* Marshall data and send request */
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_enum("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_ENUM_ALL,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_share_enum,
+ srv_io_r_net_share_enum,
+ WERR_GENERAL_FAILURE);
result = r.status;
@@ -215,14 +202,13 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
break;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+
+ done:
return result;
}
-WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
+WERROR rpccli_srvsvc_net_share_get_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *sharename,
uint32 info_level,
@@ -232,30 +218,26 @@ WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
SRV_Q_NET_SHARE_GET_INFO q;
SRV_R_NET_SHARE_GET_INFO r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_share_get_info(&q, cli->srv_name_slash, sharename,
- info_level);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- /* Marshall data and send request */
+ init_srv_q_net_share_get_info(&q, server, sharename, info_level);
- if (!srv_io_q_net_share_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_GET_INFO, &qbuf, &rbuf))
- goto done;
+ /* Marshall data and send request */
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_get_info("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_GET_INFO,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_share_get_info,
+ srv_io_r_net_share_get_info,
+ WERR_GENERAL_FAILURE);
result = r.status;
@@ -363,14 +345,12 @@ WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
break;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ done:
return result;
}
-WERROR cli_srvsvc_net_share_set_info(struct cli_state *cli,
+WERROR rpccli_srvsvc_net_share_set_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *sharename,
uint32 info_level,
@@ -380,84 +360,64 @@ WERROR cli_srvsvc_net_share_set_info(struct cli_state *cli,
SRV_Q_NET_SHARE_SET_INFO q;
SRV_R_NET_SHARE_SET_INFO r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_share_set_info(&q, cli->srv_name_slash, sharename,
- info_level, info);
-
- /* Marshall data and send request */
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- if (!srv_io_q_net_share_set_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_SET_INFO, &qbuf, &rbuf))
- goto done;
+ init_srv_q_net_share_set_info(&q, server, sharename, info_level, info);
- /* Unmarshall response */
+ /* Marshall data and send request */
- if (!srv_io_r_net_share_set_info("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_SET_INFO,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_share_set_info,
+ srv_io_r_net_share_set_info,
+ WERR_GENERAL_FAILURE);
result = r.status;
-
- if (!W_ERROR_IS_OK(result))
- goto done;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_share_del(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *sharename)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_SHARE_DEL q;
SRV_R_NET_SHARE_DEL r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- /* Marshall data and send request */
+ init_srv_q_net_share_del(&q, server, sharename);
- if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ /* Marshall data and send request */
- if (!srv_io_r_net_share_del("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_DEL,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_share_del,
+ srv_io_r_net_share_del,
+ WERR_GENERAL_FAILURE);
result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_share_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *netname, uint32 type,
const char *remark, uint32 perms,
uint32 max_uses, uint32 num_uses,
@@ -468,85 +428,65 @@ WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SRV_Q_NET_SHARE_ADD q;
SRV_R_NET_SHARE_ADD r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
- init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark,
+ init_srv_q_net_share_add(&q,server, netname, type, remark,
perms, max_uses, num_uses, path, passwd,
level, sd);
/* Marshall data and send request */
- if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_share_add("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_ADD,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_share_add,
+ srv_io_r_net_share_add,
+ WERR_GENERAL_FAILURE);
result = r.status;
-
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
return result;
}
-WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
char *server, TIME_OF_DAY_INFO *tod)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_REMOTE_TOD q;
SRV_R_NET_REMOTE_TOD r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server_slash;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_remote_tod(&q, cli->srv_name_slash);
-
- /* Marshall data and send request */
-
- if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
+ slprintf(server_slash, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server_slash);
+ init_srv_q_net_remote_tod(&q, server_slash);
r.tod = tod;
- if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0))
- goto done;
-
- result = r.status;
-
- if (!W_ERROR_IS_OK(result))
- goto done;
+ /* Marshall data and send request */
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_REMOTE_TOD,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_remote_tod,
+ srv_io_r_net_remote_tod,
+ WERR_GENERAL_FAILURE);
+ result = r.status;
return result;
}
-WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_file_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 file_level, const char *user_name,
SRV_FILE_INFO_CTR *ctr, int preferred_len,
ENUM_HND *hnd)
@@ -555,31 +495,28 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SRV_Q_NET_FILE_ENUM q;
SRV_R_NET_FILE_ENUM r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name,
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
+
+ init_srv_q_net_file_enum(&q, server, NULL, user_name,
file_level, ctr, preferred_len, hnd);
/* Marshall data and send request */
- if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
- goto done;
-
- /* Unmarshall response */
-
- if (!srv_io_r_net_file_enum("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_ENUM,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_file_enum,
+ srv_io_r_net_file_enum,
+ WERR_GENERAL_FAILURE);
result = r.status;
@@ -625,47 +562,38 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
break;
}
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
-
+ done:
return result;
}
-WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_srvsvc_net_file_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 file_id)
{
prs_struct qbuf, rbuf;
SRV_Q_NET_FILE_CLOSE q;
SRV_R_NET_FILE_CLOSE r;
WERROR result = W_ERROR(ERRgeneral);
+ fstring server;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
- /* Initialise parse structures */
-
- prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
/* Initialise input parameters */
- init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
+ strupper_m(server);
- /* Marshall data and send request */
-
- if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
- goto done;
+ init_srv_q_net_file_close(&q, server, file_id);
- /* Unmarshall response */
+ /* Marshall data and send request */
- if (!srv_io_r_net_file_close("", &r, &rbuf, 0))
- goto done;
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_CLOSE,
+ q, r,
+ qbuf, rbuf,
+ srv_io_q_net_file_close,
+ srv_io_r_net_file_close,
+ WERR_GENERAL_FAILURE);
result = r.status;
- done:
- prs_mem_free(&qbuf);
- prs_mem_free(&rbuf);
return result;
}
diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c
index 9f80bb79a3..2df27c2da5 100644
--- a/source3/rpc_client/cli_svcctl.c
+++ b/source3/rpc_client/cli_svcctl.c
@@ -61,7 +61,7 @@ const char* svc_status_string( uint32 state )
/********************************************************************
********************************************************************/
-WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_open_scm(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, uint32 access_desired )
{
SVCCTL_Q_OPEN_SCMANAGER in;
@@ -80,12 +80,12 @@ WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx,
if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) )
return WERR_NOMEM;
- fstr_sprintf( server, "\\\\%s", cli->desthost );
+ fstr_sprintf( server, "\\\\%s", cli->cli->desthost );
init_unistr2( in.servername, server, UNI_STR_TERMINATE );
in.access = access_desired;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W,
in, out,
qbuf, rbuf,
svcctl_io_q_open_scmanager,
@@ -103,7 +103,7 @@ WERROR cli_svcctl_open_scm( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/********************************************************************
********************************************************************/
-WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_open_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, POLICY_HND *hService,
const char *servicename, uint32 access_desired )
{
@@ -118,7 +118,7 @@ WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE );
in.access = access_desired;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W,
in, out,
qbuf, rbuf,
svcctl_io_q_open_service,
@@ -136,7 +136,7 @@ WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/********************************************************************
********************************************************************/
-WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
+WERROR rpccli_svcctl_close_service(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
{
SVCCTL_Q_CLOSE_SERVICE in;
SVCCTL_R_CLOSE_SERVICE out;
@@ -147,7 +147,7 @@ WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POL
memcpy( &in.handle, hService, sizeof(POLICY_HND) );
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CLOSE_SERVICE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CLOSE_SERVICE,
in, out,
qbuf, rbuf,
svcctl_io_q_close_service,
@@ -160,7 +160,7 @@ WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POL
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_enumerate_services( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, uint32 type, uint32 state,
uint32 *returned, ENUM_SERVICES_STATUS **service_array )
{
@@ -185,7 +185,7 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx
/* first time is to get the buffer size */
in.buffer_size = 0;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
in, out,
qbuf, rbuf,
svcctl_io_q_enum_services_status,
@@ -197,7 +197,7 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx
if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
in.buffer_size = out.needed;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_ENUM_SERVICES_STATUS_W,
in, out,
qbuf, rbuf,
svcctl_io_q_enum_services_status,
@@ -225,7 +225,7 @@ WERROR cli_svcctl_enumerate_services( struct cli_state *cli, TALLOC_CTX *mem_ctx
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_query_status( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService, SERVICE_STATUS *status )
{
SVCCTL_Q_QUERY_STATUS in;
@@ -237,7 +237,7 @@ WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx,
memcpy( &in.handle, hService, sizeof(POLICY_HND) );
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS,
in, out,
qbuf, rbuf,
svcctl_io_q_query_status,
@@ -255,7 +255,7 @@ WERROR cli_svcctl_query_status( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_query_config(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService, SERVICE_CONFIG *config )
{
SVCCTL_Q_QUERY_SERVICE_CONFIG in;
@@ -269,7 +269,7 @@ WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
in.buffer_size = 0;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
in, out,
qbuf, rbuf,
svcctl_io_q_query_service_config,
@@ -279,7 +279,7 @@ WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
in.buffer_size = out.needed;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_SERVICE_CONFIG_W,
in, out,
qbuf, rbuf,
svcctl_io_q_query_service_config,
@@ -298,11 +298,30 @@ WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
- copy_unistr2( config->executablepath, out.config.executablepath );
- copy_unistr2( config->loadordergroup, out.config.loadordergroup );
- copy_unistr2( config->dependencies, out.config.dependencies );
- copy_unistr2( config->startname, out.config.startname );
- copy_unistr2( config->displayname, out.config.displayname );
+ if ( out.config.executablepath ) {
+ config->executablepath = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2( config->executablepath, out.config.executablepath );
+ }
+
+ if ( out.config.loadordergroup ) {
+ config->loadordergroup = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2( config->loadordergroup, out.config.loadordergroup );
+ }
+
+ if ( out.config.dependencies ) {
+ config->dependencies = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2( config->dependencies, out.config.dependencies );
+ }
+
+ if ( out.config.startname ) {
+ config->startname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2( config->startname, out.config.startname );
+ }
+
+ if ( out.config.displayname ) {
+ config->displayname = TALLOC_ZERO_P( mem_ctx, UNISTR2 );
+ copy_unistr2( config->displayname, out.config.displayname );
+ }
return out.status;
}
@@ -310,7 +329,7 @@ WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_start_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService,
const char **parm_array, uint32 parmcount )
{
@@ -326,7 +345,7 @@ WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
in.parmcount = 0;
in.parameters = NULL;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
in, out,
qbuf, rbuf,
svcctl_io_q_start_service,
@@ -339,7 +358,7 @@ WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_control_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService, uint32 control,
SERVICE_STATUS *status )
{
@@ -353,7 +372,7 @@ WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
memcpy( &in.handle, hService, sizeof(POLICY_HND) );
in.control = control;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
in, out,
qbuf, rbuf,
svcctl_io_q_control_service,
@@ -372,7 +391,7 @@ WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
-WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx,
+WERROR rpccli_svcctl_get_dispname( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService, fstring displayname )
{
SVCCTL_Q_GET_DISPLAY_NAME in;
@@ -385,7 +404,7 @@ WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx,
memcpy( &in.handle, hService, sizeof(POLICY_HND) );
in.display_name_len = 0;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
in, out,
qbuf, rbuf,
svcctl_io_q_get_display_name,
@@ -397,7 +416,7 @@ WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx,
if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
in.display_name_len = out.display_name_len;
- CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
+ CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME,
in, out,
qbuf, rbuf,
svcctl_io_q_get_display_name,
@@ -412,4 +431,3 @@ WERROR cli_svcctl_get_dispname( struct cli_state *cli, TALLOC_CTX *mem_ctx,
return out.status;
}
-
diff --git a/source3/rpc_client/cli_wkssvc.c b/source3/rpc_client/cli_wkssvc.c
index aea4744398..d8e97beb64 100644
--- a/source3/rpc_client/cli_wkssvc.c
+++ b/source3/rpc_client/cli_wkssvc.c
@@ -2,10 +2,10 @@
Unix SMB/CIFS implementation.
NT Domain Authentication SMB / MSRPC client
Copyright (C) Andrew Tridgell 1994-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001
- Copytight (C) Rafal Szczesniak 2002
-
+ Copyright (C) Rafal Szczesniak 2002
+ Copyright (C) Jeremy Allison 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
@@ -33,61 +33,36 @@
* @return NTSTATUS of rpc call
*/
-NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS rpccli_wks_query_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
WKS_INFO_100 *wks100)
{
- prs_struct buf;
+ prs_struct qbuf;
prs_struct rbuf;
- WKS_Q_QUERY_INFO q_o;
- WKS_R_QUERY_INFO r_o;
+ WKS_Q_QUERY_INFO q;
+ WKS_R_QUERY_INFO r;
if (cli == NULL || wks100 == NULL)
return NT_STATUS_UNSUCCESSFUL;
- /* init rpc parse structures */
- prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
-
DEBUG(4, ("WksQueryInfo\n"));
/* init query structure with rpc call arguments */
- init_wks_q_query_info(&q_o, cli->desthost, 100);
-
- /* marshall data */
- if (!wks_io_q_query_info("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- /* actual rpc call over \PIPE\wkssvc */
- if (!rpc_api_pipe_req(cli, PI_WKSSVC, WKS_QUERY_INFO, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- prs_mem_free(&buf);
+ init_wks_q_query_info(&q, cli->cli->desthost, 100);
+ r.wks100 = wks100;
- r_o.wks100 = wks100;
-
- /* get call results from response buffer */
- if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
+ CLI_DO_RPC(cli, mem_ctx, PI_WKSSVC, WKS_QUERY_INFO,
+ q, r,
+ qbuf, rbuf,
+ wks_io_q_query_info,
+ wks_io_r_query_info,
+ NT_STATUS_UNSUCCESSFUL);
+
/* check returnet status code */
- if (NT_STATUS_IS_ERR(r_o.status)) {
+ if (NT_STATUS_IS_ERR(r.status)) {
/* report the error */
- DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status)));
- prs_mem_free(&rbuf);
- return r_o.status;
+ DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r.status)));
+ return r.status;
}
- /* do clean up */
- prs_mem_free(&rbuf);
-
return NT_STATUS_OK;
}
-
diff --git a/source3/rpc_parse/parse_buffer.c b/source3/rpc_parse/parse_buffer.c
index ff2a7cc2f6..36d8eda847 100644
--- a/source3/rpc_parse/parse_buffer.c
+++ b/source3/rpc_parse/parse_buffer.c
@@ -106,7 +106,7 @@ BOOL prs_rpcbuffer_p(const char *desc, prs_struct *ps, int depth, RPC_BUFFER **b
/* caputure the pointer value to stream */
- data_p = (uint32) *buffer;
+ data_p = *buffer ? 0xf000baaa : 0;
if ( !prs_uint32("ptr", ps, depth, &data_p ))
return False;
diff --git a/source3/rpc_parse/parse_dfs.c b/source3/rpc_parse/parse_dfs.c
index 3f7b2a4cd5..f102e95004 100644
--- a/source3/rpc_parse/parse_dfs.c
+++ b/source3/rpc_parse/parse_dfs.c
@@ -22,8 +22,6 @@
*/
#include "includes.h"
-#include "nterr.h"
-#include "rpc_parse.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
diff --git a/source3/rpc_parse/parse_ds.c b/source3/rpc_parse/parse_ds.c
index 9155419ae4..c613145222 100644
--- a/source3/rpc_parse/parse_ds.c
+++ b/source3/rpc_parse/parse_ds.c
@@ -24,12 +24,13 @@
/************************************************************************
************************************************************************/
-static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic)
+static BOOL ds_io_dominfobasic(const char *desc, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic, prs_struct *ps, int depth)
{
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *p = *basic;
- if ( UNMARSHALLING(ps) )
+ if ( UNMARSHALLING(ps) ) {
p = *basic = PRS_ALLOC_MEM(ps, DSROLE_PRIMARY_DOMAIN_INFO_BASIC, 1);
+ }
if ( !p )
return False;
@@ -75,7 +76,7 @@ static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSR
/************************************************************************
************************************************************************/
-BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_GETPRIMDOMINFO *q_u)
+BOOL ds_io_q_getprimdominfo( const char *desc, DS_Q_GETPRIMDOMINFO *q_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "ds_io_q_getprimdominfo");
depth++;
@@ -92,7 +93,7 @@ BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_G
/************************************************************************
************************************************************************/
-BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_GETPRIMDOMINFO *r_u)
+BOOL ds_io_r_getprimdominfo( const char *desc, DS_R_GETPRIMDOMINFO *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "ds_io_r_getprimdominfo");
depth++;
@@ -114,7 +115,7 @@ BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_G
switch ( r_u->level )
{
case DsRolePrimaryDomainInfoBasic:
- if ( !ds_io_dominfobasic( "dominfobasic", ps, depth, &r_u->info.basic ) )
+ if ( !ds_io_dominfobasic( "dominfobasic", &r_u->info.basic, ps, depth) )
return False;
break;
default:
@@ -135,8 +136,7 @@ BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_G
initialize a DS_ENUM_DOM_TRUSTS structure
************************************************************************/
-BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server,
- uint32 flags )
+BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server, uint32 flags )
{
q->flags = flags;
@@ -153,7 +153,7 @@ BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server,
/************************************************************************
************************************************************************/
-static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS *trust)
+static BOOL ds_io_domain_trusts( const char *desc, DS_DOMAIN_TRUSTS *trust, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr");
depth++;
@@ -188,7 +188,7 @@ static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS
/************************************************************************
************************************************************************/
-static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS_CTR *ctr)
+static BOOL ds_io_dom_trusts_ctr( const char *desc, DS_DOMAIN_TRUSTS_CTR *ctr, prs_struct *ps, int depth)
{
int i;
@@ -217,7 +217,7 @@ static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, D
we need another loop to read the UNISTR2's and SID's */
for ( i=0; i<ctr->max_count;i++ ) {
- if ( !ds_io_domain_trusts("domain_trusts", ps, depth, &ctr->trusts[i] ) )
+ if ( !ds_io_domain_trusts("domain_trusts", &ctr->trusts[i], ps, depth) )
return False;
}
@@ -248,7 +248,7 @@ static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, D
initialize a DS_ENUM_DOM_TRUSTS request
************************************************************************/
-BOOL ds_io_q_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_Q_ENUM_DOM_TRUSTS *q_u)
+BOOL ds_io_q_enum_domain_trusts( const char *desc, DS_Q_ENUM_DOM_TRUSTS *q_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "ds_io_q_enum_domain_trusts");
depth++;
@@ -274,7 +274,7 @@ BOOL ds_io_q_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS
/************************************************************************
************************************************************************/
-BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_R_ENUM_DOM_TRUSTS *r_u)
+BOOL ds_io_r_enum_domain_trusts( const char *desc, DS_R_ENUM_DOM_TRUSTS *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "ds_io_r_enum_domain_trusts");
depth++;
@@ -286,7 +286,7 @@ BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS
return False;
if ( r_u->num_domains ) {
- if ( !ds_io_dom_trusts_ctr("domains", ps, depth, &r_u->domains ) )
+ if ( !ds_io_dom_trusts_ctr("domains", &r_u->domains, ps, depth) )
return False;
}
@@ -298,5 +298,3 @@ BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS
return True;
}
-
-
diff --git a/source3/rpc_parse/parse_echo.c b/source3/rpc_parse/parse_echo.c
index b4aa8de24a..48dda7b171 100644
--- a/source3/rpc_parse/parse_echo.c
+++ b/source3/rpc_parse/parse_echo.c
@@ -21,8 +21,6 @@
*/
#include "includes.h"
-#include "nterr.h"
-#include "rpc_parse.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
diff --git a/source3/rpc_parse/parse_eventlog.c b/source3/rpc_parse/parse_eventlog.c
index 734f52fffb..1b57272ca4 100644
--- a/source3/rpc_parse/parse_eventlog.c
+++ b/source3/rpc_parse/parse_eventlog.c
@@ -23,9 +23,24 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
-/*
- * called from eventlog_q_open_eventlog (srv_eventlog.c)
- */
+/********************************************************************
+********************************************************************/
+
+BOOL prs_ev_open_unknown0( const char *desc, prs_struct *ps, int depth, EVENTLOG_OPEN_UNKNOWN0 *u )
+{
+ if ( !u )
+ return False;
+
+ if ( !prs_uint16("", ps, depth, &u->unknown1) )
+ return False;
+ if ( !prs_uint16("", ps, depth, &u->unknown2) )
+ return False;
+
+ return True;
+}
+
+/********************************************************************
+********************************************************************/
BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u,
prs_struct *ps, int depth)
@@ -33,62 +48,28 @@ BOOL eventlog_io_q_open_eventlog(const char *desc, EVENTLOG_Q_OPEN_EVENTLOG *q_u
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))
+ if ( !prs_pointer("", ps, depth, (void**)&q_u->unknown0, sizeof(EVENTLOG_OPEN_UNKNOWN0), (PRS_POINTER_CAST)prs_ev_open_unknown0))
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))
+ if ( !prs_unistr4("logname", ps, depth, &q_u->logname) )
return False;
- if(!prs_uint32("sourcename_ptr", ps, depth, &q_u->sourcename_ptr))
+ if ( !prs_align(ps) )
return False;
- if(!smb_io_unistr2("", &q_u->sourcename, q_u->sourcename_ptr, ps, depth))
+
+ if ( !prs_unistr4("servername", ps, depth, &q_u->servername) )
return False;
- if(!prs_align(ps))
+ if ( !prs_align(ps) )
return False;
- /* Get server name */
-
- if(!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
+ if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) )
return False;
- if(!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
+ if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) )
return False;
return True;
@@ -424,17 +405,8 @@ BOOL eventlog_io_q_clear_eventlog(const char *desc, EVENTLOG_Q_CLEAR_EVENTLOG *q
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))
+
+ if ( !prs_unistr4("backupfile", ps, depth, &q_u->backupfile) )
return False;
return True;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 921e366f11..8bbb97f226 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -296,7 +296,7 @@ BOOL smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **s
/* caputure the pointer value to stream */
- data_p = (uint32) *sid2;
+ data_p = *sid2 ? 0xf000baaa : 0;
if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
return False;
@@ -1003,7 +1003,7 @@ BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni
/* caputure the pointer value to stream */
- data_p = (uint32) *uni2;
+ data_p = *uni2 ? 0xf000baaa : 0;
if ( !prs_uint32("ptr", ps, depth, &data_p ))
return False;
@@ -1038,7 +1038,7 @@ BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
/* 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 );
+ return smb_io_unistr2( desc, uni2, uni2 ? 1 : 0, ps, depth );
}
/*******************************************************************
@@ -1139,7 +1139,7 @@ BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
}
/*******************************************************************
- Reads or writes a UNISTR2_ARRAY structure.
+ Reads or writes a UNISTR4_ARRAY structure.
********************************************************************/
BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index 3a050148c9..35533e360a 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -671,7 +671,7 @@ BOOL net_io_q_trust_dom(const char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct
void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
const char *logon_srv, const char *logon_clnt,
- DOM_CHAL *clnt_chal)
+ const DOM_CHAL *clnt_chal)
{
DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
@@ -860,7 +860,7 @@ BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int de
void init_q_auth_3(NET_Q_AUTH_3 *q_a,
const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
- DOM_CHAL *clnt_chal, uint32 clnt_flgs)
+ const DOM_CHAL *clnt_chal, uint32 clnt_flgs)
{
DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
@@ -1496,7 +1496,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
********************************************************************/
BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
- int depth, uint16 validation_level)
+ int depth, uint16 validation_level, BOOL kerb_validation_level)
{
unsigned int i;
@@ -1595,6 +1595,18 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
}
}
+ /* get kerb validation info (not really part of user_info_3) - Guenther */
+
+ if (kerb_validation_level) {
+
+ if(!prs_uint32("ptr_res_group_dom_sid", ps, depth, &usr->ptr_res_group_dom_sid))
+ return False;
+ if(!prs_uint32("res_group_count", ps, depth, &usr->res_group_count))
+ return False;
+ if(!prs_uint32("ptr_res_groups", ps, depth, &usr->ptr_res_groups))
+ return False;
+ }
+
if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
return False;
if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
@@ -1636,6 +1648,11 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
uint32 num_other_sids = usr->num_other_sids;
+ if (!(usr->user_flgs & LOGON_EXTRA_SIDS)) {
+ DEBUG(10,("net_io_user_info3: user_flgs attribute does not have LOGON_EXTRA_SIDS\n"));
+ /* return False; */
+ }
+
if (!prs_uint32("num_other_sids", ps, depth,
&num_other_sids))
return False;
@@ -1724,8 +1741,10 @@ BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps,
if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
return False;
- if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
- return False;
+ if (&r_l->buffer_creds) {
+ if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
+ return False;
+ }
if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
return False;
@@ -1733,11 +1752,11 @@ BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps,
return False;
#if 1 /* W2k always needs this - even for bad passwd. JRA */
- if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
+ if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
return False;
#else
if (r_l->switch_value != 0) {
- if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
+ if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
return False;
}
#endif
@@ -2139,9 +2158,8 @@ BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
- SAM_ACCOUNT_INFO * info, prs_struct *ps,
- int depth)
+static BOOL net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info,
+ prs_struct *ps, int depth)
{
BUFHDR2 hdr_priv_data;
uint32 i;
@@ -2295,7 +2313,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
if (ps->io)
{
/* reading */
- if (!prs_hash1(ps, ps->data_offset, sess_key, len))
+ if (!prs_hash1(ps, ps->data_offset, len))
return False;
}
if (!net_io_sam_passwd_info("pass", &info->pass,
@@ -2305,7 +2323,7 @@ static BOOL net_io_sam_account_info(const char *desc, uint8 sess_key[16],
if (!ps->io)
{
/* writing */
- if (!prs_hash1(ps, old_offset, sess_key, len))
+ if (!prs_hash1(ps, old_offset, len))
return False;
}
}
@@ -2834,7 +2852,7 @@ static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
+static BOOL net_io_sam_delta_ctr(const char *desc,
SAM_DELTA_CTR * delta, uint16 type,
prs_struct *ps, int depth)
{
@@ -2859,7 +2877,7 @@ static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
break;
case SAM_DELTA_ACCOUNT_INFO:
- if (!net_io_sam_account_info("", sess_key, &delta->account_info, ps, depth))
+ if (!net_io_sam_account_info("", &delta->account_info, ps, depth))
return False;
break;
@@ -2912,7 +2930,7 @@ static BOOL net_io_sam_delta_ctr(const char *desc, uint8 sess_key[16],
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_sam_sync(const char *desc, uint8 sess_key[16],
+BOOL net_io_r_sam_sync(const char *desc,
NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
{
uint32 i;
@@ -2976,7 +2994,7 @@ BOOL net_io_r_sam_sync(const char *desc, uint8 sess_key[16],
for (i = 0; i < r_s->num_deltas2; i++)
{
if (!net_io_sam_delta_ctr(
- "", sess_key, &r_s->deltas[i],
+ "", &r_s->deltas[i],
r_s->hdr_deltas[i].type3,
ps, depth)) {
DEBUG(0, ("hmm, failed on i=%d\n", i));
@@ -3048,7 +3066,7 @@ BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps
/*******************************************************************
reads or writes a structure.
********************************************************************/
-BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
+BOOL net_io_r_sam_deltas(const char *desc,
NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
{
unsigned int i;
@@ -3104,7 +3122,7 @@ BOOL net_io_r_sam_deltas(const char *desc, uint8 sess_key[16],
for (i = 0; i < r_s->num_deltas; i++)
{
if (!net_io_sam_delta_ctr(
- "", sess_key,
+ "",
&r_s->deltas[i],
r_s->hdr_deltas[i].type2,
ps, depth))
diff --git a/source3/rpc_parse/parse_ntsvcs.c b/source3/rpc_parse/parse_ntsvcs.c
new file mode 100644
index 0000000000..f2e4456025
--- /dev/null
+++ b/source3/rpc_parse/parse_ntsvcs.c
@@ -0,0 +1,415 @@
+/*
+ * 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
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_get_version(const char *desc, NTSVCS_Q_GET_VERSION *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_get_version");
+ depth++;
+
+ /* there is nothing to parse in this PDU */
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_get_version(const char *desc, NTSVCS_R_GET_VERSION *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_get_version");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("version", ps, depth, &r_u->version))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_get_device_list_size(const char *desc, NTSVCS_Q_GET_DEVICE_LIST_SIZE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_get_device_list_size");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_pointer("devicename", ps, depth, (void**)&q_u->devicename, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2) )
+ return False;
+ if( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("flags", ps, depth, &q_u->flags) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_get_device_list_size(const char *desc, NTSVCS_R_GET_DEVICE_LIST_SIZE *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_list_size");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("size", ps, depth, &r_u->size))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_get_device_list(const char *desc, NTSVCS_Q_GET_DEVICE_LIST *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_get_device_list");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_pointer("devicename", ps, depth, (void**)&q_u->devicename, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2) )
+ return False;
+ if( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("buffer_size", ps, depth, &q_u->buffer_size) )
+ return False;
+ if ( !prs_uint32("flags", ps, depth, &q_u->flags) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_get_device_list(const char *desc, NTSVCS_R_GET_DEVICE_LIST *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_list_size");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_io_unistr2("devicepath", ps, depth, &r_u->devicepath) )
+ return False;
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("needed", ps, depth, &r_u->needed))
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_validate_device_instance(const char *desc, NTSVCS_Q_VALIDATE_DEVICE_INSTANCE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_validate_device_instance");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) )
+ return False;
+ if( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("flags", ps, depth, &q_u->flags) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_validate_device_instance(const char *desc, NTSVCS_R_VALIDATE_DEVICE_INSTANCE *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_validate_device_instance");
+ depth++;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_get_device_reg_property(const char *desc, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_get_device_reg_property");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) )
+ return False;
+ if( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("property", ps, depth, &q_u->property) )
+ return False;
+ if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) )
+ return False;
+ if ( !prs_uint32("buffer_size1", ps, depth, &q_u->buffer_size1) )
+ return False;
+ if ( !prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2) )
+ return False;
+ if ( !prs_uint32("unknown5", ps, depth, &q_u->unknown5) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_get_device_reg_property(const char *desc, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_reg_property");
+ depth++;
+
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("unknown1", ps, depth, &r_u->unknown1) )
+ return False;
+
+ if ( !smb_io_regval_buffer("value", ps, depth, &r_u->value) )
+ return False;
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("size", ps, depth, &r_u->size) )
+ return False;
+
+ if ( !prs_uint32("needed", ps, depth, &r_u->needed) )
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_get_hw_profile_info(const char *desc, NTSVCS_Q_GET_HW_PROFILE_INFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_get_hw_profile_info");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_uint32("index", ps, depth, &q_u->index) )
+ return False;
+
+ q_u->buffer_size = 0x000000a8;
+
+ if ( UNMARSHALLING(ps) )
+ q_u->buffer = TALLOC_ARRAY(get_talloc_ctx(), uint8, q_u->buffer_size );
+
+ if ( !prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size) )
+ return False;
+
+ if ( !prs_uint32("buffer_size", ps, depth, &q_u->buffer_size) )
+ return False;
+
+ if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_get_hw_profile_info(const char *desc, NTSVCS_R_GET_HW_PROFILE_INFO *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_reg_property");
+ depth++;
+
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( UNMARSHALLING(ps) )
+ r_u->buffer = TALLOC_ARRAY(get_talloc_ctx(), uint8, r_u->buffer_size );
+
+ if ( !prs_uint8s(True, "buffer", ps, depth, r_u->buffer, r_u->buffer_size) )
+ return False;
+
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_q_hw_profile_flags(const char *desc, NTSVCS_Q_HW_PROFILE_FLAGS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_q_hw_profile_flags");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) )
+ return False;
+
+
+ if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) )
+ return False;
+ if( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) )
+ return False;
+ if ( !prs_uint32("unknown3", ps, depth, &q_u->unknown3) )
+ return False;
+ if ( !prs_uint32("unknown4", ps, depth, &q_u->unknown4) )
+ return False;
+ if ( !prs_uint32("unknown5", ps, depth, &q_u->unknown5) )
+ return False;
+ if ( !prs_uint32("unknown6", ps, depth, &q_u->unknown6) )
+ return False;
+ if ( !prs_uint32("unknown7", ps, depth, &q_u->unknown7) )
+ return False;
+
+ if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) )
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL ntsvcs_io_r_hw_profile_flags(const char *desc, NTSVCS_R_HW_PROFILE_FLAGS *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "ntsvcs_io_r_hw_profile_flags");
+ depth++;
+
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32("unknown1", ps, depth, &r_u->unknown1) )
+ return False;
+ if ( !prs_uint32("unknown2", ps, depth, &r_u->unknown2) )
+ return False;
+ if ( !prs_uint32("unknown3", ps, depth, &r_u->unknown3) )
+ return False;
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+
+
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 709a5d39af..d174bad444 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -34,7 +34,6 @@ void prs_dump(char *name, int v, prs_struct *ps)
prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size);
}
-
/**
* Dump from the start of the prs to the current location.
**/
@@ -43,7 +42,6 @@ void prs_dump_before(char *name, int v, prs_struct *ps)
prs_dump_region(name, v, ps, 0, ps->data_offset);
}
-
/**
* Dump everything from the start of the prs up to the current location.
**/
@@ -52,6 +50,7 @@ void prs_dump_region(char *name, int v, prs_struct *ps,
{
int fd, i;
pstring fname;
+ ssize_t sz;
if (DEBUGLEVEL < 50) return;
for (i=1;i<100;i++) {
if (v != -1) {
@@ -63,26 +62,28 @@ void prs_dump_region(char *name, int v, prs_struct *ps,
if (fd != -1 || errno != EEXIST) break;
}
if (fd != -1) {
- write(fd, ps->data_p + from_off, to_off - from_off);
- close(fd);
- DEBUG(0,("created %s\n", fname));
+ sz = write(fd, ps->data_p + from_off, to_off - from_off);
+ i = close(fd);
+ if ( (sz != to_off-from_off) || (i != 0) ) {
+ DEBUG(0,("Error writing/closing %s: %ld!=%ld %d\n", fname, (unsigned long)sz, (unsigned long)to_off-from_off, i ));
+ } else {
+ DEBUG(0,("created %s\n", fname));
+ }
}
}
-
-
/*******************************************************************
- debug output for parsing info.
+ Debug output for parsing info
- XXXX side-effect of this function is to increase the debug depth XXXX
+ XXXX side-effect of this function is to increase the debug depth XXXX.
+
+********************************************************************/
- ********************************************************************/
void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
{
DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
}
-
/**
* Initialise an expandable parse structure.
*
@@ -91,6 +92,7 @@ void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
*
* @return False if allocation fails, otherwise True.
**/
+
BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
{
ZERO_STRUCTP(ps);
@@ -111,6 +113,9 @@ BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
}
memset(ps->data_p, '\0', (size_t)size);
ps->is_dynamic = True; /* We own this memory. */
+ } else if (MARSHALLING(ps)) {
+ /* If size is zero and we're marshalling we should allocate memory on demand. */
+ ps->is_dynamic = True;
}
return True;
@@ -254,7 +259,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space)
* is greater.
*/
- new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
+ new_size = MAX(RPC_MAX_PDU_FRAG_LEN,extra_space);
if((new_data = SMB_MALLOC(new_size)) == NULL) {
DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
@@ -398,7 +403,7 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin
Append the data from a buffer into a parse_struct.
********************************************************************/
-BOOL prs_copy_data_in(prs_struct *dst, char *src, uint32 len)
+BOOL prs_copy_data_in(prs_struct *dst, const char *src, uint32 len)
{
if (len == 0)
return True;
@@ -565,6 +570,15 @@ void prs_force_dynamic(prs_struct *ps)
}
/*******************************************************************
+ Associate a session key with a parse struct.
+ ********************************************************************/
+
+void prs_set_session_key(prs_struct *ps, const char sess_key[16])
+{
+ ps->sess_key = sess_key;
+}
+
+/*******************************************************************
Stream a uint8.
********************************************************************/
@@ -596,9 +610,9 @@ BOOL prs_pointer( const char *name, prs_struct *ps, int depth,
{
uint32 data_p;
- /* caputure the pointer value to stream */
+ /* output f000baaa to stream if the pointer is non-zero. */
- data_p = (uint32) *data;
+ data_p = *data ? 0xf000baaa : 0;
if ( !prs_uint32("ptr", ps, depth, &data_p ))
return False;
@@ -1387,7 +1401,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
hash a stream.
********************************************************************/
-BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
+BOOL prs_hash1(prs_struct *ps, uint32 offset, int len)
{
char *q;
@@ -1396,10 +1410,10 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
#ifdef DEBUG_PASSWORD
DEBUG(100, ("prs_hash1\n"));
- dump_data(100, sess_key, 16);
+ dump_data(100, ps->sess_key, 16);
dump_data(100, q, len);
#endif
- SamOEMhash((uchar *) q, sess_key, len);
+ SamOEMhash((uchar *) q, ps->sess_key, len);
#ifdef DEBUG_PASSWORD
dump_data(100, q, len);
@@ -1413,9 +1427,9 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
MD5 it with the session key.
********************************************************************/
-static void netsec_digest(struct netsec_auth_struct *a,
- int auth_flags,
- RPC_AUTH_NETSEC_CHK * verf,
+static void schannel_digest(struct schannel_auth_struct *a,
+ enum pipe_auth_level auth_level,
+ RPC_AUTH_SCHANNEL_CHK * verf,
char *data, size_t data_len,
uchar digest_final[16])
{
@@ -1429,7 +1443,7 @@ static void netsec_digest(struct netsec_auth_struct *a,
out of order */
MD5Update(&ctx3, zeros, sizeof(zeros));
MD5Update(&ctx3, verf->sig, sizeof(verf->sig));
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
MD5Update(&ctx3, verf->confounder, sizeof(verf->confounder));
}
MD5Update(&ctx3, (const unsigned char *)data, data_len);
@@ -1445,8 +1459,8 @@ static void netsec_digest(struct netsec_auth_struct *a,
Calculate the key with which to encode the data payload
********************************************************************/
-static void netsec_get_sealing_key(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf,
+static void schannel_get_sealing_key(struct schannel_auth_struct *a,
+ RPC_AUTH_SCHANNEL_CHK *verf,
uchar sealing_key[16])
{
static uchar zeros[4];
@@ -1473,8 +1487,8 @@ static void netsec_get_sealing_key(struct netsec_auth_struct *a,
Encode or Decode the sequence number (which is symmetric)
********************************************************************/
-static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
- RPC_AUTH_NETSEC_CHK *verf)
+static void schannel_deal_with_seq_num(struct schannel_auth_struct *a,
+ RPC_AUTH_SCHANNEL_CHK *verf)
{
static uchar zeros[4];
uchar sequence_key[16];
@@ -1493,10 +1507,10 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
}
/*******************************************************************
-creates an RPC_AUTH_NETSEC_CHK structure.
+creates an RPC_AUTH_SCHANNEL_CHK structure.
********************************************************************/
-static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
+static BOOL init_rpc_auth_schannel_chk(RPC_AUTH_SCHANNEL_CHK * chk,
const uchar sig[8],
const uchar packet_digest[8],
const uchar seq_num[8], const uchar confounder[8])
@@ -1513,15 +1527,15 @@ static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
}
/*******************************************************************
- Encode a blob of data using the netsec (schannel) alogrithm, also produceing
+ Encode a blob of data using the schannel alogrithm, also produceing
a checksum over the original data. We currently only support
signing and sealing togeather - the signing-only code is close, but not
quite compatible with what MS does.
********************************************************************/
-void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf,
+void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
+ enum schannel_direction direction,
+ RPC_AUTH_SCHANNEL_CHK * verf,
char *data, size_t data_len)
{
uchar digest_final[16];
@@ -1529,16 +1543,16 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
uchar seq_num[8];
static const uchar nullbytes[8];
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
+ static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
+ static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
+ const uchar *schannel_sig = NULL;
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ schannel_sig = schannel_seal_sig;
+ } else {
+ schannel_sig = schannel_sign_sig;
}
/* fill the 'confounder' with random data */
@@ -1559,18 +1573,18 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
dump_data_pw("verf->seq_num:\n", seq_num, sizeof(verf->seq_num));
- init_rpc_auth_netsec_chk(verf, netsec_sig, nullbytes,
+ init_rpc_auth_schannel_chk(verf, schannel_sig, nullbytes,
seq_num, confounder);
/* produce a digest of the packet to prove it's legit (before we seal it) */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
+ schannel_digest(a, auth_level, verf, data, data_len, digest_final);
memcpy(verf->packet_digest, digest_final, sizeof(verf->packet_digest));
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
uchar sealing_key[16];
/* get the key to encode the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
+ schannel_get_sealing_key(a, verf, sealing_key);
/* encode the verification data */
dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder));
@@ -1587,35 +1601,35 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
/* encode the sequence number (key based on packet digest) */
/* needs to be done after the sealing, as the original version
is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
+ schannel_deal_with_seq_num(a, verf);
return;
}
/*******************************************************************
- Decode a blob of data using the netsec (schannel) alogrithm, also verifiying
+ Decode a blob of data using the schannel alogrithm, also verifiying
a checksum over the original data. We currently can verify signed messages,
as well as decode sealed messages
********************************************************************/
-BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
- enum netsec_direction direction,
- RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len)
+BOOL schannel_decode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
+ enum schannel_direction direction,
+ RPC_AUTH_SCHANNEL_CHK * verf, char *data, size_t data_len)
{
uchar digest_final[16];
- static const uchar netsec_seal_sig[8] = NETSEC_SEAL_SIGNATURE;
- static const uchar netsec_sign_sig[8] = NETSEC_SIGN_SIGNATURE;
- const uchar *netsec_sig = NULL;
+ static const uchar schannel_seal_sig[8] = SCHANNEL_SEAL_SIGNATURE;
+ static const uchar schannel_sign_sig[8] = SCHANNEL_SIGN_SIGNATURE;
+ const uchar *schannel_sig = NULL;
uchar seq_num[8];
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
- if (auth_flags & AUTH_PIPE_SEAL) {
- netsec_sig = netsec_seal_sig;
- } else if (auth_flags & AUTH_PIPE_SIGN) {
- netsec_sig = netsec_sign_sig;
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ schannel_sig = schannel_seal_sig;
+ } else {
+ schannel_sig = schannel_sign_sig;
}
/* Create the expected sequence number for comparison */
@@ -1630,7 +1644,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
break;
}
- DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
+ DEBUG(10,("SCHANNEL: schannel_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num));
@@ -1638,7 +1652,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
/* extract the sequence number (key based on supplied packet digest) */
/* needs to be done before the sealing, as the original version
is used in the sealing stuff... */
- netsec_deal_with_seq_num(a, verf);
+ schannel_deal_with_seq_num(a, verf);
if (memcmp(verf->seq_num, seq_num, sizeof(seq_num))) {
/* don't even bother with the below if the sequence number is out */
@@ -1646,7 +1660,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
digest, as supplied by the client. We check that it's a valid
checksum after the decode, below
*/
- DEBUG(2, ("netsec_decode: FAILED: packet sequence number:\n"));
+ DEBUG(2, ("schannel_decode: FAILED: packet sequence number:\n"));
dump_data(2, (const char*)verf->seq_num, sizeof(verf->seq_num));
DEBUG(2, ("should be:\n"));
dump_data(2, (const char*)seq_num, sizeof(seq_num));
@@ -1654,20 +1668,20 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
return False;
}
- if (memcmp(verf->sig, netsec_sig, sizeof(verf->sig))) {
+ if (memcmp(verf->sig, schannel_sig, sizeof(verf->sig))) {
/* Validate that the other end sent the expected header */
- DEBUG(2, ("netsec_decode: FAILED: packet header:\n"));
+ DEBUG(2, ("schannel_decode: FAILED: packet header:\n"));
dump_data(2, (const char*)verf->sig, sizeof(verf->sig));
DEBUG(2, ("should be:\n"));
- dump_data(2, (const char*)netsec_sig, sizeof(netsec_sig));
+ dump_data(2, (const char*)schannel_sig, sizeof(schannel_sig));
return False;
}
- if (auth_flags & AUTH_PIPE_SEAL) {
+ if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
uchar sealing_key[16];
/* get the key to extract the data with */
- netsec_get_sealing_key(a, verf, sealing_key);
+ schannel_get_sealing_key(a, verf, sealing_key);
/* extract the verification data */
dump_data_pw("verf->confounder:\n", verf->confounder,
@@ -1684,7 +1698,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
}
/* digest includes 'data' after unsealing */
- netsec_digest(a, auth_flags, verf, data, data_len, digest_final);
+ schannel_digest(a, auth_level, verf, data, data_len, digest_final);
dump_data_pw("Calculated digest:\n", digest_final,
sizeof(digest_final));
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index be452033fe..295fead103 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -33,7 +33,7 @@
Fill in a REGVAL_BUFFER for the data given a REGISTRY_VALUE
*******************************************************************/
-static uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val )
+uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val )
{
uint32 real_size = 0;
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index ce081b92e8..ea4ec2c863 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -191,6 +191,26 @@ interface/version dce/rpc pipe identification
}, 0x00 \
}
+#define SYNT_UNIXINFO_V0 \
+{ \
+ { \
+ 0x9c54e310, 0xa955, 0x4885, \
+ { 0xbd, 0x31 }, \
+ { 0x78, 0x78, \
+ 0x71, 0x47, 0xdf, 0xa6 } \
+ }, 0x00 \
+}
+
+#define SYNT_NTSVCS_V1 \
+{ \
+ { \
+ 0x8d9f4e40, 0xa03d, 0x11ce, \
+ { 0x8f, 0x69}, \
+ { 0x08, 0x00, \
+ 0x3e, 0x30, 0x05, 0x1b } \
+ }, 0x01 \
+}
+
/*
* IMPORTANT!! If you update this structure, make sure to
* update the index #defines in smb.h.
@@ -212,9 +232,19 @@ const struct pipe_id_info pipe_names [] =
{ 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 },
+ { PIPE_NTSVCS , SYNT_NTSVCS_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
+/****************************************************************************
+ Return the pipe name from the index.
+ ****************************************************************************/
+
+const char *cli_get_pipe_name(int pipe_idx)
+{
+ return &pipe_names[pipe_idx].client_pipe[5];
+}
+
/*******************************************************************
Inits an RPC_HDR structure.
********************************************************************/
@@ -658,8 +688,8 @@ void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
uint8 auth_pad_len,
uint32 auth_context_id)
{
- rai->auth_type = auth_type; /* nt lm ssp 0x0a */
- rai->auth_level = auth_level; /* 0x06 */
+ rai->auth_type = auth_type;
+ rai->auth_level = auth_level;
rai->auth_pad_len = auth_pad_len;
rai->auth_reserved = 0;
rai->auth_context_id = auth_context_id;
@@ -680,9 +710,9 @@ BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, in
if(!prs_align(ps))
return False;
- if(!prs_uint8 ("auth_type ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
+ if(!prs_uint8 ("auth_type ", ps, depth, &rai->auth_type))
return False;
- if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
+ if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level))
return False;
if(!prs_uint8 ("auth_pad_len ", ps, depth, &rai->auth_pad_len))
return False;
@@ -694,43 +724,6 @@ BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, in
return True;
}
-
-/*******************************************************************
- Init an RPC_HDR_AUTHA structure.
-********************************************************************/
-
-void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
- uint16 max_tsize, uint16 max_rsize,
- RPC_HDR_AUTH *auth)
-{
- rai->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
- rai->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
- rai->auth = *auth;
-}
-
-/*******************************************************************
- Reads or writes an RPC_HDR_AUTHA structure.
-********************************************************************/
-
-BOOL smb_io_rpc_hdr_autha(const char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth)
-{
- if (rai == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_hdr_autha");
- depth++;
-
- if(!prs_uint16("max_tsize ", ps, depth, &rai->max_tsize))
- return False;
- if(!prs_uint16("max_rsize ", ps, depth, &rai->max_rsize))
- return False;
-
- if(!smb_io_rpc_hdr_auth("auth", &rai->auth, ps, depth))
- return False;
-
- return True;
-}
-
/*******************************************************************
Checks an RPC_AUTH_VERIFIER structure.
********************************************************************/
@@ -775,17 +768,15 @@ BOOL smb_io_rpc_auth_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_stru
}
/*******************************************************************
- This parses an RPC_AUTH_VERIFIER for NETLOGON schannel. I think
- assuming "NTLMSSP" in sm_io_rpc_auth_verifier is somewhat wrong.
- I have to look at that later...
+ This parses an RPC_AUTH_VERIFIER for schannel. I think
********************************************************************/
-BOOL smb_io_rpc_netsec_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
+BOOL smb_io_rpc_schannel_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
{
if (rav == NULL)
return False;
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
+ prs_debug(ps, depth, desc, "smb_io_rpc_schannel_verifier");
depth++;
if(!prs_string("signature", ps, depth, rav->signature, sizeof(rav->signature)))
@@ -797,424 +788,10 @@ BOOL smb_io_rpc_netsec_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_st
}
/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_NEG structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
- uint32 neg_flgs,
- const char *myname, const char *domain)
-{
- int len_myname = strlen(myname);
- int len_domain = strlen(domain);
-
- neg->neg_flgs = neg_flgs ; /* 0x00b2b3 */
-
- init_str_hdr(&neg->hdr_domain, len_domain, len_domain, 0x20 + len_myname);
- init_str_hdr(&neg->hdr_myname, len_myname, len_myname, 0x20);
-
- fstrcpy(neg->myname, myname);
- fstrcpy(neg->domain, domain);
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
-
- *** lkclXXXX HACK ALERT! ***
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_neg(const char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth)
-{
- uint32 start_offset = prs_offset(ps);
- if (neg == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_neg");
- depth++;
-
- if(!prs_uint32("neg_flgs ", ps, depth, &neg->neg_flgs))
- return False;
-
- if (ps->io) {
- uint32 old_offset;
- uint32 old_neg_flags = neg->neg_flgs;
-
- /* reading */
-
- ZERO_STRUCTP(neg);
-
- neg->neg_flgs = old_neg_flags;
-
- if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
- return False;
-
- old_offset = prs_offset(ps);
-
- if(!prs_set_offset(ps, neg->hdr_myname.buffer + start_offset - 12))
- return False;
-
- if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname,
- MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
- return False;
-
- old_offset += neg->hdr_myname.str_str_len;
-
- if(!prs_set_offset(ps, neg->hdr_domain.buffer + start_offset - 12))
- return False;
-
- if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain,
- MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain ))))
- return False;
-
- old_offset += neg->hdr_domain .str_str_len;
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- } else {
- /* writing */
- if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
- return False;
-
- if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname,
- MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
- return False;
- if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain,
- MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain ))))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
-creates an RPC_AUTH_NTLMSSP_CHAL structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
- uint32 neg_flags,
- uint8 challenge[8])
-{
- chl->unknown_1 = 0x0;
- chl->unknown_2 = 0x00000028;
- chl->neg_flags = neg_flags; /* 0x0082b1 */
-
- memcpy(chl->challenge, challenge, sizeof(chl->challenge));
- memset((char *)chl->reserved , '\0', sizeof(chl->reserved));
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_chal(const char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth)
-{
- if (chl == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chal");
- depth++;
-
- if(!prs_uint32("unknown_1", ps, depth, &chl->unknown_1)) /* 0x0000 0000 */
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &chl->unknown_2)) /* 0x0000 b2b3 */
- return False;
- if(!prs_uint32("neg_flags", ps, depth, &chl->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- if(!prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge)))
- return False;
- if(!prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved )))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_RESP structure.
-
- *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
- *** lkclXXXX the actual offset is at the start of the auth verifier ***
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
- uchar lm_resp[24], uchar nt_resp[24],
- const char *domain, const char *user, const char *wks,
- uint32 neg_flags)
-{
- uint32 offset;
- int dom_len = strlen(domain);
- int wks_len = strlen(wks);
- int usr_len = strlen(user);
- int lm_len = (lm_resp != NULL) ? 24 : 0;
- int nt_len = (nt_resp != NULL) ? 24 : 0;
-
- DEBUG(5,("make_rpc_auth_ntlmssp_resp\n"));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("lm_resp\n"));
- dump_data(100, (char *)lm_resp, 24);
- DEBUG(100,("nt_resp\n"));
- dump_data(100, (char *)nt_resp, 24);
-#endif
-
- DEBUG(6,("dom: %s user: %s wks: %s neg_flgs: 0x%x\n",
- domain, user, wks, neg_flags));
-
- offset = 0x40;
-
- if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- dom_len *= 2;
- wks_len *= 2;
- usr_len *= 2;
- }
-
- init_str_hdr(&rsp->hdr_domain, dom_len, dom_len, offset);
- offset += dom_len;
-
- init_str_hdr(&rsp->hdr_usr, usr_len, usr_len, offset);
- offset += usr_len;
-
- init_str_hdr(&rsp->hdr_wks, wks_len, wks_len, offset);
- offset += wks_len;
-
- init_str_hdr(&rsp->hdr_lm_resp, lm_len, lm_len, offset);
- offset += lm_len;
-
- init_str_hdr(&rsp->hdr_nt_resp, nt_len, nt_len, offset);
- offset += nt_len;
-
- init_str_hdr(&rsp->hdr_sess_key, 0, 0, offset);
-
- rsp->neg_flags = neg_flags;
-
- memcpy(rsp->lm_resp, lm_resp, 24);
- memcpy(rsp->nt_resp, nt_resp, 24);
-
- if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- rpcstr_push(rsp->domain, domain, sizeof(rsp->domain), 0);
- rpcstr_push(rsp->user, user, sizeof(rsp->user), 0);
- rpcstr_push(rsp->wks, wks, sizeof(rsp->wks), 0);
- } else {
- fstrcpy(rsp->domain, domain);
- fstrcpy(rsp->user, user);
- fstrcpy(rsp->wks, wks);
- }
-
- rsp->sess_key[0] = 0;
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
-
- *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
- *** lkclXXXX the actual offset is at the start of the auth verifier ***
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_resp(const char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth)
-{
- if (rsp == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_resp");
- depth++;
-
- if (ps->io) {
- uint32 old_offset;
-
- /* reading */
-
- ZERO_STRUCTP(rsp);
-
- if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_domain ", &rsp->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_user ", &rsp->hdr_usr, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_wks ", &rsp->hdr_wks, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
- return False;
-
- if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- old_offset = prs_offset(ps);
-
- if(!prs_set_offset(ps, rsp->hdr_domain.buffer + 0xc))
- return False;
-
- if(!prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain,
- MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
- return False;
-
- old_offset += rsp->hdr_domain.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_usr.buffer + 0xc))
- return False;
-
- if(!prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user,
- MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
- return False;
-
- old_offset += rsp->hdr_usr.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_wks.buffer + 0xc))
- return False;
-
- if(!prs_uint8s(True, "wks ", ps, depth, (uint8*)rsp->wks,
- MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
- return False;
-
- old_offset += rsp->hdr_wks.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_lm_resp.buffer + 0xc))
- return False;
-
- if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
- MIN(rsp->hdr_lm_resp.str_str_len, sizeof(rsp->lm_resp ))))
- return False;
-
- old_offset += rsp->hdr_lm_resp.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_nt_resp.buffer + 0xc))
- return False;
-
- if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
- MIN(rsp->hdr_nt_resp.str_str_len, sizeof(rsp->nt_resp ))))
- return False;
-
- old_offset += rsp->hdr_nt_resp.str_str_len;
-
- if (rsp->hdr_sess_key.str_str_len != 0) {
-
- if(!prs_set_offset(ps, rsp->hdr_sess_key.buffer + 0x10))
- return False;
-
- old_offset += rsp->hdr_sess_key.str_str_len;
-
- if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
- MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
- return False;
- }
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- } else {
- /* writing */
- if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_domain ", &rsp->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_user ", &rsp->hdr_usr, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_wks ", &rsp->hdr_wks, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
- return False;
-
- if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- if(!prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain,
- MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
- return False;
-
- if(!prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user,
- MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
- return False;
-
- if(!prs_uint8s(True , "wks ", ps, depth, (uint8*)rsp->wks,
- MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
- return False;
- if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
- MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp))))
- return False;
- if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
- MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp ))))
- return False;
- if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
- MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Checks an RPC_AUTH_NTLMSSP_CHK structure.
-********************************************************************/
-
-BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num)
-{
- if (chk == NULL)
- return False;
-
- if (chk->crc32 != crc32 ||
- chk->ver != NTLMSSP_SIGN_VERSION ||
- chk->seq_num != seq_num)
- {
- DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
- chk->crc32, chk->ver, chk->seq_num));
-
- DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
- crc32, NTLMSSP_SIGN_VERSION, seq_num));
- return False;
- }
- return True;
-}
-
-/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_CHK structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
- uint32 ver, uint32 crc32, uint32 seq_num)
-{
- chk->ver = ver;
- chk->reserved = 0x0;
- chk->crc32 = crc32;
- chk->seq_num = seq_num;
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
+creates an RPC_AUTH_SCHANNEL_NEG structure.
********************************************************************/
-BOOL smb_io_rpc_auth_ntlmssp_chk(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth)
-{
- if (chk == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chk");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ver ", ps, depth, &chk->ver))
- return False;
- if(!prs_uint32("reserved", ps, depth, &chk->reserved))
- return False;
- if(!prs_uint32("crc32 ", ps, depth, &chk->crc32))
- return False;
- if(!prs_uint32("seq_num ", ps, depth, &chk->seq_num))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-creates an RPC_AUTH_NETSEC_NEG structure.
-********************************************************************/
-void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
+void init_rpc_auth_schannel_neg(RPC_AUTH_SCHANNEL_NEG *neg,
const char *domain, const char *myname)
{
neg->type1 = 0;
@@ -1224,16 +801,16 @@ void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
}
/*******************************************************************
- Reads or writes an RPC_AUTH_NETSEC_NEG structure.
+ Reads or writes an RPC_AUTH_SCHANNEL_NEG structure.
********************************************************************/
-BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg,
+BOOL smb_io_rpc_auth_schannel_neg(const char *desc, RPC_AUTH_SCHANNEL_NEG *neg,
prs_struct *ps, int depth)
{
if (neg == NULL)
return False;
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_neg");
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_neg");
depth++;
if(!prs_align(ps))
@@ -1252,16 +829,17 @@ BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg,
}
/*******************************************************************
-reads or writes an RPC_AUTH_NETSEC_CHK structure.
+reads or writes an RPC_AUTH_SCHANNEL_CHK structure.
********************************************************************/
-BOOL smb_io_rpc_auth_netsec_chk(const char *desc, int auth_len,
- RPC_AUTH_NETSEC_CHK * chk,
+
+BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
+ RPC_AUTH_SCHANNEL_CHK * chk,
prs_struct *ps, int depth)
{
if (chk == NULL)
return False;
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk");
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_chk");
depth++;
if ( !prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig)) )
@@ -1273,7 +851,7 @@ BOOL smb_io_rpc_auth_netsec_chk(const char *desc, int auth_len,
if ( !prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)) )
return False;
- if ( auth_len == RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN ) {
+ if ( auth_len == RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN ) {
if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) )
return False;
}
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 6b0193c6e4..1aaebf71e3 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -25,8 +25,6 @@
*/
#include "includes.h"
-#include "rpc_parse.h"
-#include "nterr.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
@@ -7038,9 +7036,9 @@ inits a SAMR_R_GET_DOM_PWINFO structure.
void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
const char *dest_host, const char *user_name,
- const char nt_newpass[516],
+ const uchar nt_newpass[516],
const uchar nt_oldhash[16],
- const char lm_newpass[516],
+ const uchar lm_newpass[516],
const uchar lm_oldhash[16])
{
DEBUG(5, ("init_samr_q_chgpasswd_user\n"));
diff --git a/source3/rpc_parse/parse_svcctl.c b/source3/rpc_parse/parse_svcctl.c
index b86ca23df1..e1a7ad8427 100644
--- a/source3/rpc_parse/parse_svcctl.c
+++ b/source3/rpc_parse/parse_svcctl.c
@@ -100,40 +100,48 @@ static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config,
return True;
}
+
/*******************************************************************
********************************************************************/
-BOOL svcctl_io_service_description( const char *desc, UNISTR2 *svcdesc, prs_struct *ps, int depth )
+BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth )
{
-
- prs_debug(ps, depth, desc, "svcctl_io_service_description");
+ prs_struct *ps=&buffer->prs;
+
+ prs_debug(ps, depth, desc, "svcctl_io_enum_services_status");
depth++;
-
- if (!prs_io_unistr2("", ps, depth, svcdesc))
+
+ 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;
}
-
/*******************************************************************
********************************************************************/
-BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth )
+BOOL svcctl_io_service_status_process( const char *desc, SERVICE_STATUS_PROCESS *status, RPC_BUFFER *buffer, int depth )
{
prs_struct *ps=&buffer->prs;
-
- prs_debug(ps, depth, desc, "svcctl_io_enum_services_status");
+
+ prs_debug(ps, depth, desc, "svcctl_io_service_status_process");
depth++;
-
- if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) )
+
+ if ( !svcctl_io_service_status("status", &status->status, ps, depth) )
return False;
- if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) )
+ if(!prs_align(ps))
return False;
- if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) )
+ if(!prs_uint32("process_id", ps, depth, &status->process_id))
return False;
-
+ if(!prs_uint32("service_flags", ps, depth, &status->service_flags))
+ return False;
+
return True;
}
@@ -151,6 +159,45 @@ uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status )
return size;
}
+/********************************************************************
+********************************************************************/
+
+static uint32 sizeof_unistr2( UNISTR2 *string )
+{
+ uint32 size = 0;
+
+ if ( !string )
+ return 0;
+
+ size = sizeof(uint32) * 3; /* length fields */
+ size += 2 * string->uni_max_len; /* string data */
+ size += size % 4; /* alignment */
+
+ return size;
+}
+
+/********************************************************************
+********************************************************************/
+
+uint32 svcctl_sizeof_service_config( SERVICE_CONFIG *config )
+{
+ uint32 size = 0;
+
+ size = sizeof(uint32) * 4; /* static uint32 fields */
+
+ /* now add the UNISTR2 + pointer sizes */
+
+ size += sizeof(uint32) * sizeof_unistr2(config->executablepath);
+ size += sizeof(uint32) * sizeof_unistr2(config->loadordergroup);
+ size += sizeof(uint32) * sizeof_unistr2(config->dependencies);
+ size += sizeof(uint32) * sizeof_unistr2(config->startname);
+ size += sizeof(uint32) * sizeof_unistr2(config->displayname);
+
+ return size;
+}
+
+
+
/*******************************************************************
********************************************************************/
@@ -694,7 +741,7 @@ BOOL svcctl_io_q_query_service_config2(const char *desc, SVCCTL_Q_QUERY_SERVICE_
if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
return False;
- if(!prs_uint32("info_level", ps, depth, &q_u->info_level))
+ if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
@@ -705,39 +752,148 @@ BOOL svcctl_io_q_query_service_config2(const char *desc, SVCCTL_Q_QUERY_SERVICE_
/*******************************************************************
- Creates a service description response buffer.
- The format seems to be DWORD:length of buffer
- DWORD:offset (fixed as four)
- UNISTR: unicode description in the rest of the buffer
********************************************************************/
-void init_service_description_buffer(RPC_DATA_BLOB *str, const char *service_desc, int blob_length)
+void init_service_description_buffer(SERVICE_DESCRIPTION *desc, const char *service_desc )
{
- uint32 offset;
- uint8 *bp;
+ desc->unknown = 0x04; /* always 0x0000 0004 (no idea what this is) */
+ init_unistr( &desc->description, service_desc );
+}
- ZERO_STRUCTP(str);
+/*******************************************************************
+********************************************************************/
- offset = 4;
+BOOL svcctl_io_service_description( const char *desc, SERVICE_DESCRIPTION *description, RPC_BUFFER *buffer, int depth )
+{
+ prs_struct *ps = &buffer->prs;
- /* set up string lengths. */
+ prs_debug(ps, depth, desc, "svcctl_io_service_description");
+ depth++;
- str->buf_len = create_rpc_blob(str, blob_length);
- DEBUG(10, ("init_service_description buffer: Allocated a blob of [%d] \n",str->buf_len));
+ if ( !prs_uint32("unknown", ps, depth, &description->unknown) )
+ return False;
+ if ( !prs_unistr("description", ps, depth, &description->description) )
+ return False;
- if ( str && str->buffer && str->buf_len) {
- memset(str->buffer,0,str->buf_len);
- memcpy(str->buffer, &offset, sizeof(uint32));
- bp = &str->buffer[4];
- if (service_desc) {
- rpcstr_push(bp, service_desc,str->buf_len-4,0);
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+uint32 svcctl_sizeof_service_description( SERVICE_DESCRIPTION *desc )
+{
+ if ( !desc )
+ return 0;
+
+ /* make sure to include the terminating NULL */
+ return ( sizeof(uint32) + (2*(str_len_uni(&desc->description)+1)) );
+}
+
+/*******************************************************************
+********************************************************************/
+
+static BOOL svcctl_io_action( const char *desc, SC_ACTION *action, prs_struct *ps, int depth )
+{
+
+ prs_debug(ps, depth, desc, "svcctl_io_action");
+ depth++;
+
+ if ( !prs_uint32("type", ps, depth, &action->type) )
+ return False;
+ if ( !prs_uint32("delay", ps, depth, &action->delay) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_service_fa( const char *desc, SERVICE_FAILURE_ACTIONS *fa, RPC_BUFFER *buffer, int depth )
+{
+ prs_struct *ps = &buffer->prs;
+ int i;
+
+ prs_debug(ps, depth, desc, "svcctl_io_service_description");
+ depth++;
+
+ if ( !prs_uint32("reset_period", ps, depth, &fa->reset_period) )
+ return False;
+
+ if ( !prs_pointer( desc, ps, depth, (void**)&fa->rebootmsg, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
+ return False;
+ if ( !prs_pointer( desc, ps, depth, (void**)&fa->command, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
+ return False;
+
+ if ( !prs_uint32("num_actions", ps, depth, &fa->num_actions) )
+ return False;
+
+ if ( UNMARSHALLING(ps) && fa->num_actions ) {
+ if ( !(fa->actions = TALLOC_ARRAY( get_talloc_ctx(), SC_ACTION, fa->num_actions )) ) {
+ DEBUG(0,("svcctl_io_service_fa: talloc() failure!\n"));
+ return False;
}
}
+
+ for ( i=0; i<fa->num_actions; i++ ) {
+ if ( !svcctl_io_action( "actions", &fa->actions[i], ps, depth ) )
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
+uint32 svcctl_sizeof_service_fa( SERVICE_FAILURE_ACTIONS *fa)
+{
+ uint32 size = 0;
+
+ if ( !fa )
+ return 0;
+
+ size = sizeof(uint32) * 2;
+ size += sizeof_unistr2( fa->rebootmsg );
+ size += sizeof_unistr2( fa->command );
+ size += sizeof(SC_ACTION) * fa->num_actions;
+
+ return size;
}
/*******************************************************************
********************************************************************/
+BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config2");
+ 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_werror("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+********************************************************************/
+
BOOL svcctl_io_q_query_service_status_ex(const char *desc, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, prs_struct *ps, int depth)
{
if (q_u == NULL)
@@ -752,7 +908,7 @@ BOOL svcctl_io_q_query_service_status_ex(const char *desc, SVCCTL_Q_QUERY_SERVIC
if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth))
return False;
- if(!prs_uint32("info_level", ps, depth, &q_u->info_level))
+ if(!prs_uint32("level", ps, depth, &q_u->level))
return False;
if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
@@ -771,7 +927,7 @@ BOOL svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVIC
return False;
prs_debug(ps, depth, desc, "svcctl_io_r_query_service_status_ex");
- depth++;
+ depth++;
if (!prs_rpcbuffer("", ps, depth, &r_u->buffer))
return False;
@@ -791,37 +947,80 @@ BOOL svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVIC
/*******************************************************************
********************************************************************/
-BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u, prs_struct *ps, int depth)
+BOOL svcctl_io_q_lock_service_db(const char *desc, SVCCTL_Q_LOCK_SERVICE_DB *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_lock_service_db");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("scm_handle", &q_u->handle, ps, depth))
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_lock_service_db(const char *desc, SVCCTL_R_LOCK_SERVICE_DB *r_u, prs_struct *ps, int depth)
{
if ( !r_u )
return False;
- prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config2");
+ prs_debug(ps, depth, desc, "svcctl_io_r_lock_service_db");
depth++;
if(!prs_align(ps))
return False;
- if(!prs_uint32("returned", ps, depth, &r_u->returned))
+ if(!smb_io_pol_hnd("lock_handle", &r_u->h_lock, ps, depth))
return False;
- if (r_u->returned > 4) {
- if (!prs_uint32("offset", ps, depth, &r_u->offset))
- return False;
+ if(!prs_werror("status", ps, depth, &r_u->status))
+ return False;
- if ( !prs_pointer( desc, ps, depth, (void**)&r_u->description, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
- return False;
+ return True;
+}
- if(!prs_align(ps))
- return False;
- } else {
- /* offset does double duty here */
- r_u->offset = 0;
- if (!prs_uint32("offset", ps, depth, &r_u->offset))
- return False;
- }
+/*******************************************************************
+********************************************************************/
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
+BOOL svcctl_io_q_unlock_service_db(const char *desc, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_q_unlock_service_db");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("h_lock", &q_u->h_lock, ps, depth))
+ return False;
+
+ return True;
+
+}
+
+/*******************************************************************
+********************************************************************/
+
+BOOL svcctl_io_r_unlock_service_db(const char *desc, SVCCTL_R_UNLOCK_SERVICE_DB *r_u, prs_struct *ps, int depth)
+{
+ if ( !r_u )
+ return False;
+
+ prs_debug(ps, depth, desc, "svcctl_io_r_unlock_service_db");
+ depth++;
+
+ if(!prs_align(ps))
return False;
if(!prs_werror("status", ps, depth, &r_u->status))
@@ -831,3 +1030,5 @@ BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_
}
+
+
diff --git a/source3/rpc_server/srv_eventlog.c b/source3/rpc_server/srv_eventlog.c
index 65b10e8fe4..ae15d43f4b 100644
--- a/source3/rpc_server/srv_eventlog.c
+++ b/source3/rpc_server/srv_eventlog.c
@@ -27,7 +27,6 @@ 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;
@@ -53,7 +52,6 @@ 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;
@@ -79,7 +77,6 @@ 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;
@@ -105,7 +102,6 @@ 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;
@@ -131,7 +127,6 @@ 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;
@@ -157,7 +152,6 @@ 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;
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index a9b0c9bed8..414c99d28e 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -1,7 +1,8 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Marcin Krzysztof Porwit 2005.
+ * Copyright (C) Marcin Krzysztof Porwit 2005,
+ * 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
@@ -23,56 +24,152 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
-typedef struct eventlog_info
+typedef struct {
+ char *logname;
+ char *servername;
+ uint32 num_records;
+ uint32 oldest_entry;
+ uint32 flags;
+} EventlogInfo;
+
+
+/********************************************************************
+ Inform the external eventlog machinery of default values (on startup
+ probably)
+********************************************************************/
+
+void eventlog_refresh_external_parameters( NT_USER_TOKEN *token )
{
- /* 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;
- uint32 active_entry;
- uint32 flags;
-} Eventlog_info;
+ const char **elogs = lp_eventlog_list();
+ int i;
+
+ if ( !elogs )
+ return ;
+
+ if ( !*lp_eventlog_control_cmd() )
+ return;
+
+ for ( i=0; elogs[i]; i++ ) {
+
+ DEBUG(10,("eventlog_refresh_external_parameters: Refreshing =>[%s]\n",
+ elogs[i]));
+
+ if ( !control_eventlog_hook( token, elogs[i] ) ) {
+ DEBUG(0,("eventlog_refresh_external_parameters: failed to refresh [%s]\n",
+ elogs[i]));
+ }
+ }
+
+ return;
+}
+
+/********************************************************************
+********************************************************************/
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);
+ TALLOC_FREE( ptr );
}
-static Eventlog_info *find_eventlog_info_by_hnd(pipes_struct *p,
- POLICY_HND *handle)
+/********************************************************************
+********************************************************************/
+
+static EventlogInfo *find_eventlog_info_by_hnd(pipes_struct *p, POLICY_HND *handle)
{
- Eventlog_info *info = NULL;
+ EventlogInfo *info;
- if(!(find_policy_by_hnd(p,handle,(void **)&info)))
- {
- DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
- }
+ if ( !find_policy_by_hnd(p,handle,(void **)&info) ) {
+ DEBUG(2,("find_eventlog_info_by_hnd: eventlog not found.\n"));
+ return NULL;
+ }
- return info;
+ return info;
}
-void policy_handle_to_string(POLICY_HND *handle, fstring *dest)
+/********************************************************************
+ Callout to control the specified event log - passing out only
+ the MaxSize and Retention values, along with eventlog name
+ uses smbrun...
+ INPUT: <control_cmd> <log name> <retention> <maxsize>
+ OUTPUT: nothing
+********************************************************************/
+
+BOOL control_eventlog_hook(NT_USER_TOKEN *token, const char *elogname )
{
- 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]);
+ char *cmd = lp_eventlog_control_cmd();
+ pstring command;
+ int ret;
+ int fd = -1;
+ uint32 uiMaxSize, uiRetention;
+ pstring path;
+ REGISTRY_KEY *keyinfo;
+ REGISTRY_VALUE *val;
+ REGVAL_CTR *values;
+ WERROR wresult;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("control_eventlog_hook: No \"eventlog control command\" defined in smb.conf!\n"));
+ return False;
+ }
+
+ /* set resonable defaults. 512Kb on size and 1 week on time */
+
+ uiMaxSize = 0x80000;
+ uiRetention = 604800;
+
+ /* the general idea is to internally open the registry
+ key and retreive the values. That way we can continue
+ to use the same fetch/store api that we use in
+ srv_reg_nt.c */
+
+ pstr_sprintf( path, "%s/%s", KEY_EVENTLOG, elogname );
+ wresult = regkey_open_internal( &keyinfo, path, token, REG_KEY_READ );
+
+ if ( !W_ERROR_IS_OK( wresult ) ) {
+ DEBUG(4,("control_eventlog_hook: Failed to open key [%s] (%s)\n",
+ path, dos_errstr(wresult) ));
+ return False;
+ }
+
+ if ( !(values = TALLOC_ZERO_P( keyinfo, REGVAL_CTR )) ) {
+ TALLOC_FREE( keyinfo );
+ DEBUG(0,("control_eventlog_hook: talloc() failed!\n"));
+
+ return False;
+ }
+ fetch_reg_values( keyinfo, values );
+
+ if ( (val = regval_ctr_getvalue( values, "Retention" )) != NULL )
+ uiRetention = IVAL( regval_data_p(val), 0 );
+
+ if ( (val = regval_ctr_getvalue( values, "MaxSize" )) != NULL )
+ uiMaxSize = IVAL( regval_data_p(val), 0 );
+
+ TALLOC_FREE( keyinfo );
+
+ /* now run the command */
+
+ pstr_sprintf(command, "%s \"%s\" %u %u", cmd, elogname, uiRetention, uiMaxSize );
+
+ DEBUG(10, ("control_eventlog_hook: Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
+
+ if ( ret != 0 ) {
+ DEBUG(10,("control_eventlog_hook: Command returned [%d]\n", ret));
+ if (fd != -1 )
+ close(fd);
+ return False;
+ }
+
+ close(fd);
+ return True;
}
+
+/********************************************************************
+********************************************************************/
+
/**
* Callout to open the specified event log
*
@@ -81,109 +178,53 @@ void policy_handle_to_string(POLICY_HND *handle, fstring *dest)
* 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)
+static BOOL open_eventlog_hook( EventlogInfo *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;
- }
+ char *cmd = lp_eventlog_open_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog open command\" entry in the config.\n"));
+ return False;
+ }
+
+ pstr_sprintf(command, "%s \"%s\"", cmd, info->logname );
- qlines = fd_lines_load(fd, &numlines);
- DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
- close(fd);
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
- 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;
+ if(ret != 0) {
+ if(fd != -1) {
+ close(fd);
+ }
+ return False;
}
- }
- file_lines_free(qlines);
- return False;
-}
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
-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))
- {
- free_eventlog_info(info);
- return WERR_NOMEM;
- }
-
- policy_handle_to_string(&r_u->handle, &info->handle_string);
-
- if(!(_eventlog_open_eventlog_hook(info)))
- {
- close_policy_hnd(p, &r_u->handle);
- return WERR_BADFILE;
- }
-
- return WERR_OK;
+ 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->logname));
+ file_lines_free(qlines);
+ return True;
+ }
+ }
+
+ file_lines_free(qlines);
+
+ return False;
}
+
+/********************************************************************
+********************************************************************/
/**
* Callout to get the number of records in the specified event log
*
@@ -192,74 +233,52 @@ WERROR _eventlog_open_eventlog(pipes_struct *p,
* 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);
+static BOOL get_num_records_hook(EventlogInfo *info)
+{
+ char *cmd = lp_eventlog_num_records_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog num records command\" entry in the config.\n"));
+ return False;
+ }
- if(numlines)
- {
- DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
- sscanf(qlines[0], "%d", &(info->num_records));
- file_lines_free(qlines);
- return True;
- }
+ pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
- file_lines_free(qlines);
- return False;
-}
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
-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(ret != 0) {
+ if(fd != -1) {
+ close(fd);
+ }
+ return False;
+ }
- if(!q_u || !r_u)
- return WERR_NOMEM;
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
- handle = &(q_u->handle);
- info = find_eventlog_info_by_hnd(p, handle);
+ if(numlines) {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ sscanf(qlines[0], "%d", &(info->num_records));
+ file_lines_free(qlines);
+ return True;
+ }
- if(!(_eventlog_get_num_records_hook(info)))
- return WERR_BADFILE;
+ file_lines_free(qlines);
+ return False;
+}
- r_u->num_records = info->num_records;
+/********************************************************************
+********************************************************************/
- return WERR_OK;
-}
/**
* Callout to find the oldest record in the log
*
@@ -269,75 +288,51 @@ WERROR _eventlog_get_num_records(pipes_struct *p,
* 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)
+static BOOL get_oldest_entry_hook(EventlogInfo *info)
{
- Eventlog_info *info = NULL;
- POLICY_HND *handle = NULL;
+ char *cmd = lp_eventlog_oldest_record_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog oldest record command\" entry in the config.\n"));
+ return False;
+ }
+
+ pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
- if(!q_u || !r_u)
- return WERR_NOMEM;
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
- handle = &(q_u->handle);
- info = find_eventlog_info_by_hnd(p, handle);
+ if(ret != 0) {
+ if(fd != -1) {
+ close(fd);
+ }
+ return False;
+ }
- if(!(_eventlog_get_oldest_entry_hook(info)))
- return WERR_BADFILE;
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
- r_u->oldest_entry = info->oldest_entry;
+ if(numlines) {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ sscanf(qlines[0], "%d", &(info->oldest_entry));
+ file_lines_free(qlines);
+ return True;
+ }
- return WERR_OK;
+ file_lines_free(qlines);
+ return False;
}
+/********************************************************************
+********************************************************************/
/**
* Callout to close the specified event log
*
@@ -346,270 +341,206 @@ WERROR _eventlog_get_oldest_entry(pipes_struct *p,
* 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)
+
+static BOOL close_eventlog_hook(EventlogInfo *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;
- }
+ char *cmd = lp_eventlog_close_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog close command\" entry in the config.\n"));
+ return False;
+ }
- qlines = fd_lines_load(fd, &numlines);
- DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
- close(fd);
+ pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
- 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;
- }
- }
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
- file_lines_free(qlines);
- return False;
-}
+ if(ret != 0) {
+ if(fd != -1) {
+ close(fd);
+ }
+ 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;
+ qlines = fd_lines_load(fd, &numlines);
+ DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
+ close(fd);
- if(!q_u || !r_u)
- return WERR_NOMEM;
+ if(numlines) {
+ DEBUGADD(10, ("Line[0] = [%s]\n", qlines[0]));
+ if(0 == strncmp(qlines[0], "SUCCESS", 7)) {
+ DEBUGADD(10, ("Able to close [%s].\n", info->logname));
+ file_lines_free(qlines);
+ return True;
+ }
+ }
- 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;
+ file_lines_free(qlines);
+ return False;
}
-static BOOL _eventlog_read_parse_line(char *line, Eventlog_entry *entry, BOOL *eor)
+/********************************************************************
+********************************************************************/
+
+static BOOL parse_logentry(char *line, Eventlog_entry *entry, BOOL *eor)
{
- char *start = NULL, *stop = NULL;
- pstring temp;
- int temp_len = 0, i;
+ char *start = NULL, *stop = NULL;
+ pstring temp;
+ int temp_len = 0, i;
- start = line;
+ start = line;
- /* empty line signyfiying record delimeter, or we're at the end of the buffer */
- if(start == NULL || strlen(start) == 0)
- {
- DEBUG(6, ("_eventlog_read_parse_line: found end-of-record indicator.\n"));
- *eor = True;
- return True;
- }
- if(!(stop = strchr(line, ':')))
- return False;
+ /* empty line signyfiying record delimeter, or we're at the end of the buffer */
+ if(start == NULL || strlen(start) == 0) {
+ DEBUG(6, ("parse_logentry: found end-of-record indicator.\n"));
+ *eor = True;
+ return True;
+ }
+ 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;
- }
- }
+ DEBUG(6, ("parse_logentry: 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, "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));
- stop++;
- while(isspace(stop[0]))
- stop++;
- temp_len = strlen(stop);
- strncpy(temp, stop, temp_len);
- 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));
- stop++;
- while(isspace(stop[0]))
- stop++;
- temp_len = strlen(stop);
- strncpy(temp, stop, temp_len);
- 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));
- stop++;
- while(isspace(stop[0]))
- stop++;
- temp_len = strlen(stop);
- strncpy(temp, stop, temp_len);
- 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. */
+ 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));
+ stop++;
+ while(isspace(stop[0])) {
+ stop++;
+ }
+ temp_len = strlen(stop);
+ strncpy(temp, stop, temp_len);
+ 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));
+ stop++;
+ while(isspace(stop[0])) {
+ stop++;
+ }
+ temp_len = strlen(stop);
+ strncpy(temp, stop, temp_len);
+ 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));
+ stop++;
+ while(isspace(stop[0])) {
+ stop++;
+ }
+ temp_len = strlen(stop);
+ strncpy(temp, stop, temp_len);
+ 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++;
+ }
+ entry->data_record.user_data_len = strlen(stop);
+ memset(entry->data_record.user_data, 0, sizeof(entry->data_record.user_data));
+ if(entry->data_record.user_data_len > 0) {
+ /* copy no more than the first 1024 bytes */
+ if(entry->data_record.user_data_len > sizeof(entry->data_record.user_data))
+ entry->data_record.user_data_len = sizeof(entry->data_record.user_data);
+ memcpy(entry->data_record.user_data, stop, entry->data_record.user_data_len);
+ }
+ } 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;
- }
- return True;
}
+
+/********************************************************************
+********************************************************************/
+
/**
* Callout to read entries from the specified event log
*
@@ -640,254 +571,162 @@ static BOOL _eventlog_read_parse_line(char *line, Eventlog_entry *entry, BOOL *e
* DAT:[(uint8)] - The user-defined data portion of the event log. Can not be multiple lines.
* <empty line> - end-of-record indicator
*/
-static BOOL _eventlog_read_eventlog_hook(Eventlog_info *info,
- Eventlog_entry *entry,
- const char *direction,
- int starting_record,
- int buffer_size,
- BOOL *eof,
- char ***buffer,
- int *numlines)
+
+static BOOL read_eventlog_hook(EventlogInfo *info, Eventlog_entry *entry,
+ const char *direction, int starting_record,
+ int buffer_size, BOOL *eof,
+ char ***buffer, int *numlines)
{
- char *cmd = lp_eventlog_read_cmd();
- pstring command;
- int ret;
- int fd = -1;
+ char *cmd = lp_eventlog_read_cmd();
+ pstring command;
+ int ret;
+ int fd = -1;
- if(info == NULL)
- return False;
+ if ( !info )
+ 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);
-
- *numlines = 0;
-
- 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;
- }
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog read command\" entry in the config.\n"));
+ return False;
+ }
- *buffer = fd_lines_load(fd, numlines);
- DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
- close(fd);
+ pstr_sprintf( command, "%s \"%s\" %s %d %d",
+ cmd, info->logname, direction, starting_record, buffer_size );
+
+ *numlines = 0;
+
+ 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;
+ }
+
+ *buffer = 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);
+ if(*numlines) {
+ /*
+ for(i = 0; i < numlines; i++)
+ {
+ DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
+ parse_logentry(qlines[i], entry);
+ }
+ file_lines_free(qlines);
+ */
+ *eof = False;
+ return True;
}
- file_lines_free(qlines);
- */
- *eof = False;
- return True;
- }
- *eof = True;
+ *eof = True;
/* file_lines_free(qlines);*/
- return False;
+ return False;
}
-
-static Eventlog_entry *_eventlog_read_package_entry(prs_struct *ps,
+
+/********************************************************************
+********************************************************************/
+
+static Eventlog_entry *read_package_entry(prs_struct *ps,
EVENTLOG_Q_READ_EVENTLOG *q_u,
EVENTLOG_R_READ_EVENTLOG *r_u,
Eventlog_entry *entry)
{
- uint8 *offset;
- Eventlog_entry *ee_new = NULL;
-
- ee_new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
- if(ee_new == NULL)
- return NULL;
-
- 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 NULL;
- 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;
-
- memcpy(&(ee_new->record), &entry->record, sizeof(Eventlog_record));
- memcpy(&(ee_new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
- ee_new->data = entry->data;
-
- return ee_new;
-}
+ uint8 *offset;
+ Eventlog_entry *ee_new = NULL;
-static BOOL _eventlog_add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee_new)
-{
- Eventlog_entry *insert_point;
-
- insert_point=r_u->entry;
-
- if (NULL == insert_point)
- {
- r_u->entry = ee_new;
- ee_new->next = NULL;
- }
- else
- {
- while ((NULL != insert_point->next))
- {
- insert_point=insert_point->next;
- }
- ee_new->next = NULL;
- insert_point->next = ee_new;
- }
- r_u->num_records++;
- r_u->num_bytes_in_resp += ee_new->record.length;
-
- return True;
+ ee_new = PRS_ALLOC_MEM(ps, Eventlog_entry, 1);
+ if(ee_new == NULL) {
+ return NULL;
+ }
+
+ 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 NULL;
+ }
+ 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;
+
+ memcpy(&(ee_new->record), &entry->record, sizeof(Eventlog_record));
+ memcpy(&(ee_new->data_record), &entry->data_record, sizeof(Eventlog_data_record));
+ ee_new->data = entry->data;
+
+ return ee_new;
}
-
-WERROR _eventlog_read_eventlog(pipes_struct *p,
- EVENTLOG_Q_READ_EVENTLOG *q_u,
- EVENTLOG_R_READ_EVENTLOG *r_u)
+
+/********************************************************************
+********************************************************************/
+
+static BOOL add_record_to_resp(EVENTLOG_R_READ_EVENTLOG *r_u, Eventlog_entry *ee_new)
{
- Eventlog_info *info = NULL;
- POLICY_HND *handle;
- Eventlog_entry entry, *ee_new;
- BOOL eof = False, eor = False;
- const char *direction = "";
- uint32 num_records_read = 0;
- prs_struct *ps;
- int numlines, i;
- char **buffer;
-
- if(!q_u || !r_u)
- return WERR_NOMEM;
-
- handle = &(q_u->handle);
- info = find_eventlog_info_by_hnd(p, handle);
- info->flags = q_u->flags;
- ps = &p->out_data.rdata;
- /* if this is the first time we're reading on this handle */
- if(info->active_entry == 0)
- {
- /* 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)
- info->active_entry = q_u->offset;
- else
- info->active_entry = info->oldest_entry;
-
- }
-
- if(q_u->flags & EVENTLOG_FORWARDS_READ)
- direction = "forward";
- else if(q_u->flags & EVENTLOG_BACKWARDS_READ)
- direction = "backward";
-
- if(!(_eventlog_read_eventlog_hook(info, &entry, direction, info->active_entry, q_u->max_read_size, &eof, &buffer, &numlines)))
- {
- if(eof == False)
- return WERR_NOMEM;
- }
- if(numlines > 0)
- {
- ZERO_STRUCT(entry);
- for(i = 0; i < numlines; i++)
- {
- num_records_read = r_u->num_records;
- DEBUGADD(10, ("Line[%d] = [%s]\n", i, buffer[i]));
- _eventlog_read_parse_line(buffer[i], &entry, &eor);
- if(eor == True)
- {
- /* package ee_new entry */
- if((ee_new = _eventlog_read_package_entry(ps, q_u, r_u, &entry)) == NULL)
- {
- free(buffer);
- return WERR_NOMEM;
- }
- /* Now see if there is enough room to add */
- if(r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size)
- {
- r_u->bytes_in_next_record = ee_new->record.length;
- /* response would be too big to fit in client-size buffer */
- break;
+ Eventlog_entry *insert_point;
+
+ insert_point=r_u->entry;
+
+ if (NULL == insert_point) {
+ r_u->entry = ee_new;
+ ee_new->next = NULL;
+ } else {
+ while ((NULL != insert_point->next)) {
+ insert_point=insert_point->next;
}
- _eventlog_add_record_to_resp(r_u, ee_new);
- ZERO_STRUCT(entry);
- eor=False;
- num_records_read = r_u->num_records - num_records_read;
- DEBUG(10, ("_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
- num_records_read,
- r_u->num_records,
- r_u->num_bytes_in_resp,
- q_u->max_read_size));
- /* update the active record */
- if(info->flags & EVENTLOG_FORWARDS_READ)
- info->active_entry += num_records_read;
- else if(info->flags & EVENTLOG_BACKWARDS_READ)
- info->active_entry -= num_records_read;
- }
- }
- free(buffer);
- }
-
- return WERR_OK;
+ ee_new->next = NULL;
+ insert_point->next = ee_new;
+ }
+ r_u->num_records++;
+ r_u->num_bytes_in_resp += ee_new->record.length;
+
+ return True;
}
+
+/********************************************************************
+********************************************************************/
+
/**
* Callout to clear (and optionally backup) a specified event log
*
@@ -902,96 +741,224 @@ WERROR _eventlog_read_eventlog(pipes_struct *p,
* 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)
+
+static BOOL clear_eventlog_hook(EventlogInfo *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;
- }
+ char *cmd = lp_eventlog_clear_cmd();
+ char **qlines;
+ pstring command;
+ int numlines = 0;
+ int ret;
+ int fd = -1;
+
+ if ( !cmd || !*cmd ) {
+ DEBUG(0, ("Must define an \"eventlog clear command\" entry in the config.\n"));
+ return False;
+ }
+
+ if ( strlen(backup_file_name) )
+ pstr_sprintf( command, "%s \"%s\" \"%s\"", cmd, info->logname, backup_file_name );
+ else
+ pstr_sprintf( command, "%s \"%s\"", cmd, info->logname );
+
+ DEBUG(10, ("Running [%s]\n", command));
+ ret = smbrun(command, &fd);
+ DEBUGADD(10, ("returned [%d]\n", ret));
- qlines = fd_lines_load(fd, &numlines);
- DEBUGADD(10, ("Lines returned = [%d]\n", numlines));
- close(fd);
+ if(ret != 0) {
+ if(fd != -1) {
+ close(fd);
+ }
+ return False;
+ }
- 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;
+ 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->logname));
+ file_lines_free(qlines);
+ return True;
+ }
}
- }
- file_lines_free(qlines);
- return False;
+ 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)
+{
+ EventlogInfo *info = NULL;
+ fstring str;
+
+ if ( !(info = TALLOC_ZERO_P(NULL, EventlogInfo)) )
+ return WERR_NOMEM;
+
+ fstrcpy( str, global_myname() );
+ if ( q_u->servername.string ) {
+ rpcstr_pull( str, q_u->servername.string->buffer,
+ sizeof(str), q_u->servername.string->uni_str_len*2, 0 );
+ }
+ info->servername = talloc_strdup( info, str );
+
+ fstrcpy( str, "Application" );
+ if ( q_u->logname.string ) {
+ rpcstr_pull( str, q_u->logname.string->buffer,
+ sizeof(str), q_u->logname.string->uni_str_len*2, 0 );
+ }
+ info->logname = talloc_strdup( info, str );
+
+ DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the server name.\n", info->servername));
+ DEBUG(10, ("_eventlog_open_eventlog: Using [%s] as the source log file.\n", info->logname));
+
+ if ( !create_policy_hnd(p, &r_u->handle, free_eventlog_info, (void *)info) ) {
+ free_eventlog_info(info);
+ return WERR_NOMEM;
+ }
+
+ if ( !(open_eventlog_hook(info)) ) {
+ close_policy_hnd(p, &r_u->handle);
+ return WERR_BADFILE;
+ }
+
+ return WERR_OK;
}
-WERROR _eventlog_clear_eventlog(pipes_struct *p,
- EVENTLOG_Q_CLEAR_EVENTLOG *q_u,
- EVENTLOG_R_CLEAR_EVENTLOG *r_u)
+/********************************************************************
+********************************************************************/
+
+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;
+ EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+ pstring backup_file_name;
- if(!q_u || !r_u)
- return WERR_NOMEM;
+ pstrcpy( backup_file_name, "" );
- handle = &(q_u->handle);
- info = find_eventlog_info_by_hnd(p, handle);
- memset(backup_file_name, 0, sizeof(backup_file_name));
+ if ( q_u->backupfile.string )
+ unistr2_to_ascii(backup_file_name, q_u->backupfile.string, 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;
+ backup_file_name, info->logname));
+
+ if ( !(clear_eventlog_hook(info, backup_file_name)) )
+ return WERR_BADFILE;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _eventlog_close_eventlog(pipes_struct *p, EVENTLOG_Q_CLOSE_EVENTLOG *q_u, EVENTLOG_R_CLOSE_EVENTLOG *r_u)
+{
+ EventlogInfo *info = find_eventlog_info_by_hnd(p,&q_u->handle);
+
+ if ( !(close_eventlog_hook(info)) )
+ return WERR_BADFILE;
+
+ if ( !(close_policy_hnd(p, &q_u->handle)) ) {
+ return WERR_BADFID;
+ }
+
+ return WERR_OK;
}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _eventlog_read_eventlog(pipes_struct *p, EVENTLOG_Q_READ_EVENTLOG *q_u, EVENTLOG_R_READ_EVENTLOG *r_u)
+{
+ EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+ Eventlog_entry entry, *ee_new;
+ BOOL eof = False, eor = False;
+ const char *direction = "";
+ uint32 num_records_read = 0;
+ prs_struct *ps;
+ int numlines, i;
+ char **buffer;
+
+ info->flags = q_u->flags;
+ ps = &p->out_data.rdata;
+
+ if ( info->flags & EVENTLOG_FORWARDS_READ )
+ direction = "forward";
+ else if ( info->flags & EVENTLOG_BACKWARDS_READ )
+ direction = "backward";
+
+ if ( !(read_eventlog_hook(info, &entry, direction, q_u->offset, q_u->max_read_size, &eof, &buffer, &numlines)) ) {
+ if(eof == False) {
+ return WERR_NOMEM;
+ }
+ }
+
+ if(numlines > 0) {
+ ZERO_STRUCT(entry);
+ for(i = 0; i < numlines; i++) {
+ num_records_read = r_u->num_records;
+ DEBUGADD(10, ("Line[%d] = [%s]\n", i, buffer[i]));
+ parse_logentry(buffer[i], &entry, &eor);
+ if(eor == True) {
+ /* package ee_new entry */
+ if((ee_new = read_package_entry(ps, q_u, r_u, &entry)) == NULL) {
+ SAFE_FREE(buffer);
+ return WERR_NOMEM;
+ }
+ /* Now see if there is enough room to add */
+ if(r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size) {
+ r_u->bytes_in_next_record = ee_new->record.length;
+ /* response would be too big to fit in client-size buffer */
+ break;
+ }
+ add_record_to_resp(r_u, ee_new);
+ ZERO_STRUCT(entry);
+ eor=False;
+ num_records_read = r_u->num_records - num_records_read;
+ DEBUG(10, ("_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n",
+ num_records_read,
+ r_u->num_records,
+ r_u->num_bytes_in_resp,
+ q_u->max_read_size));
+ }
+ }
+ SAFE_FREE(buffer);
+ }
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _eventlog_get_oldest_entry(pipes_struct *p, EVENTLOG_Q_GET_OLDEST_ENTRY *q_u, EVENTLOG_R_GET_OLDEST_ENTRY *r_u)
+{
+ EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+
+ if ( !(get_oldest_entry_hook(info)) )
+ return WERR_BADFILE;
+
+ r_u->oldest_entry = info->oldest_entry;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _eventlog_get_num_records(pipes_struct *p, EVENTLOG_Q_GET_NUM_RECORDS *q_u, EVENTLOG_R_GET_NUM_RECORDS *r_u)
+{
+ EventlogInfo *info = find_eventlog_info_by_hnd(p, &q_u->handle);
+
+ if ( !(get_num_records_hook(info)) )
+ return WERR_BADFILE;
+
+ r_u->num_records = info->num_records;
+
+ return WERR_OK;
+}
+
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index 68072b528a..7da87d5b93 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -253,16 +253,18 @@ BOOL pipe_access_check(pipes_struct *p)
user_struct *user = get_valid_user_struct(p->vuid);
/* schannel, so we must be ok */
- if (p->netsec_auth_validated)
+ if (p->pipe_bound && (p->auth.auth_type == PIPE_AUTH_TYPE_SCHANNEL)) {
return True;
+ }
if (!user) {
DEBUG(3, ("invalid vuid %d\n", p->vuid));
return False;
}
- if (user->guest)
+ if (user->guest) {
return False;
+ }
}
return True;
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 021f1dc8e0..15d420538e 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -805,17 +805,12 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV
struct lsa_info *handle;
uint32 i;
uint32 enum_context = q_u->enum_context;
- int num_privs = 0;
+ int num_privs = count_all_privileges();
LSA_PRIV_ENTRY *entries = NULL;
LUID_ATTR luid;
/* remember that the enum_context starts at 0 and not 1 */
- if ( lp_enable_privileges() )
- num_privs = count_all_privileges();
- else
- DEBUG(2,("_lsa_enum_privs: client trying to enumerate privileges by not enabled in smb.conf!\n"));
-
if ( enum_context >= num_privs )
return NT_STATUS_NO_MORE_ENTRIES;
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 15827a8b55..5aefe3ca3c 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -74,6 +74,7 @@ NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u,
/****************************************************************************
Send a message to smbd to do a sam synchronisation
**************************************************************************/
+
static void send_sync_message(void)
{
TDB_CONTEXT *tdb;
@@ -268,26 +269,33 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
-
- rpcstr_pull(p->dc.remote_machine,q_u->uni_logon_clnt.buffer,sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0);
-
- /* create a server challenge for the client */
- /* Set these to random values. */
- generate_random_buffer(p->dc.srv_chal.data, 8);
-
- memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
+ if (!p->dc) {
+ p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo);
+ if (!p->dc) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ DEBUG(10,("_net_req_chal: new challenge requested. Clearing old state.\n"));
+ ZERO_STRUCTP(p->dc);
+ }
- memcpy(p->dc.clnt_chal.data , q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
+ rpcstr_pull(p->dc->remote_machine,
+ q_u->uni_logon_clnt.buffer,
+ sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0);
- memset((char *)p->dc.sess_key, '\0', sizeof(p->dc.sess_key));
+ /* Save the client challenge to the server. */
+ memcpy(p->dc->clnt_chal.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- p->dc.challenge_sent = True;
+ /* Create a server challenge for the client */
+ /* Set this to a random value. */
+ generate_random_buffer(p->dc->srv_chal.data, 8);
+
/* set up the LSA REQUEST CHALLENGE response */
- init_net_r_req_chal(r_u, &p->dc.srv_chal, status);
+ init_net_r_req_chal(r_u, &p->dc->srv_chal, NT_STATUS_OK);
- return status;
+ p->dc->challenge_sent = True;
+
+ return NT_STATUS_OK;
}
/*************************************************************************
@@ -301,50 +309,54 @@ static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS statu
}
/*************************************************************************
- _net_auth
+ _net_auth. Create the initial credentials.
*************************************************************************/
NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
- DOM_CHAL srv_cred;
- UTIME srv_time;
fstring mach_acct;
+ fstring remote_machine;
+ DOM_CHAL srv_chal_out;
- srv_time.time = 0;
-
- rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
+ if (!p->dc || !p->dc->challenge_sent) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
- if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
+ rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),
+ q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
+ rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring),
+ q_u->clnt_id.uni_comp_name.uni_str_len*2,0);
- /* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
- p->dc.md4pw, p->dc.sess_key);
-
- /* check that the client credentials are valid */
- if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
-
- /* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-
- /* Save the machine account name. */
- fstrcpy(p->dc.mach_acct, mach_acct);
-
- p->dc.authenticated = True;
+ if (!get_md4pw((char *)p->dc->mach_pw, mach_acct)) {
+ DEBUG(0,("_net_auth: creds_server_check failed. Failed to "
+ "get pasword for machine account %s "
+ "from client %s\n",
+ mach_acct, remote_machine ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
- } else {
- status = NT_STATUS_ACCESS_DENIED;
- }
- } else {
- status = NT_STATUS_ACCESS_DENIED;
+ /* From the client / server challenges and md4 password, generate sess key */
+ creds_server_init(p->dc,
+ &p->dc->clnt_chal, /* Stored client chal. */
+ &p->dc->srv_chal, /* Stored server chal. */
+ p->dc->mach_pw,
+ &srv_chal_out);
+
+ /* Check client credentials are valid. */
+ if (!creds_server_check(p->dc, &q_u->clnt_chal)) {
+ DEBUG(0,("_net_auth: creds_server_check failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ remote_machine, mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
}
-
+
+ fstrcpy(p->dc->mach_acct, mach_acct);
+ fstrcpy(p->dc->remote_machine, remote_machine);
+ p->dc->authenticated = True;
+
/* set up the LSA AUTH response */
- init_net_r_auth(r_u, &srv_cred, status);
+ /* Return the server credentials. */
+ init_net_r_auth(r_u, &srv_chal_out, NT_STATUS_OK);
return r_u->status;
}
@@ -367,51 +379,54 @@ static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
- DOM_CHAL srv_cred;
- UTIME srv_time;
NEG_FLAGS srv_flgs;
fstring mach_acct;
+ fstring remote_machine;
+ DOM_CHAL srv_chal_out;
- srv_time.time = 0;
+ rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),
+ q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
+ rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring),
+ q_u->clnt_id.uni_comp_name.uni_str_len*2,0);
+
+ if (!p->dc || !p->dc->challenge_sent) {
+ DEBUG(0,("_net_auth2: no challenge sent to client %s\n",
+ remote_machine ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
if ( (lp_server_schannel() == True) &&
((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) {
/* schannel must be used, but client did not offer it. */
- status = NT_STATUS_ACCESS_DENIED;
+ DEBUG(0,("_net_auth2: schannel required but client failed "
+ "to offer it. Client was %s\n",
+ mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
}
- rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring),q_u->clnt_id.uni_acct_name.uni_str_len*2,0);
-
- if (p->dc.challenge_sent && get_md4pw((char *)p->dc.md4pw, mach_acct)) {
-
- /* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&p->dc.clnt_chal, &p->dc.srv_chal,
- p->dc.md4pw, p->dc.sess_key);
-
- /* check that the client credentials are valid */
- if (cred_assert(&q_u->clnt_chal, p->dc.sess_key, &p->dc.clnt_cred.challenge, srv_time)) {
-
- /* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &p->dc.srv_cred.challenge, srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data));
-
- /* Save the machine account name. */
- fstrcpy(p->dc.mach_acct, mach_acct);
-
- p->dc.authenticated = True;
+ if (!get_md4pw((char *)p->dc->mach_pw, mach_acct)) {
+ DEBUG(0,("_net_auth2: failed to get machine password for "
+ "account %s\n",
+ mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
- } else {
- status = NT_STATUS_ACCESS_DENIED;
- }
- } else {
- status = NT_STATUS_ACCESS_DENIED;
+ /* From the client / server challenges and md4 password, generate sess key */
+ creds_server_init(p->dc,
+ &p->dc->clnt_chal, /* Stored client chal. */
+ &p->dc->srv_chal, /* Stored server chal. */
+ p->dc->mach_pw,
+ &srv_chal_out);
+
+ /* Check client credentials are valid. */
+ if (!creds_server_check(p->dc, &q_u->clnt_chal)) {
+ DEBUG(0,("_net_auth2: creds_server_check failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ remote_machine, mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
}
-
+
srv_flgs.neg_flags = 0x000001ff;
if (lp_server_schannel() != False) {
@@ -419,12 +434,11 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
}
/* set up the LSA AUTH 2 response */
- init_net_r_auth_2(r_u, &srv_cred, &srv_flgs, status);
+ init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK);
- if (NT_STATUS_IS_OK(status)) {
- server_auth2_negotiated = True;
- last_dcinfo = p->dc;
- }
+ server_auth2_negotiated = True;
+ p->dc->authenticated = True;
+ last_dcinfo = *p->dc;
return r_u->status;
}
@@ -436,32 +450,39 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
{
NTSTATUS status = NT_STATUS_ACCESS_DENIED;
- DOM_CRED srv_cred;
- pstring workstation;
+ fstring workstation;
SAM_ACCOUNT *sampass=NULL;
BOOL ret = False;
unsigned char pwd[16];
int i;
uint32 acct_ctrl;
+ DOM_CRED cred_out;
const uchar *old_pw;
- /* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred)))
+ if (!p->dc || !p->dc->authenticated) {
return NT_STATUS_INVALID_HANDLE;
+ }
- memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
+ /* Step the creds chain forward. */
+ if (!creds_server_step(p->dc, &q_u->clnt_id.cred, &cred_out)) {
+ DEBUG(0,("_net_srv_pwset: creds_server_step failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ p->dc->remote_machine, p->dc->mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
rpcstr_pull(workstation,q_u->clnt_id.login.uni_comp_name.buffer,
sizeof(workstation),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0);
- DEBUG(3,("Server Password Set by Wksta:[%s] on account [%s]\n", workstation, p->dc.mach_acct));
+ DEBUG(3,("_net_srv_pwset: Server Password Set by Wksta:[%s] on account [%s]\n",
+ workstation, p->dc->mach_acct));
pdb_init_sam(&sampass);
become_root();
- ret=pdb_getsampwnam(sampass, p->dc.mach_acct);
+ ret=pdb_getsampwnam(sampass, p->dc->mach_acct);
unbecome_root();
/* Ensure the account exists and is a machine account. */
@@ -481,7 +502,8 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
return NT_STATUS_ACCOUNT_DISABLED;
}
- cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);
+ /* Woah - what does this to to the credential chain ? JRA */
+ cred_hash3( pwd, q_u->pwd, p->dc->sess_key, 0);
DEBUG(100,("Server password set : new given value was :\n"));
for(i = 0; i < sizeof(pwd); i++)
@@ -498,17 +520,17 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
} else {
/* LM password should be NULL for machines */
- if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) {
+ if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
pdb_free_sam(&sampass);
return NT_STATUS_NO_MEMORY;
}
- if (!pdb_set_nt_passwd (sampass, pwd, PDB_CHANGED)) {
+ if (!pdb_set_nt_passwd(sampass, pwd, PDB_CHANGED)) {
pdb_free_sam(&sampass);
return NT_STATUS_NO_MEMORY;
}
- if (!pdb_set_pass_changed_now (sampass)) {
+ if (!pdb_set_pass_changed_now(sampass)) {
pdb_free_sam(&sampass);
/* Not quite sure what this one qualifies as, but this will do */
return NT_STATUS_UNSUCCESSFUL;
@@ -518,42 +540,41 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
ret = pdb_update_sam_account (sampass);
unbecome_root();
}
- if (ret)
+ if (ret) {
status = NT_STATUS_OK;
+ }
/* set up the LSA Server Password Set response */
- init_net_r_srv_pwset(r_u, &srv_cred, status);
+ init_net_r_srv_pwset(r_u, &cred_out, status);
pdb_free_sam(&sampass);
return r_u->status;
}
-
/*************************************************************************
_net_sam_logoff:
*************************************************************************/
NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u)
{
- DOM_CRED srv_cred;
-
if (!get_valid_user_struct(p->vuid))
return NT_STATUS_NO_SUCH_USER;
- /* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred,
- &q_u->sam_id.client.cred, &srv_cred)))
+ if (!p->dc || !p->dc->authenticated) {
return NT_STATUS_INVALID_HANDLE;
+ }
- /* what happens if we get a logoff for an unknown user? */
- memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
-
- /* XXXX maybe we want to say 'no', reject the client's credentials */
r_u->buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
- r_u->status = NT_STATUS_OK;
+ /* checks and updates credentials. creates reply credentials */
+ if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) {
+ DEBUG(0,("_net_sam_logoff: creds_server_step failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ p->dc->remote_machine, p->dc->mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ r_u->status = NT_STATUS_OK;
return r_u->status;
}
@@ -567,7 +588,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
NTSTATUS status = NT_STATUS_OK;
NET_USER_INFO_3 *usr_info = NULL;
NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr;
- DOM_CRED srv_cred;
UNISTR2 *uni_samlogon_user = NULL;
UNISTR2 *uni_samlogon_domain = NULL;
UNISTR2 *uni_samlogon_workstation = NULL;
@@ -588,26 +608,31 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
r_u->switch_value = 0; /* indicates no info */
r_u->auth_resp = 1; /* authoritative response */
r_u->switch_value = 3; /* indicates type of validation user info */
+ r_u->buffer_creds = 1; /* Ensure we always return server creds. */
if (!get_valid_user_struct(p->vuid))
return NT_STATUS_NO_SUCH_USER;
+ if (!p->dc || !p->dc->authenticated) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
- if ( (lp_server_schannel() == True) && (!p->netsec_auth_validated) ) {
+ if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) {
/* 'server schannel = yes' should enforce use of
schannel, the client did offer it in auth2, but
obviously did not use it. */
+ DEBUG(0,("_net_sam_logoff: client %s not using schannel for netlogon\n",
+ p->dc->remote_machine ));
return NT_STATUS_ACCESS_DENIED;
}
/* checks and updates credentials. creates reply credentials */
- if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
- return NT_STATUS_INVALID_HANDLE;
-
- memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
-
- r_u->buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
+ if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) {
+ DEBUG(0,("_net_sam_logoff: creds_server_step failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ p->dc->remote_machine, p->dc->mach_acct ));
+ return NT_STATUS_ACCESS_DENIED;
+ }
/* find the username */
@@ -692,7 +717,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
nt_workstation, chal,
ctr->auth.id1.lm_owf.data,
ctr->auth.id1.nt_owf.data,
- p->dc.sess_key)) {
+ p->dc->sess_key)) {
status = NT_STATUS_NO_MEMORY;
}
break;
@@ -791,7 +816,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
}
ZERO_STRUCT(netlogon_sess_key);
- memcpy(netlogon_sess_key, p->dc.sess_key, 8);
+ memcpy(netlogon_sess_key, p->dc->sess_key, 8);
if (server_info->user_session_key.length) {
memcpy(user_session_key, server_info->user_session_key.data,
MIN(sizeof(user_session_key), server_info->user_session_key.length));
diff --git a/source3/rpc_server/srv_ntsvcs.c b/source3/rpc_server/srv_ntsvcs.c
new file mode 100644
index 0000000000..48910dbee2
--- /dev/null
+++ b/source3/rpc_server/srv_ntsvcs.c
@@ -0,0 +1,220 @@
+/*
+ * 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_ntsvcs_get_version(pipes_struct *p)
+{
+ NTSVCS_Q_GET_VERSION q_u;
+ NTSVCS_R_GET_VERSION 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(!ntsvcs_io_q_get_version("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_get_version(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_get_version("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_get_device_list_size(pipes_struct *p)
+{
+ NTSVCS_Q_GET_DEVICE_LIST_SIZE q_u;
+ NTSVCS_R_GET_DEVICE_LIST_SIZE 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(!ntsvcs_io_q_get_device_list_size("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_get_device_list_size(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_get_device_list_size("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_get_device_list(pipes_struct *p)
+{
+ NTSVCS_Q_GET_DEVICE_LIST q_u;
+ NTSVCS_R_GET_DEVICE_LIST 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(!ntsvcs_io_q_get_device_list("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_get_device_list(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_get_device_list("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_validate_device_instance(pipes_struct *p)
+{
+ NTSVCS_Q_VALIDATE_DEVICE_INSTANCE q_u;
+ NTSVCS_R_VALIDATE_DEVICE_INSTANCE 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(!ntsvcs_io_q_validate_device_instance("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_validate_device_instance(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_validate_device_instance("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_get_device_reg_property(pipes_struct *p)
+{
+ NTSVCS_Q_GET_DEVICE_REG_PROPERTY q_u;
+ NTSVCS_R_GET_DEVICE_REG_PROPERTY 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(!ntsvcs_io_q_get_device_reg_property("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_get_device_reg_property(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_get_device_reg_property("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_get_hw_profile_info(pipes_struct *p)
+{
+ NTSVCS_Q_GET_HW_PROFILE_INFO q_u;
+ NTSVCS_R_GET_HW_PROFILE_INFO 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(!ntsvcs_io_q_get_hw_profile_info("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_get_hw_profile_info(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_get_hw_profile_info("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_ntsvcs_hw_profile_flags(pipes_struct *p)
+{
+ NTSVCS_Q_HW_PROFILE_FLAGS q_u;
+ NTSVCS_R_HW_PROFILE_FLAGS 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(!ntsvcs_io_q_hw_profile_flags("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _ntsvcs_hw_profile_flags(p, &q_u, &r_u);
+
+ if(!ntsvcs_io_r_hw_profile_flags("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ \PIPE\svcctl commands
+ ********************************************************************/
+
+static struct api_struct api_ntsvcs_cmds[] =
+{
+ { "NTSVCS_GET_VERSION" , NTSVCS_GET_VERSION , api_ntsvcs_get_version },
+ { "NTSVCS_GET_DEVICE_LIST_SIZE" , NTSVCS_GET_DEVICE_LIST_SIZE , api_ntsvcs_get_device_list_size },
+ { "NTSVCS_GET_DEVICE_LIST" , NTSVCS_GET_DEVICE_LIST , api_ntsvcs_get_device_list },
+ { "NTSVCS_VALIDATE_DEVICE_INSTANCE" , NTSVCS_VALIDATE_DEVICE_INSTANCE , api_ntsvcs_validate_device_instance },
+ { "NTSVCS_GET_DEVICE_REG_PROPERTY" , NTSVCS_GET_DEVICE_REG_PROPERTY , api_ntsvcs_get_device_reg_property },
+ { "NTSVCS_GET_HW_PROFILE_INFO" , NTSVCS_GET_HW_PROFILE_INFO , api_ntsvcs_get_hw_profile_info },
+ { "NTSVCS_HW_PROFILE_FLAGS" , NTSVCS_HW_PROFILE_FLAGS , api_ntsvcs_hw_profile_flags }
+};
+
+
+void ntsvcs_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_ntsvcs_cmds;
+ *n_fns = sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_ntsvcs_init(void)
+{
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "ntsvcs", "ntsvcs", api_ntsvcs_cmds,
+ sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct));
+}
diff --git a/source3/rpc_server/srv_ntsvcs_nt.c b/source3/rpc_server/srv_ntsvcs_nt.c
new file mode 100644
index 0000000000..0bb9154aaf
--- /dev/null
+++ b/source3/rpc_server/srv_ntsvcs_nt.c
@@ -0,0 +1,174 @@
+/*
+ * 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
+
+/********************************************************************
+********************************************************************/
+
+static char* get_device_path( const char *device )
+{
+ static pstring path;
+
+ pstr_sprintf( path, "ROOT\\Legacy_%s\\0000", device );
+
+ return path;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_get_version( pipes_struct *p, NTSVCS_Q_GET_VERSION *q_u, NTSVCS_R_GET_VERSION *r_u )
+{
+ r_u->version = 0x00000400; /* no idea what this means */
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_get_device_list_size( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST_SIZE *q_u, NTSVCS_R_GET_DEVICE_LIST_SIZE *r_u )
+{
+ fstring device;
+ const char *devicepath;
+
+ if ( !q_u->devicename )
+ return WERR_ACCESS_DENIED;
+
+ rpcstr_pull(device, q_u->devicename->buffer, sizeof(device), q_u->devicename->uni_str_len*2, 0);
+ devicepath = get_device_path( device );
+
+ r_u->size = strlen(devicepath) + 2;
+
+ return WERR_OK;
+}
+
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_get_device_list( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST *q_u, NTSVCS_R_GET_DEVICE_LIST *r_u )
+{
+ fstring device;
+ const char *devicepath;
+
+ if ( !q_u->devicename )
+ return WERR_ACCESS_DENIED;
+
+ rpcstr_pull(device, q_u->devicename->buffer, sizeof(device), q_u->devicename->uni_str_len*2, 0);
+ devicepath = get_device_path( device );
+
+ /* From the packet traces I've see, I think this really should be an array
+ of UNISTR2's. But I've never seen more than one string in spite of the
+ fact that the string in double NULL terminated. -- jerry */
+
+ init_unistr2( &r_u->devicepath, devicepath, UNI_STR_TERMINATE );
+ r_u->needed = r_u->devicepath.uni_str_len;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u )
+{
+ fstring devicepath;
+ char *ptr;
+ REGVAL_CTR *values;
+ REGISTRY_VALUE *val;
+
+ rpcstr_pull(devicepath, q_u->devicepath.buffer, sizeof(devicepath), q_u->devicepath.uni_str_len*2, 0);
+
+ switch( q_u->property ) {
+ case DEV_REGPROP_DESC:
+ /* just parse the service name from the device path and then
+ lookup the display name */
+ if ( !(ptr = strrchr_m( devicepath, '\\' )) )
+ return WERR_GENERAL_FAILURE;
+ *ptr = '\0';
+
+ if ( !(ptr = strrchr_m( devicepath, '_' )) )
+ return WERR_GENERAL_FAILURE;
+ ptr++;
+
+ if ( !(values = svcctl_fetch_regvalues( ptr, p->pipe_user.nt_user_token )) )
+ return WERR_GENERAL_FAILURE;
+
+ if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) ) {
+ TALLOC_FREE( values );
+ return WERR_GENERAL_FAILURE;
+ }
+
+ r_u->unknown1 = 0x1; /* always 1...tested using a remove device manager connection */
+ r_u->size = reg_init_regval_buffer( &r_u->value, val );
+ r_u->needed = r_u->size;
+
+ TALLOC_FREE(values);
+
+ break;
+
+ default:
+ r_u->unknown1 = 0x00437c98;
+ return WERR_CM_NO_SUCH_VALUE;
+ }
+
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_validate_device_instance( pipes_struct *p, NTSVCS_Q_VALIDATE_DEVICE_INSTANCE *q_u, NTSVCS_R_VALIDATE_DEVICE_INSTANCE *r_u )
+{
+ /* whatever dude */
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_get_hw_profile_info( pipes_struct *p, NTSVCS_Q_GET_HW_PROFILE_INFO *q_u, NTSVCS_R_GET_HW_PROFILE_INFO *r_u )
+{
+ /* steal the incoming buffer */
+
+ r_u->buffer_size = q_u->buffer_size;
+ r_u->buffer = q_u->buffer;
+
+ /* Take the 5th Ammentment */
+
+ return WERR_CM_NO_MORE_HW_PROFILES;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _ntsvcs_hw_profile_flags( pipes_struct *p, NTSVCS_Q_HW_PROFILE_FLAGS *q_u, NTSVCS_R_HW_PROFILE_FLAGS *r_u )
+{
+ /* just nod your head */
+
+ return WERR_OK;
+}
+
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 63e8d2f5cd..ba6d9704e8 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1,11 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998,
- * Copyright (C) Jeremy Allison 1999,
- * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
+ * Almost completely rewritten by (C) Jeremy Allison 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 +26,6 @@
* and DCE/RPC, while minimising the amount of mallocs, unnecessary
* data copies, and network traffic.
*
- * in this version, which takes a "let's learn what's going on and
- * get something running" approach, there is additional network
- * traffic generated, but the code should be easier to understand...
- *
- * ... if you read the docs. or stare at packets for weeks on end.
- *
*/
#include "includes.h"
@@ -51,52 +41,38 @@ extern struct current_user current_user;
We need to transfer the session key from one rpc bind to the
next. This is the way the netlogon schannel works.
**************************************************************/
+
struct dcinfo last_dcinfo;
BOOL server_auth2_negotiated = False;
-static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
+static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
{
- unsigned char *hash = p->ntlmssp_hash;
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
-
- for( ind = 0; ind < len; ind++) {
- unsigned char tc;
- unsigned char t;
+ AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state;
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
+ if (a) {
+ auth_ntlmssp_end(&a);
}
-
- hash[256] = index_i;
- hash[257] = index_j;
+ auth->a_u.auth_ntlmssp_state = NULL;
}
/*******************************************************************
Generate the next PDU to be returned from the data in p->rdata.
- We cheat here as this function doesn't handle the special auth
- footers of the authenticated bind response reply.
+ Handle NTLMSSP.
********************************************************************/
-BOOL create_next_pdu(pipes_struct *p)
+static BOOL create_next_pdu_ntlmssp(pipes_struct *p)
{
RPC_HDR_RESP hdr_resp;
- BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
- BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
uint32 ss_padding_len = 0;
- uint32 data_len;
uint32 data_space_available;
uint32 data_len_left;
+ uint32 data_len;
prs_struct outgoing_pdu;
- uint32 data_pos;
+ NTSTATUS status;
+ DATA_BLOB auth_blob;
+ RPC_HDR_AUTH auth_info;
+ uint8 auth_type, auth_level;
+ AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
/*
* If we're in the fault state, keep returning fault PDU's until
@@ -124,18 +100,6 @@ BOOL create_next_pdu(pipes_struct *p)
* Work out how much we can fit in a single PDU.
*/
- data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
- if(p->ntlmssp_auth_validated) {
- data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
- } else if(p->netsec_auth_validated) {
- data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN);
- }
-
- /*
- * The amount we send is the minimum of the available
- * space and the amount left to send.
- */
-
data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
/*
@@ -143,10 +107,18 @@ BOOL create_next_pdu(pipes_struct *p)
*/
if(!data_len_left) {
- DEBUG(0,("create_next_pdu: no data left to send !\n"));
+ DEBUG(0,("create_next_pdu_ntlmssp: no data left to send !\n"));
return False;
}
+ data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -
+ RPC_HDR_AUTH_LEN - NTLMSSP_SIG_SIZE;
+
+ /*
+ * The amount we send is the minimum of the available
+ * space and the amount left to send.
+ */
+
data_len = MIN(data_len_left, data_space_available);
/*
@@ -162,9 +134,9 @@ BOOL create_next_pdu(pipes_struct *p)
if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
p->hdr.flags |= RPC_FLG_LAST;
- if ((auth_seal || auth_verify || p->netsec_auth_validated) && (data_len_left % 8)) {
+ if (data_len_left % 8) {
ss_padding_len = 8 - (data_len_left % 8);
- DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n",
+ DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n",
ss_padding_len ));
}
}
@@ -173,20 +145,11 @@ BOOL create_next_pdu(pipes_struct *p)
* Set up the header lengths.
*/
- if (p->ntlmssp_auth_validated) {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
- data_len + ss_padding_len +
- RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
- p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
- } else if (p->netsec_auth_validated) {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
data_len + ss_padding_len +
- RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
- p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
- } else {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
- p->hdr.auth_len = 0;
- }
+ RPC_HDR_AUTH_LEN + NTLMSSP_SIG_SIZE;
+ p->hdr.auth_len = NTLMSSP_SIG_SIZE;
+
/*
* Init the parse struct to point at the outgoing
@@ -198,125 +161,281 @@ BOOL create_next_pdu(pipes_struct *p)
/* Store the header in the data stream. */
if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR.\n"));
prs_mem_free(&outgoing_pdu);
return False;
}
if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_RESP.\n"));
prs_mem_free(&outgoing_pdu);
return False;
}
- /* Store the current offset. */
- data_pos = prs_offset(&outgoing_pdu);
-
/* Copy the data into the PDU. */
if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
- DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to copy %u bytes of data.\n", (unsigned int)data_len));
prs_mem_free(&outgoing_pdu);
return False;
}
/* Copy the sign/seal padding data. */
if (ss_padding_len) {
- char pad[8];
+ unsigned char pad[8];
+
memset(pad, '\0', 8);
if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
- DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes of pad data.\n",
+ (unsigned int)ss_padding_len));
prs_mem_free(&outgoing_pdu);
return False;
}
}
- if (p->ntlmssp_auth_validated) {
- /*
- * NTLMSSP processing. Mutually exclusive with Schannel.
- */
- uint32 crc32 = 0;
- char *data;
-
- DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len));
-
- /*
- * Set data to point to where we copied the data into.
- */
- data = prs_data_p(&outgoing_pdu) + data_pos;
+ /* Now write out the auth header and null blob. */
+ if (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) {
+ auth_type = RPC_NTLMSSP_AUTH_TYPE;
+ } else {
+ auth_type = RPC_SPNEGO_AUTH_TYPE;
+ }
+ if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) {
+ auth_level = RPC_AUTH_LEVEL_PRIVACY;
+ } else {
+ auth_level = RPC_AUTH_LEVEL_INTEGRITY;
+ }
- if (auth_seal) {
- crc32 = crc32_calc_buffer(data, data_len + ss_padding_len);
- NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len);
- }
+ init_rpc_hdr_auth(&auth_info, auth_type, auth_level, ss_padding_len, 1 /* context id. */);
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_AUTH.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
- if (auth_seal || auth_verify) {
- RPC_HDR_AUTH auth_info;
+ /* Generate the sign blob. */
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE,
- auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL,
- (auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0));
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+ switch (p->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ /* Data portion is encrypted. */
+ status = ntlmssp_seal_packet(a->ntlmssp_state,
+ prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+ data_len + ss_padding_len,
+ prs_data_p(&outgoing_pdu),
+ (size_t)prs_offset(&outgoing_pdu),
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&auth_blob);
prs_mem_free(&outgoing_pdu);
return False;
}
- }
-
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
- char *auth_data = prs_data_p(&outgoing_pdu);
-
- p->ntlmssp_seq_num++;
- init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
- crc32, p->ntlmssp_seq_num++);
- auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
+ break;
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ /* Data is signed. */
+ status = ntlmssp_sign_packet(a->ntlmssp_state,
+ prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+ data_len + ss_padding_len,
+ prs_data_p(&outgoing_pdu),
+ (size_t)prs_offset(&outgoing_pdu),
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&auth_blob);
prs_mem_free(&outgoing_pdu);
return False;
}
- NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+ break;
+ default:
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ /* Append the auth blob. */
+ if (!prs_copy_data_in(&outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) {
+ DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n",
+ (unsigned int)NTLMSSP_SIG_SIZE));
+ data_blob_free(&auth_blob);
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ data_blob_free(&auth_blob);
+
+ /*
+ * Setup the counts for this PDU.
+ */
+
+ p->out_data.data_sent_length += data_len;
+ p->out_data.current_pdu_len = p->hdr.frag_len;
+ p->out_data.current_pdu_sent = 0;
+
+ prs_mem_free(&outgoing_pdu);
+ return True;
+}
+
+/*******************************************************************
+ Generate the next PDU to be returned from the data in p->rdata.
+ Return an schannel authenticated fragment.
+ ********************************************************************/
+
+static BOOL create_next_pdu_schannel(pipes_struct *p)
+{
+ RPC_HDR_RESP hdr_resp;
+ uint32 ss_padding_len = 0;
+ uint32 data_len;
+ uint32 data_space_available;
+ uint32 data_len_left;
+ prs_struct outgoing_pdu;
+ uint32 data_pos;
+
+ /*
+ * If we're in the fault state, keep returning fault PDU's until
+ * the pipe gets closed. JRA.
+ */
+
+ if(p->fault_state) {
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
+ return True;
+ }
+
+ memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
+
+ /* Change the incoming request header to a response. */
+ p->hdr.pkt_type = RPC_RESPONSE;
+
+ /* Set up rpc header flags. */
+ if (p->out_data.data_sent_length == 0) {
+ p->hdr.flags = RPC_FLG_FIRST;
+ } else {
+ p->hdr.flags = 0;
+ }
+
+ /*
+ * Work out how much we can fit in a single PDU.
+ */
+
+ data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
+
+ /*
+ * Ensure there really is data left to send.
+ */
+
+ if(!data_len_left) {
+ DEBUG(0,("create_next_pdu_schannel: no data left to send !\n"));
+ return False;
+ }
+
+ data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN -
+ RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
+
+ /*
+ * The amount we send is the minimum of the available
+ * space and the amount left to send.
+ */
+
+ data_len = MIN(data_len_left, data_space_available);
+
+ /*
+ * Set up the alloc hint. This should be the data left to
+ * send.
+ */
+
+ hdr_resp.alloc_hint = data_len_left;
+
+ /*
+ * Work out if this PDU will be the last.
+ */
+
+ if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
+ p->hdr.flags |= RPC_FLG_LAST;
+ if (data_len_left % 8) {
+ ss_padding_len = 8 - (data_len_left % 8);
+ DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n",
+ ss_padding_len ));
+ }
+ }
+
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len +
+ RPC_HDR_AUTH_LEN + RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
+ p->hdr.auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
+
+ /*
+ * Init the parse struct to point at the outgoing
+ * data.
+ */
+
+ prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
+ prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+
+ /* Store the header in the data stream. */
+ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_RESP.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ /* Store the current offset. */
+ data_pos = prs_offset(&outgoing_pdu);
+
+ /* Copy the data into the PDU. */
+
+ if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
+ DEBUG(0,("create_next_pdu_schannel: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ /* Copy the sign/seal padding data. */
+ if (ss_padding_len) {
+ char pad[8];
+ memset(pad, '\0', 8);
+ if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
+ DEBUG(0,("create_next_pdu_schannel: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
+ prs_mem_free(&outgoing_pdu);
+ return False;
}
- } else if (p->netsec_auth_validated) {
+ }
+
+ {
/*
- * Schannel processing. Mutually exclusive with NTLMSSP.
+ * Schannel processing.
*/
- int auth_type, auth_level;
char *data;
RPC_HDR_AUTH auth_info;
-
- RPC_AUTH_NETSEC_CHK verf;
- prs_struct rverf;
- prs_struct rauth;
+ RPC_AUTH_SCHANNEL_CHK verf;
data = prs_data_p(&outgoing_pdu) + data_pos;
/* Check it's the type of reply we were expecting to decode */
- get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level);
- init_rpc_hdr_auth(&auth_info, auth_type, auth_level,
- ss_padding_len, 1);
+ init_rpc_hdr_auth(&auth_info,
+ RPC_SCHANNEL_AUTH_TYPE,
+ p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY ?
+ RPC_AUTH_LEVEL_PRIVACY : RPC_AUTH_LEVEL_INTEGRITY,
+ ss_padding_len, 1);
if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+ DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_AUTH.\n"));
prs_mem_free(&outgoing_pdu);
return False;
}
- prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
- prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
-
- netsec_encode(&p->netsec_auth,
- p->netsec_auth.auth_flags,
+ schannel_encode(p->auth.a_u.schannel_auth,
+ p->auth.auth_level,
SENDER_IS_ACCEPTOR,
&verf, data, data_len + ss_padding_len);
- smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN,
- &verf, &outgoing_pdu, 0);
+ if (!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
+ &verf, &outgoing_pdu, 0)) {
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
- p->netsec_auth.seq_num++;
+ p->auth.a_u.schannel_auth->seq_num++;
}
/*
@@ -332,279 +451,299 @@ BOOL create_next_pdu(pipes_struct *p)
}
/*******************************************************************
- Process an NTLMSSP authentication response.
- If this function succeeds, the user has been authenticated
- and their domain, name and calling workstation stored in
- the pipe struct.
- The initial challenge is stored in p->challenge.
- *******************************************************************/
+ Generate the next PDU to be returned from the data in p->rdata.
+ No authentication done.
+********************************************************************/
-static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
+static BOOL create_next_pdu_noauth(pipes_struct *p)
{
- uchar lm_owf[24];
- uchar nt_owf[128];
- int nt_pw_len;
- int lm_pw_len;
- fstring user_name;
- fstring domain;
- fstring wks;
+ RPC_HDR_RESP hdr_resp;
+ uint32 data_len;
+ uint32 data_space_available;
+ uint32 data_len_left;
+ prs_struct outgoing_pdu;
- NTSTATUS nt_status;
+ /*
+ * If we're in the fault state, keep returning fault PDU's until
+ * the pipe gets closed. JRA.
+ */
- struct auth_context *auth_context = NULL;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
+ if(p->fault_state) {
+ setup_fault_pdu(p, NT_STATUS(0x1c010002));
+ return True;
+ }
- DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
+ memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
- memset(p->user_name, '\0', sizeof(p->user_name));
- memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
- memset(p->domain, '\0', sizeof(p->domain));
- memset(p->wks, '\0', sizeof(p->wks));
+ /* Change the incoming request header to a response. */
+ p->hdr.pkt_type = RPC_RESPONSE;
- /* Set up for non-authenticated user. */
- delete_nt_token(&p->pipe_user.nt_user_token);
- p->pipe_user.ngroups = 0;
- SAFE_FREE( p->pipe_user.groups);
+ /* Set up rpc header flags. */
+ if (p->out_data.data_sent_length == 0) {
+ p->hdr.flags = RPC_FLG_FIRST;
+ } else {
+ p->hdr.flags = 0;
+ }
- /*
- * Setup an empty password for a guest user.
+ /*
+ * Work out how much we can fit in a single PDU.
*/
+ data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
+
/*
- * We always negotiate UNICODE.
+ * Ensure there really is data left to send.
*/
- if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
- rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
- rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
- rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
- } else {
- pull_ascii_fstring(user_name, ntlmssp_resp->user);
- pull_ascii_fstring(domain, ntlmssp_resp->domain);
- pull_ascii_fstring(wks, ntlmssp_resp->wks);
+ if(!data_len_left) {
+ DEBUG(0,("create_next_pdu_noath: no data left to send !\n"));
+ return False;
}
- DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
+ data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
- nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
- lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);
+ /*
+ * The amount we send is the minimum of the available
+ * space and the amount left to send.
+ */
- memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
- memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);
+ data_len = MIN(data_len_left, data_space_available);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("lm, nt owfs, chal\n"));
- dump_data(100, (char *)lm_owf, sizeof(lm_owf));
- dump_data(100, (char *)nt_owf, nt_pw_len);
- dump_data(100, (char *)p->challenge, 8);
-#endif
+ /*
+ * Set up the alloc hint. This should be the data left to
+ * send.
+ */
+
+ hdr_resp.alloc_hint = data_len_left;
/*
- * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
+ * Work out if this PDU will be the last.
*/
- if (*user_name) {
+ if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
+ p->hdr.flags |= RPC_FLG_LAST;
+ }
- /*
- * Do the length checking only if user is not NULL.
- */
+ /*
+ * Set up the header lengths.
+ */
- if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_usr.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_domain.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_wks.str_str_len == 0)
- return False;
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
+ p->hdr.auth_len = 0;
+ /*
+ * Init the parse struct to point at the outgoing
+ * data.
+ */
+
+ prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
+ prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+
+ /* Store the header in the data stream. */
+ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
}
-
- make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
- if (!make_user_info_netlogon_network(&user_info,
- user_name, domain, wks,
- lm_owf, lm_pw_len,
- nt_owf, nt_pw_len)) {
- DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n"));
+ if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR_RESP.\n"));
+ prs_mem_free(&outgoing_pdu);
return False;
}
-
- nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
-
- (auth_context->free)(&auth_context);
- free_user_info(&user_info);
-
- p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
-
- if (!p->ntlmssp_auth_validated) {
- DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
-failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
- free_server_info(&server_info);
+
+ /* Copy the data into the PDU. */
+
+ if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
+ DEBUG(0,("create_next_pdu_noauth: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+ prs_mem_free(&outgoing_pdu);
return False;
}
/*
- * Set up the sign/seal data.
+ * Setup the counts for this PDU.
*/
- if (server_info->lm_session_key.length != 16) {
- DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
-succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n",
- domain, user_name, wks, p->name, server_info->lm_session_key.length));
- free_server_info(&server_info);
- return False;
- } else {
- uchar p24[24];
- NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24);
- {
- unsigned char j = 0;
- int ind;
+ p->out_data.data_sent_length += data_len;
+ p->out_data.current_pdu_len = p->hdr.frag_len;
+ p->out_data.current_pdu_sent = 0;
- unsigned char k2[8];
+ prs_mem_free(&outgoing_pdu);
+ return True;
+}
- memcpy(k2, p24, 5);
- k2[5] = 0xe5;
- k2[6] = 0x38;
- k2[7] = 0xb0;
+/*******************************************************************
+ Generate the next PDU to be returned from the data in p->rdata.
+********************************************************************/
- for (ind = 0; ind < 256; ind++)
- p->ntlmssp_hash[ind] = (unsigned char)ind;
+BOOL create_next_pdu(pipes_struct *p)
+{
+ switch(p->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_NONE:
+ case PIPE_AUTH_LEVEL_CONNECT:
+ /* This is incorrect for auth level connect. Fixme. JRA */
+ return create_next_pdu_noauth(p);
+
+ default:
+ switch(p->auth.auth_type) {
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ return create_next_pdu_ntlmssp(p);
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ return create_next_pdu_schannel(p);
+ default:
+ break;
+ }
+ }
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
+ DEBUG(0,("create_next_pdu: invalid internal auth level %u / type %u",
+ (unsigned int)p->auth.auth_level,
+ (unsigned int)p->auth.auth_type));
+ return False;
+}
- j += (p->ntlmssp_hash[ind] + k2[ind%8]);
+/*******************************************************************
+ Process an NTLMSSP authentication response.
+ If this function succeeds, the user has been authenticated
+ and their domain, name and calling workstation stored in
+ the pipe struct.
+*******************************************************************/
- tc = p->ntlmssp_hash[ind];
- p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
- p->ntlmssp_hash[j] = tc;
- }
+static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
+{
+ DATA_BLOB reply;
+ NTSTATUS status;
+ AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
- p->ntlmssp_hash[256] = 0;
- p->ntlmssp_hash[257] = 0;
- }
+ DEBUG(5,("pipe_ntlmssp_verify_final: checking user details\n"));
- dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
- sizeof(p->ntlmssp_hash));
+ ZERO_STRUCT(reply);
-/* NTLMSSPhash(p->ntlmssp_hash, p24); */
- p->ntlmssp_seq_num = 0;
+ memset(p->user_name, '\0', sizeof(p->user_name));
+ memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
+ memset(p->domain, '\0', sizeof(p->domain));
+ memset(p->wks, '\0', sizeof(p->wks));
+ /* Set up for non-authenticated user. */
+ delete_nt_token(&p->pipe_user.nt_user_token);
+ p->pipe_user.ngroups = 0;
+ SAFE_FREE( p->pipe_user.groups);
+
+ status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
+
+ /* Don't generate a reply. */
+ data_blob_free(&reply);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
}
- fstrcpy(p->user_name, user_name);
- fstrcpy(p->pipe_user_name, server_info->unix_name);
- fstrcpy(p->domain, domain);
- fstrcpy(p->wks, wks);
+ fstrcpy(p->user_name, a->ntlmssp_state->user);
+ fstrcpy(p->pipe_user_name, a->server_info->unix_name);
+ fstrcpy(p->domain, a->ntlmssp_state->domain);
+ fstrcpy(p->wks, a->ntlmssp_state->workstation);
+
+ DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n",
+ p->user_name, p->domain, p->wks));
/*
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
*/
- if (p->session_key.data) {
- data_blob_free(&p->session_key);
+ p->pipe_user.uid = a->server_info->uid;
+ p->pipe_user.gid = a->server_info->gid;
+
+ /*
+ * Copy the session key from the ntlmssp state.
+ */
+
+ data_blob_free(&p->session_key);
+ p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length);
+ if (!p->session_key.data) {
+ return False;
}
- p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length);
- p->pipe_user.uid = server_info->uid;
- p->pipe_user.gid = server_info->gid;
-
- p->pipe_user.ngroups = server_info->n_groups;
+ p->pipe_user.ngroups = a->server_info->n_groups;
if (p->pipe_user.ngroups) {
- if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) {
+ if (!(p->pipe_user.groups = memdup(a->server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) {
DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
- free_server_info(&server_info);
return False;
}
}
- if (server_info->ptok)
- p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok);
- else {
+ if (a->server_info->ptok) {
+ p->pipe_user.nt_user_token = dup_nt_token(a->server_info->ptok);
+ } else {
DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
p->pipe_user.nt_user_token = NULL;
- free_server_info(&server_info);
return False;
}
- p->ntlmssp_auth_validated = True;
-
- free_server_info(&server_info);
return True;
}
/*******************************************************************
The switch table for the pipe names and the functions to handle them.
- *******************************************************************/
+*******************************************************************/
-struct rpc_table
-{
- struct
- {
- const char *clnt;
- const char *srv;
- } pipe;
- struct api_struct *cmds;
- int n_cmds;
+struct rpc_table {
+ struct {
+ const char *clnt;
+ const char *srv;
+ } pipe;
+ struct api_struct *cmds;
+ int n_cmds;
};
static struct rpc_table *rpc_lookup;
static int rpc_lookup_size;
/*******************************************************************
- This is the client reply to our challenge for an authenticated
- bind request. The challenge we sent is in p->challenge.
+ This is the "stage3" NTLMSSP response after a bind request and reply.
*******************************************************************/
-BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
+BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p)
{
- RPC_HDR_AUTHA autha_info;
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ RPC_HDR_AUTH auth_info;
+ uint32 pad;
+ DATA_BLOB blob;
+
+ ZERO_STRUCT(blob);
- DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+ DEBUG(5,("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
if (p->hdr.auth_len == 0) {
- DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
- return False;
+ DEBUG(0,("api_pipe_bind_auth3: No auth field sent !\n"));
+ goto err;
+ }
+
+ /* 4 bytes padding. */
+ if (!prs_uint32("pad", rpc_in_p, 0, &pad)) {
+ DEBUG(0,("api_pipe_bind_auth3: unmarshall of 4 byte pad failed.\n"));
+ goto err;
}
/*
* Decode the authentication verifier response.
*/
- if(!smb_io_rpc_hdr_autha("", &autha_info, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n"));
- return False;
+ if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_bind_auth3: unmarshall of RPC_HDR_AUTH failed.\n"));
+ goto err;
}
- if (autha_info.auth.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) {
- DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
- (int)autha_info.auth.auth_type, (int)autha_info.auth.auth_level ));
+ if (auth_info.auth_type != RPC_NTLMSSP_AUTH_TYPE) {
+ DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
+ (unsigned int)auth_info.auth_type ));
return False;
}
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n"));
- return False;
- }
-
- /*
- * Ensure this is a NTLMSSP_AUTH packet type.
- */
-
- if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
- DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
- return False;
- }
+ blob = data_blob(NULL,p->hdr.auth_len);
- if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n"));
- return False;
+ if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) {
+ DEBUG(0,("api_pipe_bind_auth3: Failed to pull %u bytes - the response blob.\n",
+ (unsigned int)p->hdr.auth_len ));
+ goto err;
}
/*
@@ -612,12 +751,23 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
* for correctness against the given DOMAIN\user name.
*/
- if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp))
- return False;
+ if (!pipe_ntlmssp_verify_final(p, &blob)) {
+ goto err;
+ }
+
+ data_blob_free(&blob);
+
+ p->pipe_bound = True;
- p->pipe_bound = True
-;
return True;
+
+ err:
+
+ data_blob_free(&blob);
+ free_pipe_ntlmssp_auth_data(&p->auth);
+ p->auth.a_u.auth_ntlmssp_state = NULL;
+
+ return False;
}
/*******************************************************************
@@ -642,13 +792,12 @@ static BOOL setup_bind_nak(pipes_struct *p)
prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
-
/*
* Initialize a bind_nak header.
*/
init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
- p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
+ p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
/*
* Marshall the header into the outgoing PDU.
@@ -673,6 +822,11 @@ static BOOL setup_bind_nak(pipes_struct *p)
p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
p->out_data.current_pdu_sent = 0;
+ if (p->auth.auth_data_free_func) {
+ (*p->auth.auth_data_free_func)(&p->auth);
+ }
+ p->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
+ p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
p->pipe_bound = False;
return True;
@@ -766,15 +920,13 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
- for ( i=0; pipe_names[i].client_pipe; i++ )
- {
+ 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)
&& (transfer->version == pipe_names[i].trans_syntax.version)
- && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) )
- {
+ && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) {
struct api_struct *fns = NULL;
int n_fns = 0;
PIPE_RPC_FNS *context_fns;
@@ -800,8 +952,9 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
}
}
- if(pipe_names[i].client_pipe == NULL)
+ if(pipe_names[i].client_pipe == NULL) {
return False;
+ }
return True;
}
@@ -809,6 +962,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
/*******************************************************************
Register commands to an RPC pipe
*******************************************************************/
+
NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
{
struct rpc_table *rpc_entry;
@@ -857,6 +1011,365 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s
}
/*******************************************************************
+ Handle a SPNEGO krb5 bind auth.
+*******************************************************************/
+
+static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info,
+ DATA_BLOB *psecblob, prs_struct *pout_auth)
+{
+ return False;
+}
+
+/*******************************************************************
+ Handle the first part of a SPNEGO bind auth.
+*******************************************************************/
+
+static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p,
+ RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
+{
+ DATA_BLOB blob;
+ DATA_BLOB secblob;
+ DATA_BLOB response;
+ DATA_BLOB chal;
+ char *OIDs[ASN1_MAX_OIDS];
+ int i;
+ NTSTATUS status;
+ BOOL got_kerberos_mechanism = False;
+ AUTH_NTLMSSP_STATE *a = NULL;
+ RPC_HDR_AUTH auth_info;
+
+ ZERO_STRUCT(secblob);
+ ZERO_STRUCT(chal);
+ ZERO_STRUCT(response);
+
+ /* Grab the SPNEGO blob. */
+ blob = data_blob(NULL,p->hdr.auth_len);
+
+ if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) {
+ DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n",
+ (unsigned int)p->hdr.auth_len ));
+ goto err;
+ }
+
+ if (blob.data[0] != ASN1_APPLICATION(0)) {
+ goto err;
+ }
+
+ /* parse out the OIDs and the first sec blob */
+ if (!parse_negTokenTarg(blob, OIDs, &secblob)) {
+ DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
+ goto err;
+ }
+
+ if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
+ got_kerberos_mechanism = True;
+ }
+
+ for (i=0;OIDs[i];i++) {
+ DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
+ SAFE_FREE(OIDs[i]);
+ }
+ DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
+
+ if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
+ BOOL ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth);
+ data_blob_free(&secblob);
+ data_blob_free(&blob);
+ return ret;
+ }
+
+ if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) {
+ /* Free any previous auth type. */
+ free_pipe_ntlmssp_auth_data(&p->auth);
+ }
+
+ /* Initialize the NTLM engine. */
+ status = auth_ntlmssp_start(&a);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err;
+ }
+
+ /*
+ * Pass the first security blob of data to it.
+ * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
+ * which means we need another packet to complete the bind.
+ */
+
+ status = auth_ntlmssp_update(a, secblob, &chal);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
+ goto err;
+ }
+
+ /* Generate the response blob we need for step 2 of the bind. */
+ response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+
+ /* Copy the blob into the pout_auth parse struct */
+ init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
+ if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
+ DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of RPC_HDR_AUTH failed.\n"));
+ goto err;
+ }
+
+ if (!prs_copy_data_in(pout_auth, response.data, response.length)) {
+ DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of data blob failed.\n"));
+ goto err;
+ }
+
+ p->auth.a_u.auth_ntlmssp_state = a;
+ p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
+ p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+
+ data_blob_free(&blob);
+ data_blob_free(&secblob);
+ data_blob_free(&chal);
+ data_blob_free(&response);
+
+ /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
+ return True;
+
+ err:
+
+ data_blob_free(&blob);
+ data_blob_free(&secblob);
+ data_blob_free(&chal);
+ data_blob_free(&response);
+
+ p->auth.a_u.auth_ntlmssp_state = NULL;
+
+ return False;
+}
+
+/*******************************************************************
+ Handle the second part of a SPNEGO bind auth.
+*******************************************************************/
+
+static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p,
+ RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
+{
+ DATA_BLOB spnego_blob, auth_blob, auth_reply;
+ AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
+
+ ZERO_STRUCT(spnego_blob);
+ ZERO_STRUCT(auth_blob);
+ ZERO_STRUCT(auth_reply);
+
+ if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
+ DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
+ goto err;
+ }
+
+ /* Grab the SPNEGO blob. */
+ spnego_blob = data_blob(NULL,p->hdr.auth_len);
+
+ if (!prs_copy_data_out(spnego_blob.data, rpc_in_p, p->hdr.auth_len)) {
+ DEBUG(0,("pipe_spnego_auth_bind_continue: Failed to pull %u bytes - the SPNEGO auth header.\n",
+ (unsigned int)p->hdr.auth_len ));
+ goto err;
+ }
+
+ if (spnego_blob.data[0] != ASN1_CONTEXT(1)) {
+ DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
+ goto err;
+ }
+
+ if (!spnego_parse_auth(spnego_blob, &auth_blob)) {
+ DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
+ goto err;
+ }
+
+ /*
+ * The following call actually checks the challenge/response data.
+ * for correctness against the given DOMAIN\user name.
+ */
+
+ if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
+ goto err;
+ }
+
+ data_blob_free(&spnego_blob);
+ data_blob_free(&auth_blob);
+ data_blob_free(&auth_reply);
+
+ p->pipe_bound = True;
+
+ return True;
+
+ err:
+
+ data_blob_free(&spnego_blob);
+ data_blob_free(&auth_blob);
+ data_blob_free(&auth_reply);
+
+ free_pipe_ntlmssp_auth_data(&p->auth);
+ p->auth.a_u.auth_ntlmssp_state = NULL;
+
+ return False;
+}
+
+/*******************************************************************
+ Handle an schannel bind auth.
+*******************************************************************/
+
+static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
+ RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
+{
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_SCHANNEL_NEG neg;
+ RPC_AUTH_VERIFIER auth_verifier;
+ uint32 flags;
+
+ if (!server_auth2_negotiated) {
+ DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
+ return False;
+ }
+
+ if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) {
+ DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
+ return False;
+ }
+
+ p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct);
+ if (!p->auth.a_u.schannel_auth) {
+ return False;
+ }
+
+ memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));
+ memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
+
+ p->auth.a_u.schannel_auth->seq_num = 0;
+
+ /*
+ * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
+ * here ? We do that for NTLMSPP, but the session key is already set up from the vuser
+ * struct of the person who opened the pipe. I need to test this further. JRA.
+ */
+
+ /* The client opens a second RPC NETLOGON pipe without
+ doing a auth2. The credentials for the schannel are
+ re-used from the auth2 the client did before. */
+ p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo);
+ if (!p->dc) {
+ return False;
+ }
+ *p->dc = last_dcinfo;
+
+ init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
+ if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
+ DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n"));
+ return False;
+ }
+
+ /*** SCHANNEL verifier ***/
+
+ init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
+ if(!smb_io_rpc_schannel_verifier("", &auth_verifier, pout_auth, 0)) {
+ DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_AUTH_VERIFIER failed.\n"));
+ return False;
+ }
+
+ prs_align(pout_auth);
+
+ flags = 5;
+ if(!prs_uint32("flags ", pout_auth, 0, &flags)) {
+ return False;
+ }
+
+ DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
+ neg.domain, neg.myname));
+
+ /* We're finished with this bind - no more packets. */
+ p->auth.auth_data_free_func = NULL;
+ p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+
+ p->pipe_bound = True;
+
+ return True;
+}
+
+/*******************************************************************
+ Handle an NTLMSSP bind auth.
+*******************************************************************/
+
+static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p,
+ RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
+{
+ RPC_HDR_AUTH auth_info;
+ DATA_BLOB blob;
+ DATA_BLOB response;
+ NTSTATUS status;
+ AUTH_NTLMSSP_STATE *a = NULL;
+
+ ZERO_STRUCT(blob);
+ ZERO_STRUCT(response);
+
+ /* Grab the NTLMSSP blob. */
+ blob = data_blob(NULL,p->hdr.auth_len);
+
+ if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to pull %u bytes - the NTLM auth header.\n",
+ (unsigned int)p->hdr.auth_len ));
+ goto err;
+ }
+
+ if (strncmp(blob.data, "NTLMSSP", 7) != 0) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to read NTLMSSP in blob\n"));
+ goto err;
+ }
+
+ /* We have an NTLMSSP blob. */
+ status = auth_ntlmssp_start(&a);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
+ nt_errstr(status) ));
+ goto err;
+ }
+
+ status = auth_ntlmssp_update(a, blob, &response);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
+ nt_errstr(status) ));
+ goto err;
+ }
+
+ data_blob_free(&blob);
+
+ /* Copy the blob into the pout_auth parse struct */
+ init_rpc_hdr_auth(&auth_info, RPC_NTLMSSP_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1);
+ if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of RPC_HDR_AUTH failed.\n"));
+ goto err;
+ }
+
+ if (!prs_copy_data_in(pout_auth, response.data, response.length)) {
+ DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of data blob failed.\n"));
+ goto err;
+ }
+
+ p->auth.a_u.auth_ntlmssp_state = a;
+ p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
+ p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+
+ data_blob_free(&blob);
+ data_blob_free(&response);
+
+ DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
+
+ /* We can't set pipe_bound True yet - we need an RPC_AUTH3 response packet... */
+ return True;
+
+ err:
+
+ data_blob_free(&blob);
+ data_blob_free(&response);
+
+ free_pipe_ntlmssp_auth_data(&p->auth);
+ p->auth.a_u.auth_ntlmssp_state = NULL;
+ return False;
+}
+
+/*******************************************************************
Respond to a pipe bind request.
*******************************************************************/
@@ -872,10 +1385,41 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
prs_struct outgoing_rpc;
int i = 0;
int auth_len = 0;
- enum RPC_PKT_TYPE reply_pkt_type;
+ unsigned int auth_type = RPC_ANONYMOUS_AUTH_TYPE;
+
+ /* No rebinds on a bound pipe - use alter context. */
+ if (p->pipe_bound) {
+ DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound pipe %s.\n", p->pipe_srv_name));
+ return setup_bind_nak(p);
+ }
+
+ prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
+
+ /*
+ * Marshall directly into the outgoing PDU space. We
+ * must do this as we need to set to the bind response
+ * header and are never sending more than one PDU here.
+ */
+
+ prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
- p->ntlmssp_auth_requested = False;
- p->netsec_auth_validated = False;
+ /*
+ * Setup the memory to marshall the ba header, and the
+ * auth footers.
+ */
+
+ if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
+ DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
+ prs_mem_free(&outgoing_rpc);
+ return False;
+ }
+
+ if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
+ DEBUG(0,("api_pipe_bind_req: malloc out_auth failed.\n"));
+ prs_mem_free(&outgoing_rpc);
+ prs_mem_free(&out_hdr_ba);
+ return False;
+ }
DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
@@ -887,17 +1431,21 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
for (i = 0; i < rpc_lookup_size; i++) {
if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
- DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
- fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
- break;
- }
+ DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
+ fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
+ break;
+ }
}
if (i == rpc_lookup_size) {
if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
- DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
- p->name ));
+ DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
+ p->name ));
+ prs_mem_free(&outgoing_rpc);
+ prs_mem_free(&out_hdr_ba);
+ prs_mem_free(&out_auth);
+
return setup_bind_nak(p);
}
@@ -912,122 +1460,205 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
if (i == rpc_lookup_size) {
DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
- return False;
+ goto err_exit;
}
}
/* decode the bind request */
if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) {
DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
- return setup_bind_nak(p);
+ goto err_exit;
}
+ /* name has to be \PIPE\xxxxx */
+ fstrcpy(ack_pipe_name, "\\PIPE\\");
+ fstrcat(ack_pipe_name, p->pipe_srv_name);
+
+ DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
+
/*
- * Check if this is an authenticated request.
+ * Check if this is an authenticated bind request.
*/
- if (p->hdr.auth_len != 0) {
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
-
+ if (p->hdr.auth_len) {
/*
* Decode the authentication verifier.
*/
if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
- return setup_bind_nak(p);
+ goto err_exit;
}
- switch(auth_info.auth_type) {
- case NTLMSSP_AUTH_TYPE:
+ auth_type = auth_info.auth_type;
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to "
- "unmarshall RPC_HDR_AUTH struct.\n"));
- return setup_bind_nak(p);
- }
+ /* Work out if we have to sign or seal etc. */
+ switch (auth_info.auth_level) {
+ case RPC_AUTH_LEVEL_INTEGRITY:
+ p->auth.auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
+ break;
+ case RPC_AUTH_LEVEL_PRIVACY:
+ p->auth.auth_level = PIPE_AUTH_LEVEL_PRIVACY;
+ break;
+ default:
+ DEBUG(0,("api_pipe_bind_req: unexpected auth level (%u).\n",
+ (unsigned int)auth_info.auth_level ));
+ goto err_exit;
+ }
+ } else {
+ ZERO_STRUCT(auth_info);
+ }
- if(!strequal(auth_verifier.signature, "NTLMSSP")) {
- DEBUG(0,("api_pipe_bind_req: "
- "auth_verifier.signature != NTLMSSP\n"));
- return setup_bind_nak(p);
- }
+ assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
- if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
- DEBUG(0,("api_pipe_bind_req: "
- "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
- auth_verifier.msg_type));
- return setup_bind_nak(p);
- }
+ switch(auth_type) {
+ case RPC_NTLMSSP_AUTH_TYPE:
+ if (!pipe_ntlmssp_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) {
+ goto err_exit;
+ }
+ assoc_gid = 0x7a77;
+ break;
- if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: "
- "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
- return setup_bind_nak(p);
- }
+ case RPC_SCHANNEL_AUTH_TYPE:
+ if (!pipe_schannel_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) {
+ goto err_exit;
+ }
+ break;
- p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
- p->ntlmssp_auth_requested = True;
- break;
+ case RPC_SPNEGO_AUTH_TYPE:
+ if (!pipe_spnego_auth_bind_negotiate(p, rpc_in_p, &auth_info, &out_auth)) {
+ goto err_exit;
+ }
+ break;
- case NETSEC_AUTH_TYPE:
- {
- RPC_AUTH_NETSEC_NEG neg;
- struct netsec_auth_struct *a = &(p->netsec_auth);
+ case RPC_ANONYMOUS_AUTH_TYPE:
+ /* Unauthenticated bind request. */
+ /* We're finished - no more packets. */
+ p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
+ /* We must set the pipe auth_level here also. */
+ p->auth.auth_level = PIPE_AUTH_LEVEL_NONE;
+ p->pipe_bound = True;
+ break;
- if (!server_auth2_negotiated) {
- DEBUG(0, ("Attempt to bind using schannel "
- "without successful serverauth2\n"));
- return setup_bind_nak(p);
- }
+ default:
+ DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type ));
+ goto err_exit;
+ }
- if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) {
- DEBUG(0,("api_pipe_bind_req: "
- "Could not unmarshal SCHANNEL auth neg\n"));
- return setup_bind_nak(p);
- }
+ /*
+ * Create the bind response struct.
+ */
- p->netsec_auth_validated = True;
+ /* If the requested abstract synt uuid doesn't match our client pipe,
+ reject the bind_ack & set the transfer interface synt to all 0's,
+ ver 0 (observed when NT5 attempts to bind to abstract interfaces
+ unknown to NT4)
+ Needed when adding entries to a DACL from NT5 - SK */
- memset(a->sess_key, 0, sizeof(a->sess_key));
- memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
+ if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0],
+ hdr_rb.rpc_context[0].context_id )) {
+ init_rpc_hdr_ba(&hdr_ba,
+ RPC_MAX_PDU_FRAG_LEN,
+ RPC_MAX_PDU_FRAG_LEN,
+ assoc_gid,
+ ack_pipe_name,
+ 0x1, 0x0, 0x0,
+ &hdr_rb.rpc_context[0].transfer[0]);
+ } else {
+ RPC_IFACE null_interface;
+ ZERO_STRUCT(null_interface);
+ /* Rejection reason: abstract syntax not supported */
+ init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
+ RPC_MAX_PDU_FRAG_LEN, assoc_gid,
+ ack_pipe_name, 0x1, 0x2, 0x1,
+ &null_interface);
+ p->pipe_bound = False;
+ }
- a->seq_num = 0;
+ /*
+ * and marshall it.
+ */
- DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
- neg.domain, neg.myname));
- break;
- }
+ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
+ goto err_exit;
+ }
- case SPNEGO_AUTH_TYPE:
- default:
- DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
- auth_info.auth_type ));
- return setup_bind_nak(p);
- }
+ /*
+ * Create the header, now we know the length.
+ */
+
+ if (prs_offset(&out_auth)) {
+ auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
}
- switch(p->hdr.pkt_type) {
- case RPC_BIND:
- /* name has to be \PIPE\xxxxx */
- fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, p->pipe_srv_name);
- reply_pkt_type = RPC_BINDACK;
- break;
- case RPC_ALTCONT:
- /* secondary address CAN be NULL
- * as the specs say it's ignored.
- * It MUST NULL to have the spoolss working.
- */
- fstrcpy(ack_pipe_name,"");
- reply_pkt_type = RPC_ALTCONTRESP;
- break;
- default:
- return False;
+ init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id,
+ RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
+ auth_len);
+
+ /*
+ * Marshall the header into the outgoing PDU.
+ */
+
+ if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
+ goto err_exit;
}
- DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
+ /*
+ * Now add the RPC_HDR_BA and any auth needed.
+ */
+
+ if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
+ DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
+ goto err_exit;
+ }
+
+ if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+ DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
+ goto err_exit;
+ }
+
+ /*
+ * Setup the lengths for the initial reply.
+ */
+
+ p->out_data.data_sent_length = 0;
+ p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
+ p->out_data.current_pdu_sent = 0;
+
+ prs_mem_free(&out_hdr_ba);
+ prs_mem_free(&out_auth);
+
+ return True;
+
+ err_exit:
+
+ prs_mem_free(&outgoing_rpc);
+ prs_mem_free(&out_hdr_ba);
+ prs_mem_free(&out_auth);
+ return setup_bind_nak(p);
+}
+
+/****************************************************************************
+ Deal with an alter context call. Can be third part of 3 leg auth request for
+ SPNEGO calls.
+****************************************************************************/
+
+BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p)
+{
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_AUTH auth_info;
+ uint16 assoc_gid;
+ fstring ack_pipe_name;
+ prs_struct out_hdr_ba;
+ prs_struct out_auth;
+ prs_struct outgoing_rpc;
+ int auth_len = 0;
+
+ prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
/*
* Marshall directly into the outgoing PDU space. We
@@ -1035,7 +1666,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
* header and are never sending more than one PDU here.
*/
- prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
/*
@@ -1044,22 +1674,68 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
*/
if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
- DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
+ DEBUG(0,("api_pipe_alter_context: malloc out_hdr_ba failed.\n"));
prs_mem_free(&outgoing_rpc);
return False;
}
if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
- DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
+ DEBUG(0,("api_pipe_alter_context: malloc out_auth failed.\n"));
prs_mem_free(&outgoing_rpc);
prs_mem_free(&out_hdr_ba);
return False;
}
- if (p->ntlmssp_auth_requested)
- assoc_gid = 0x7a77;
- else
- assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
+ DEBUG(5,("api_pipe_alter_context: decode request. %d\n", __LINE__));
+
+ /* decode the alter context request */
+ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_RB struct.\n"));
+ goto err_exit;
+ }
+
+ /* secondary address CAN be NULL
+ * as the specs say it's ignored.
+ * It MUST be NULL to have the spoolss working.
+ */
+ fstrcpy(ack_pipe_name,"");
+
+ DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
+
+ /*
+ * Check if this is an authenticated alter context request.
+ */
+
+ if (p->hdr.auth_len != 0) {
+ /*
+ * Decode the authentication verifier.
+ */
+
+ if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
+ DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+ goto err_exit;
+ }
+
+ /*
+ * Currently only the SPNEGO auth type uses the alter ctx
+ * response in place of the NTLMSSP auth3 type.
+ */
+
+ if (auth_info.auth_type == RPC_SPNEGO_AUTH_TYPE) {
+ /* We can only finish if the pipe is unbound. */
+ if (!p->pipe_bound) {
+ if (!pipe_spnego_auth_bind_continue(p, rpc_in_p, &auth_info, &out_auth)) {
+ goto err_exit;
+ }
+ } else {
+ goto err_exit;
+ }
+ }
+ } else {
+ ZERO_STRUCT(auth_info);
+ }
+
+ assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
/*
* Create the bind response struct.
@@ -1074,8 +1750,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0],
hdr_rb.rpc_context[0].context_id )) {
init_rpc_hdr_ba(&hdr_ba,
- MAX_PDU_FRAG_LEN,
- MAX_PDU_FRAG_LEN,
+ RPC_MAX_PDU_FRAG_LEN,
+ RPC_MAX_PDU_FRAG_LEN,
assoc_gid,
ack_pipe_name,
0x1, 0x0, 0x0,
@@ -1084,10 +1760,11 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
RPC_IFACE null_interface;
ZERO_STRUCT(null_interface);
/* Rejection reason: abstract syntax not supported */
- init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN,
- MAX_PDU_FRAG_LEN, assoc_gid,
+ init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
+ RPC_MAX_PDU_FRAG_LEN, assoc_gid,
ack_pipe_name, 0x1, 0x2, 0x1,
&null_interface);
+ p->pipe_bound = False;
}
/*
@@ -1095,85 +1772,19 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
*/
if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
+ DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR_BA failed.\n"));
goto err_exit;
}
/*
- * Now the authentication.
+ * Create the header, now we know the length.
*/
- if (p->ntlmssp_auth_requested) {
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
-
- generate_random_buffer(p->challenge, 8);
-
- /*** Authentication info ***/
-
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1);
- if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
- goto err_exit;
- }
-
- /*** NTLMSSP verifier ***/
-
- init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
- goto err_exit;
- }
-
- /* NTLMSSP challenge ***/
-
- init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge);
- if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n"));
- goto err_exit;
- }
-
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
- }
-
- if (p->netsec_auth_validated) {
- RPC_AUTH_VERIFIER auth_verifier;
- uint32 flags;
-
- /* The client opens a second RPC NETLOGON pipe without
- doing a auth2. The credentials for the schannel are
- re-used from the auth2 the client did before. */
- p->dc = last_dcinfo;
-
- init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, auth_info.auth_level, RPC_HDR_AUTH_LEN, 1);
- if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
- goto err_exit;
- }
-
- /*** NETSEC verifier ***/
-
- init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
- if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
- goto err_exit;
- }
-
- prs_align(&out_auth);
-
- flags = 5;
- if(!prs_uint32("flags ", &out_auth, 0, &flags))
- goto err_exit;
-
+ if (prs_offset(&out_auth)) {
auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
}
- /*
- * Create the header, now we know the length.
- */
-
- init_rpc_hdr(&p->hdr, reply_pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
+ init_rpc_hdr(&p->hdr, RPC_ALTCONTRESP, RPC_FLG_FIRST | RPC_FLG_LAST,
p->hdr.call_id,
RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
auth_len);
@@ -1183,7 +1794,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
*/
if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
- DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
+ DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR failed.\n"));
goto err_exit;
}
@@ -1192,19 +1803,15 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
*/
if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
- DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
+ DEBUG(0,("api_pipe_alter_context: append of RPC_HDR_BA failed.\n"));
goto err_exit;
}
- if((p->ntlmssp_auth_requested|p->netsec_auth_validated) &&
- !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
- DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
+ if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+ DEBUG(0,("api_pipe_alter_context: append of auth info failed.\n"));
goto err_exit;
}
- if(!p->ntlmssp_auth_requested)
- p->pipe_bound = True;
-
/*
* Setup the lengths for the initial reply.
*/
@@ -1223,138 +1830,141 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
prs_mem_free(&outgoing_rpc);
prs_mem_free(&out_hdr_ba);
prs_mem_free(&out_auth);
- return False;
+ return setup_bind_nak(p);
}
/****************************************************************************
- Deal with sign & seal processing on an RPC request.
+ Deal with NTLMSSP sign & seal processing on an RPC request.
****************************************************************************/
-BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
+BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in,
+ uint32 *p_ss_padding_len, NTSTATUS *pstatus)
{
- /*
- * We always negotiate the following two bits....
- */
- BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
- BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
- int data_len;
- int auth_len;
- uint32 old_offset;
- uint32 crc32 = 0;
+ RPC_HDR_AUTH auth_info;
+ uint32 auth_len = p->hdr.auth_len;
+ uint32 save_offset = prs_offset(rpc_in);
+ AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state;
+ unsigned char *data = NULL;
+ size_t data_len;
+ unsigned char *full_packet_data = NULL;
+ size_t full_packet_data_len;
+ DATA_BLOB auth_blob;
+
+ *pstatus = NT_STATUS_OK;
- auth_len = p->hdr.auth_len;
+ if (p->auth.auth_level == PIPE_AUTH_LEVEL_NONE || p->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
+ return True;
+ }
+
+ if (!a) {
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
+ return False;
+ }
- if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) {
- DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len ));
+ /* Ensure there's enough data for an authenticated request. */
+ if ((auth_len > RPC_MAX_SIGN_SIZE) ||
+ (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len)) {
+ DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len %u is too large.\n",
+ (unsigned int)auth_len ));
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
return False;
}
/*
- * The following is that length of the data we must verify or unseal.
- * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
- * preceeding the auth_data.
+ * We need the full packet data + length (minus auth stuff) as well as the packet data + length
+ * after the RPC header.
+ * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
+ * functions as NTLMv2 checks the rpc headers also.
*/
- data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
-
- DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+ data = (unsigned char *)(prs_data_p(rpc_in) + RPC_HDR_REQ_LEN);
+ data_len = (size_t)(p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len);
- if (auth_seal) {
- /*
- * The data in rpc_in doesn't contain the RPC_HEADER as this
- * has already been consumed.
- */
- char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN;
- dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
- sizeof(p->ntlmssp_hash));
+ full_packet_data = p->in_data.current_in_pdu;
+ full_packet_data_len = p->hdr.frag_len - auth_len;
- dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n",
- (const unsigned char *)data, data_len);
- NTLMSSPcalc_p(p, (uchar*)data, data_len);
- dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n",
- (const unsigned char *)data, data_len);
- crc32 = crc32_calc_buffer(data, data_len);
+ /* Pull the auth header and the following data into a blob. */
+ if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {
+ DEBUG(0,("api_pipe_ntlmssp_auth_process: cannot move offset to %u.\n",
+ (unsigned int)RPC_HDR_REQ_LEN + (unsigned int)data_len ));
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
+ return False;
}
- old_offset = prs_offset(rpc_in);
-
- if (auth_seal || auth_verify) {
- RPC_HDR_AUTH auth_info;
-
- if(!prs_set_offset(rpc_in, old_offset + data_len)) {
- DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n",
- (unsigned int)old_offset + data_len ));
- return False;
- }
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
- DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
- return False;
- }
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
+ DEBUG(0,("api_pipe_ntlmssp_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
+ return False;
}
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
- char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4;
-
- DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4));
-
- /*
- * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the
- * incoming buffer.
- */
- if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) {
- DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n",
- RPC_AUTH_NTLMSSP_CHK_LEN - 4 ));
- return False;
- }
-
- NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) {
- DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n"));
- return False;
- }
-
- if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) {
- DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n"));
+ auth_blob.data = prs_data_p(rpc_in) + prs_offset(rpc_in);
+ auth_blob.length = auth_len;
+
+ switch (p->auth.auth_level) {
+ case PIPE_AUTH_LEVEL_PRIVACY:
+ /* Data is encrypted. */
+ *pstatus = ntlmssp_unseal_packet(a->ntlmssp_state,
+ data, data_len,
+ full_packet_data,
+ full_packet_data_len,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(*pstatus)) {
+ return False;
+ }
+ break;
+ case PIPE_AUTH_LEVEL_INTEGRITY:
+ /* Data is signed. */
+ *pstatus = ntlmssp_check_packet(a->ntlmssp_state,
+ data, data_len,
+ full_packet_data,
+ full_packet_data_len,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(*pstatus)) {
+ return False;
+ }
+ break;
+ default:
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
return False;
- }
}
/*
* Return the current pointer to the data offset.
*/
- if(!prs_set_offset(rpc_in, old_offset)) {
+ if(!prs_set_offset(rpc_in, save_offset)) {
DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
- (unsigned int)old_offset ));
+ (unsigned int)save_offset ));
+ *pstatus = NT_STATUS_INVALID_PARAMETER;
return False;
}
+ /*
+ * Remember the padding length. We must remove it from the real data
+ * stream once the sign/seal is done.
+ */
+
+ *p_ss_padding_len = auth_info.auth_pad_len;
+
return True;
}
/****************************************************************************
Deal with schannel processing on an RPC request.
****************************************************************************/
-BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
+
+BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len)
{
- /*
- * We always negotiate the following two bits....
- */
- int data_len;
- int auth_len;
- uint32 old_offset;
+ uint32 data_len;
+ uint32 auth_len;
+ uint32 save_offset = prs_offset(rpc_in);
RPC_HDR_AUTH auth_info;
- RPC_AUTH_NETSEC_CHK netsec_chk;
-
+ RPC_AUTH_SCHANNEL_CHK schannel_chk;
auth_len = p->hdr.auth_len;
- if (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) {
- DEBUG(0,("Incorrect auth_len %d.\n", auth_len ));
+ if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
+ DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len ));
return False;
}
@@ -1364,16 +1974,21 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
* preceeding the auth_data.
*/
+ if (p->hdr.frag_len < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len) {
+ DEBUG(0,("Incorrect frag %u, auth %u.\n",
+ (unsigned int)p->hdr.frag_len,
+ (unsigned int)auth_len ));
+ return False;
+ }
+
data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
RPC_HDR_AUTH_LEN - auth_len;
DEBUG(5,("data %d auth %d\n", data_len, auth_len));
- old_offset = prs_offset(rpc_in);
-
- if(!prs_set_offset(rpc_in, old_offset + data_len)) {
+ if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) {
DEBUG(0,("cannot move offset to %u.\n",
- (unsigned int)old_offset + data_len ));
+ (unsigned int)RPC_HDR_REQ_LEN + data_len ));
return False;
}
@@ -1382,34 +1997,22 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
return False;
}
- if (auth_info.auth_type != NETSEC_AUTH_TYPE) {
+ if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) {
DEBUG(0,("Invalid auth info %d on schannel\n",
auth_info.auth_type));
return False;
}
- if (auth_info.auth_level == RPC_PIPE_AUTH_SEAL_LEVEL) {
- p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL;
- } else if (auth_info.auth_level == RPC_PIPE_AUTH_SIGN_LEVEL) {
- p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN;
- } else {
- DEBUG(0,("Invalid auth level %d on schannel\n",
- auth_info.auth_level));
- return False;
- }
-
- if(!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN,
- &netsec_chk, rpc_in, 0))
- {
- DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n"));
+ if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, &schannel_chk, rpc_in, 0)) {
+ DEBUG(0,("failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n"));
return False;
}
- if (!netsec_decode(&p->netsec_auth,
- p->netsec_auth.auth_flags,
+ if (!schannel_decode(p->auth.a_u.schannel_auth,
+ p->auth.auth_level,
SENDER_IS_INITIATOR,
- &netsec_chk,
- prs_data_p(rpc_in)+old_offset, data_len)) {
+ &schannel_chk,
+ prs_data_p(rpc_in)+RPC_HDR_REQ_LEN, data_len)) {
DEBUG(3,("failed to decode PDU\n"));
return False;
}
@@ -1418,14 +2021,21 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
* Return the current pointer to the data offset.
*/
- if(!prs_set_offset(rpc_in, old_offset)) {
+ if(!prs_set_offset(rpc_in, save_offset)) {
DEBUG(0,("failed to set offset back to %u\n",
- (unsigned int)old_offset ));
+ (unsigned int)save_offset ));
return False;
}
/* The sequence number gets incremented on both send and receive. */
- p->netsec_auth.seq_num++;
+ p->auth.a_u.schannel_auth->seq_num++;
+
+ /*
+ * Remember the padding length. We must remove it from the real data
+ * stream once the sign/seal is done.
+ */
+
+ *p_ss_padding_len = auth_info.auth_pad_len;
return True;
}
@@ -1436,7 +2046,9 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
{
- if (p->ntlmssp_auth_validated) {
+ if (p->pipe_bound &&
+ (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP ||
+ (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
memcpy(user, &p->pipe_user, sizeof(struct current_user));
} else {
memcpy(user, &current_user, sizeof(struct current_user));
@@ -1470,7 +2082,7 @@ static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 contex
}
/****************************************************************************
- memory cleanup
+ Memory cleanup.
****************************************************************************/
void free_pipe_rpc_context( PIPE_RPC_FNS *list )
@@ -1496,14 +2108,17 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list )
BOOL api_pipe_request(pipes_struct *p)
{
BOOL ret = False;
+ BOOL changed_user = False;
PIPE_RPC_FNS *pipe_fns;
- if (p->ntlmssp_auth_validated) {
-
+ if (p->pipe_bound &&
+ ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) ||
+ (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
if(!become_authenticated_pipe_user(p)) {
prs_mem_free(&p->out_data.rdata);
return False;
}
+ changed_user = True;
}
DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
@@ -1522,8 +2137,9 @@ BOOL api_pipe_request(pipes_struct *p)
p->hdr_req.context_id, p->name));
}
- if(p->ntlmssp_auth_validated)
+ if (changed_user) {
unbecome_authenticated_pipe_user();
+ }
return ret;
}
@@ -1649,6 +2265,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
case PI_EVENTLOG:
eventlog_get_pipe_fns( &cmds, &n_cmds );
break;
+ case PI_NTSVCS:
+ ntsvcs_get_pipe_fns( &cmds, &n_cmds );
+ break;
#ifdef DEVELOPER
case PI_ECHO:
echo_get_pipe_fns( &cmds, &n_cmds );
@@ -1663,5 +2282,3 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
return;
}
-
-
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 83b78f8d2f..205223190b 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -2,8 +2,8 @@
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Jeremy Allison 1999.
+ * Largely re-written : 2005
+ * Copyright (C) Jeremy Allison 1998 - 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
@@ -106,10 +106,11 @@ static int pipe_handle_offset;
void set_pipe_handle_offset(int max_open_files)
{
- if(max_open_files < 0x7000)
- pipe_handle_offset = 0x7000;
- else
- pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
+ if(max_open_files < 0x7000) {
+ pipe_handle_offset = 0x7000;
+ } else {
+ pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
+ }
}
/****************************************************************************
@@ -128,8 +129,9 @@ void reset_chain_p(void)
void init_rpc_pipe_hnd(void)
{
bmap = bitmap_allocate(MAX_OPEN_PIPES);
- if (!bmap)
+ if (!bmap) {
exit_server("out of memory in init_rpc_pipe_hnd");
+ }
}
/****************************************************************************
@@ -154,7 +156,7 @@ static BOOL pipe_init_outgoing_data(pipes_struct *p)
* Initialize the outgoing RPC data buffer.
* we will use this as the raw data area for replying to rpc requests.
*/
- if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
+ if(!prs_init(&o_data->rdata, RPC_MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
return False;
}
@@ -177,8 +179,9 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
pipe_name, pipes_open));
- if (strstr(pipe_name, "spoolss"))
+ if (strstr(pipe_name, "spoolss")) {
is_spoolss_pipe = True;
+ }
if (is_spoolss_pipe && current_spoolss_pipes_open >= MAX_OPEN_SPOOLSS_PIPES) {
DEBUG(10,("open_rpc_pipe_p: spooler bug workaround. Denying open on pipe %s\n",
@@ -189,8 +192,10 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
/* not repeating pipe numbers makes it easier to track things in
log files and prevents client bugs where pipe numbers are reused
over connection restarts */
- if (next_pipe == 0)
+
+ if (next_pipe == 0) {
next_pipe = (sys_getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
+ }
i = bitmap_find(bmap, next_pipe);
@@ -201,8 +206,9 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
next_pipe = (i+1) % MAX_OPEN_PIPES;
- for (p = Pipes; p; p = p->next)
+ for (p = Pipes; p; p = p->next) {
DEBUG(5,("open_rpc_pipe_p: name %s pnum=%x\n", p->name, p->pnum));
+ }
p = SMB_MALLOC_P(smb_np_struct);
if (!p) {
@@ -259,8 +265,9 @@ smb_np_struct *open_rpc_pipe_p(char *pipe_name,
chain_p = p;
/* Iterate over p_it as a temp variable, to display all open pipes */
- for (p_it = Pipes; p_it; p_it = p_it->next)
+ for (p_it = Pipes; p_it; p_it = p_it->next) {
DEBUG(5,("open pipes: name %s pnum=%x\n", p_it->name, p_it->pnum));
+ }
return chain_p;
}
@@ -297,9 +304,17 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
return NULL;
}
+ if ((p->pipe_state_mem_ctx = talloc_init("pipe_state %s %p", pipe_name, p)) == NULL) {
+ DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
+ talloc_destroy(p->mem_ctx);
+ SAFE_FREE(p);
+ return NULL;
+ }
+
if (!init_pipe_handle_list(p, pipe_name)) {
DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
talloc_destroy(p->mem_ctx);
+ talloc_destroy(p->pipe_state_mem_ctx);
SAFE_FREE(p);
return NULL;
}
@@ -311,8 +326,10 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
* change the type to UNMARSALLING before processing the stream.
*/
- if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
+ if(!prs_init(&p->in_data.data, RPC_MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
+ talloc_destroy(p->mem_ctx);
+ talloc_destroy(p->pipe_state_mem_ctx);
return NULL;
}
@@ -325,12 +342,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
p->vuid = vuid;
- p->ntlmssp_chal_flags = 0;
- p->ntlmssp_auth_validated = False;
- p->ntlmssp_auth_requested = False;
-
- p->pipe_bound = False;
- p->fault_state = False;
p->endian = RPC_LITTLE_ENDIAN;
ZERO_STRUCT(p->pipe_user);
@@ -345,21 +356,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
}
/*
- * Initialize the incoming RPC struct.
- */
-
- p->in_data.pdu_needed_len = 0;
- p->in_data.pdu_received_len = 0;
-
- /*
- * Initialize the outgoing RPC struct.
- */
-
- p->out_data.current_pdu_len = 0;
- p->out_data.current_pdu_sent = 0;
- p->out_data.data_sent_length = 0;
-
- /*
* Initialize the outgoing RPC data buffer with no memory.
*/
prs_init(&p->out_data.rdata, 0, p->mem_ctx, MARSHALL);
@@ -504,7 +500,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
* Ensure that the pdu length is sane.
*/
- if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > MAX_PDU_FRAG_LEN)) {
+ if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > RPC_MAX_PDU_FRAG_LEN)) {
DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
set_incoming_fault(p);
prs_mem_free(&rpc_in);
@@ -514,18 +510,8 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
(unsigned int)p->hdr.flags ));
- /*
- * Adjust for the header we just ate.
- */
- p->in_data.pdu_received_len = 0;
p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;
- /*
- * Null the data we just ate.
- */
-
- memset((char *)&p->in_data.current_in_pdu[0], '\0', RPC_HEADER_LEN);
-
prs_mem_free(&rpc_in);
return 0; /* No extra data processed. */
@@ -540,12 +526,13 @@ static void free_pipe_context(pipes_struct *p)
{
if (p->mem_ctx) {
DEBUG(3,("free_pipe_context: destroying talloc pool of size "
- "%llu\n", talloc_total_size(p->mem_ctx) ));
+ "%lu\n", (unsigned long)talloc_total_size(p->mem_ctx) ));
talloc_free_children(p->mem_ctx);
} else {
p->mem_ctx = talloc_init("pipe %s %p", p->name, p);
- if (p->mem_ctx == NULL)
+ if (p->mem_ctx == NULL) {
p->fault_state = True;
+ }
}
}
@@ -556,9 +543,9 @@ static void free_pipe_context(pipes_struct *p)
static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
{
- BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
+ uint32 ss_padding_len = 0;
size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- (auth_verify ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
+ (p->hdr.auth_len ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
if(!p->pipe_bound) {
DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
@@ -581,29 +568,40 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
return False;
}
- if(p->ntlmssp_auth_validated && !api_pipe_auth_process(p, rpc_in_p)) {
- DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
- set_incoming_fault(p);
- return False;
- }
+ switch(p->auth.auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ break;
- if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ {
+ NTSTATUS status;
+ if(!api_pipe_ntlmssp_auth_process(p, rpc_in_p, &ss_padding_len, &status)) {
+ DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
+ DEBUG(0,("process_request_pdu: error was %s.\n", nt_errstr(status) ));
+ set_incoming_fault(p);
+ return False;
+ }
+ break;
+ }
- /*
- * Authentication _was_ requested and it already failed.
- */
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ if (!api_pipe_schannel_process(p, rpc_in_p, &ss_padding_len)) {
+ DEBUG(3,("process_request_pdu: failed to do schannel processing.\n"));
+ set_incoming_fault(p);
+ return False;
+ }
+ break;
- DEBUG(0,("process_request_pdu: RPC request received on pipe %s "
- "where authentication failed. Denying the request.\n",
- p->name));
- set_incoming_fault(p);
- return False;
+ default:
+ DEBUG(0,("process_request_pdu: unknown auth type %u set.\n", (unsigned int)p->auth.auth_type ));
+ set_incoming_fault(p);
+ return False;
}
- if (p->netsec_auth_validated && !api_pipe_netsec_process(p, rpc_in_p)) {
- DEBUG(3,("process_request_pdu: failed to do schannel processing.\n"));
- set_incoming_fault(p);
- return False;
+ /* Now we've done the sign/seal we can remove any padding data. */
+ if (data_len > ss_padding_len) {
+ data_len -= ss_padding_len;
}
/*
@@ -643,8 +641,7 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
* size as the current offset.
*/
- if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data)))
- {
+ if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n"));
set_incoming_fault(p);
return False;
@@ -664,8 +661,9 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
free_pipe_context(p);
- if(pipe_init_outgoing_data(p))
+ if(pipe_init_outgoing_data(p)) {
ret = api_pipe_request(p);
+ }
free_pipe_context(p);
@@ -690,11 +688,11 @@ static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
already been parsed and stored in p->hdr.
****************************************************************************/
-static ssize_t process_complete_pdu(pipes_struct *p)
+static void process_complete_pdu(pipes_struct *p)
{
prs_struct rpc_in;
- size_t data_len = p->in_data.pdu_received_len;
- char *data_p = (char *)&p->in_data.current_in_pdu[0];
+ size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
+ char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
BOOL reply = False;
if(p->fault_state) {
@@ -702,7 +700,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
p->name ));
set_incoming_fault(p);
setup_fault_pdu(p, NT_STATUS(0x1c010002));
- return (ssize_t)data_len;
+ return;
}
prs_init( &rpc_in, 0, p->mem_ctx, UNMARSHALL);
@@ -722,19 +720,28 @@ static ssize_t process_complete_pdu(pipes_struct *p)
switch (p->hdr.pkt_type) {
case RPC_BIND:
- case RPC_ALTCONT:
/*
* We assume that a pipe bind is only in one pdu.
*/
- if(pipe_init_outgoing_data(p))
+ if(pipe_init_outgoing_data(p)) {
reply = api_pipe_bind_req(p, &rpc_in);
+ }
+ break;
+ case RPC_ALTCONT:
+ /*
+ * We assume that a pipe bind is only in one pdu.
+ */
+ if(pipe_init_outgoing_data(p)) {
+ reply = api_pipe_alter_context(p, &rpc_in);
+ }
break;
- case RPC_BINDRESP:
+ case RPC_AUTH3:
/*
- * We assume that a pipe bind_resp is only in one pdu.
+ * The third packet in an NTLMSSP auth exchange.
*/
- if(pipe_init_outgoing_data(p))
- reply = api_pipe_bind_auth_resp(p, &rpc_in);
+ if(pipe_init_outgoing_data(p)) {
+ reply = api_pipe_bind_auth3(p, &rpc_in);
+ }
break;
case RPC_REQUEST:
reply = process_request_pdu(p, &rpc_in);
@@ -761,7 +768,6 @@ static ssize_t process_complete_pdu(pipes_struct *p)
}
prs_mem_free(&rpc_in);
- return (ssize_t)data_len;
}
/****************************************************************************
@@ -770,8 +776,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
{
- size_t data_to_copy = MIN(n, MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
- size_t old_pdu_received_len = p->in_data.pdu_received_len;
+ size_t data_to_copy = MIN(n, RPC_MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
(unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
@@ -812,8 +817,9 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
* data we need, then loop again.
*/
- if(p->in_data.pdu_needed_len == 0)
+ if(p->in_data.pdu_needed_len == 0) {
return unmarshall_rpc_header(p);
+ }
/*
* Ok - at this point we have a valid RPC_HEADER in p->hdr.
@@ -824,24 +830,27 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
/*
* Copy as much of the data as we need into the current_in_pdu buffer.
+ * pdu_needed_len becomes zero when we have a complete pdu.
*/
memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);
p->in_data.pdu_received_len += data_to_copy;
+ p->in_data.pdu_needed_len -= data_to_copy;
/*
* Do we have a complete PDU ?
- * (return the nym of bytes handled in the call)
+ * (return the number of bytes handled in the call)
*/
- if(p->in_data.pdu_received_len == p->in_data.pdu_needed_len)
- return process_complete_pdu(p) - old_pdu_received_len;
+ if(p->in_data.pdu_needed_len == 0) {
+ process_complete_pdu(p);
+ return data_to_copy;
+ }
DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
(unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
return (ssize_t)data_to_copy;
-
}
/****************************************************************************
@@ -878,8 +887,9 @@ static ssize_t write_to_internal_pipe(void *np_conn, char *data, size_t n)
DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
- if(data_used < 0)
+ if(data_used < 0) {
return -1;
+ }
data_left -= data_used;
data += data_used;
@@ -948,9 +958,9 @@ static ssize_t read_from_internal_pipe(void *np_conn, char *data, size_t n,
* authentications failing. Just ignore it so things work.
*/
- if(n > MAX_PDU_FRAG_LEN) {
+ if(n > RPC_MAX_PDU_FRAG_LEN) {
DEBUG(5,("read_from_pipe: too large read (%u) requested on \
-pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, MAX_PDU_FRAG_LEN ));
+pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, RPC_MAX_PDU_FRAG_LEN ));
}
/*
@@ -1019,8 +1029,9 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
{
- if (p == NULL)
+ if (p == NULL) {
return False;
+ }
if (p->open) {
DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
@@ -1043,8 +1054,9 @@ BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state)
{
- if (p == NULL)
+ if (p == NULL) {
return False;
+ }
if (p->open) {
DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
@@ -1121,9 +1133,18 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
prs_mem_free(&p->out_data.rdata);
prs_mem_free(&p->in_data.data);
- if (p->mem_ctx)
+ if (p->auth.auth_data_free_func) {
+ (*p->auth.auth_data_free_func)(&p->auth);
+ }
+
+ if (p->mem_ctx) {
talloc_destroy(p->mem_ctx);
-
+ }
+
+ if (p->pipe_state_mem_ctx) {
+ talloc_destroy(p->pipe_state_mem_ctx);
+ }
+
free_pipe_rpc_context( p->contexts );
/* Free the handles database. */
@@ -1152,8 +1173,9 @@ smb_np_struct *get_rpc_pipe_p(char *buf, int where)
{
int pnum = SVAL(buf,where);
- if (chain_p)
+ if (chain_p) {
return chain_p;
+ }
return get_rpc_pipe(pnum);
}
@@ -1168,9 +1190,10 @@ smb_np_struct *get_rpc_pipe(int pnum)
DEBUG(4,("search for pipe pnum=%x\n", pnum));
- for (p=Pipes;p;p=p->next)
+ for (p=Pipes;p;p=p->next) {
DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
p->name, p->pnum, pipes_open));
+ }
for (p=Pipes;p;p=p->next) {
if (p->pnum == pnum) {
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index 871b1a9f12..1772524038 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -383,7 +383,7 @@ static BOOL api_reg_restore_key(pipes_struct *p)
if(!reg_io_q_restore_key("", &q_u, data, 0))
return False;
-
+
r_u.status = _reg_restore_key(p, &q_u, &r_u);
if(!reg_io_r_restore_key("", &r_u, rdata, 0))
@@ -393,7 +393,7 @@ static BOOL api_reg_restore_key(pipes_struct *p)
}
/*******************************************************************
- ******************************************************************/
+ ********************************************************************/
static BOOL api_reg_save_key(pipes_struct *p)
{
@@ -417,6 +417,57 @@ static BOOL api_reg_save_key(pipes_struct *p)
}
/*******************************************************************
+ api_reg_open_hkpd
+ ********************************************************************/
+
+static BOOL api_reg_open_hkpd(pipes_struct *p)
+{
+ 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;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg open */
+ if(!reg_io_q_open_hive("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_open_hkpd(p, &q_u, &r_u);
+
+ if(!reg_io_r_open_hive("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ api_reg_open_hkpd
+ ********************************************************************/
+static BOOL api_reg_open_hkpt(pipes_struct *p)
+{
+ 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;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg open */
+ if(!reg_io_q_open_hive("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _reg_open_hkpt(p, &q_u, &r_u);
+
+ if(!reg_io_r_open_hive("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
******************************************************************/
static BOOL api_reg_create_key_ex(pipes_struct *p)
@@ -573,6 +624,8 @@ static struct api_struct api_reg_cmds[] =
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
{ "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
{ "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
+ { "REG_OPEN_HKPD" , REG_OPEN_HKPD , api_reg_open_hkpd },
+ { "REG_OPEN_HKPT" , REG_OPEN_HKPT , api_reg_open_hkpt },
{ "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
{ "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },
{ "REG_ENUM_VALUE" , REG_ENUM_VALUE , api_reg_enum_value },
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index a405948864..4db5ed0ed6 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -33,62 +33,9 @@
#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
+static struct generic_mapping reg_generic_map =
+ { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
-static struct generic_mapping reg_generic_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
-
-/********************************************************************
-********************************************************************/
-
-NTSTATUS registry_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
- uint32 access_desired, uint32 *access_granted )
-{
- NTSTATUS result;
-
- if ( geteuid() == sec_initial_uid() ) {
- DEBUG(5,("registry_access_check: access check bypassed for 'root'\n"));
- *access_granted = REG_KEY_ALL;
- return NT_STATUS_OK;
- }
-
- se_map_generic( &access_desired, &reg_generic_map );
- se_access_check( sec_desc, token, access_desired, access_granted, &result );
-
- return result;
-}
-
-/********************************************************************
-********************************************************************/
-
-SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
-{
- SEC_ACE ace[2];
- SEC_ACCESS mask;
- size_t i = 0;
- SEC_DESC *sd;
- SEC_ACL *acl;
- uint32 sd_size;
-
- /* basic access for Everyone */
-
- init_sec_access(&mask, REG_KEY_READ );
- init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- /* Full Access 'BUILTIN\Administrators' */
-
- init_sec_access(&mask, REG_KEY_ALL );
- init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
-
- /* create the security descriptor */
-
- if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
- return NULL;
-
- if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
- return NULL;
-
- return sd;
-}
/******************************************************************
free() function for REGISTRY_KEY
@@ -96,9 +43,7 @@ SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
static void free_regkey_info(void *ptr)
{
- REGISTRY_KEY *info = (REGISTRY_KEY*)ptr;
-
- SAFE_FREE(info);
+ TALLOC_FREE( ptr );
}
/******************************************************************
@@ -126,89 +71,38 @@ static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
HK[LM|U]\<key>\<key>\...
*******************************************************************/
-static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent,
- const char *subkeyname, uint32 access_granted )
+static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
+ REGISTRY_KEY **keyinfo, REGISTRY_KEY *parent,
+ const char *subkeyname, uint32 access_desired )
{
- REGISTRY_KEY *regkey = NULL;
+ pstring keypath;
+ int path_len;
WERROR result = WERR_OK;
- REGSUBKEY_CTR *subkeys = NULL;
- pstring subkeyname2;
- int subkey_len;
-
- DEBUG(7,("open_registry_key: name = [%s][%s]\n",
- parent ? parent->name : "NULL", subkeyname));
-
- /* strip any trailing '\'s */
- pstrcpy( subkeyname2, subkeyname );
- subkey_len = strlen ( subkeyname2 );
- if ( subkey_len && subkeyname2[subkey_len-1] == '\\' )
- subkeyname2[subkey_len-1] = '\0';
- if ((regkey=SMB_MALLOC_P(REGISTRY_KEY)) == NULL)
- return WERR_NOMEM;
-
- ZERO_STRUCTP( regkey );
-
- /*
- * very crazy, but regedit.exe on Win2k will attempt to call
- * REG_OPEN_ENTRY with a keyname of "". We should return a new
- * (second) handle here on the key->name. regedt32.exe does
- * not do this stupidity. --jerry
- */
-
- if ( !subkey_len ) {
- pstrcpy( regkey->name, parent->name );
- }
- else {
- pstrcpy( regkey->name, "" );
- if ( parent ) {
- pstrcat( regkey->name, parent->name );
- pstrcat( regkey->name, "\\" );
- }
- pstrcat( regkey->name, subkeyname2 );
- }
+ /* create a full registry path and strip any trailing '\'
+ characters */
+
+ pstr_sprintf( keypath, "%s%s%s",
+ parent ? parent->name : "",
+ parent ? "\\" : "",
+ subkeyname );
- /* Look up the table of registry I/O operations */
-
- if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) {
- DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
- regkey->name ));
- result = WERR_BADFILE;
- goto done;
- }
+ path_len = strlen( keypath );
+ if ( path_len && keypath[path_len-1] == '\\' )
+ keypath[path_len-1] = '\0';
- /* check if the path really exists; failed is indicated by -1 */
- /* if the subkey count failed, bail out */
-
- if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
- result = WERR_NOMEM;
- goto done;
- }
-
- if ( fetch_reg_keys( regkey, subkeys ) == -1 ) {
- result = WERR_BADFILE;
- goto done;
- }
+ /* now do the internal open */
- if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) ) {
+ result = regkey_open_internal( keyinfo, keypath, p->pipe_user.nt_user_token, access_desired );
+ if ( !W_ERROR_IS_OK(result) )
+ return result;
+
+ if ( !create_policy_hnd( p, hnd, free_regkey_info, *keyinfo ) ) {
result = WERR_BADFILE;
- goto done;
+ TALLOC_FREE( *keyinfo );
}
- /* save the access mask */
-
- regkey->access_granted = access_granted;
-
-done:
- /* clean up */
-
- TALLOC_FREE( subkeys );
-
- if ( ! NT_STATUS_IS_OK(result) )
- SAFE_FREE( regkey );
- DEBUG(7,("open_registry_key: exit\n"));
-
return result;
}
@@ -332,43 +226,39 @@ 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_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
- SEC_DESC *sec_desc;
- uint32 access_granted = 0;
- NTSTATUS status;
+ REGISTRY_KEY *keyinfo;
- /* perform access checks */
- /* top level keys are done here without passing through the REGISTRY_HOOK api */
+ return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKLM, q_u->access );
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR _reg_open_hkpd(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
+{
+ REGISTRY_KEY *keyinfo;
- if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) )
- return WERR_NOMEM;
-
- status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
- if ( !NT_STATUS_IS_OK(status) )
- return ntstatus_to_werror( status );
-
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, access_granted );
+ return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPD, q_u->access );
}
/*******************************************************************
********************************************************************/
-WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
+WERROR _reg_open_hkpt(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
- SEC_DESC *sec_desc;
- uint32 access_granted = 0;
- NTSTATUS status;
+ REGISTRY_KEY *keyinfo;
- /* perform access checks */
- /* top level keys are done here without passing through the REGISTRY_HOOK api */
+ return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKPT, q_u->access );
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
+{
+ REGISTRY_KEY *keyinfo;
- if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) )
- return WERR_NOMEM;
-
- status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
- if ( !NT_STATUS_IS_OK(status) )
- return ntstatus_to_werror( status );
-
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, access_granted );
+ return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKCR, q_u->access );
}
/*******************************************************************
@@ -376,21 +266,9 @@ WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_
WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HIVE *q_u, REG_R_OPEN_HIVE *r_u)
{
- SEC_DESC *sec_desc;
- uint32 access_granted = 0;
- NTSTATUS status;
-
- /* perform access checks */
- /* top level keys are done here without passing through the REGISTRY_HOOK api */
+ REGISTRY_KEY *keyinfo;
- if ( !(sec_desc = construct_registry_sd( p->mem_ctx )) )
- return WERR_NOMEM;
-
- status = registry_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
- if ( !NT_STATUS_IS_OK(status) )
- return ntstatus_to_werror( status );
-
- return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, access_granted );
+ return open_registry_key( p, &r_u->pol, &keyinfo, NULL, KEY_HKU, q_u->access );
}
/*******************************************************************
@@ -401,9 +279,8 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
{
fstring name;
REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->pol);
- REGISTRY_KEY *newkey;
- uint32 access_granted;
- WERROR result;
+ REGISTRY_KEY *newkey = NULL;
+ uint32 check_rights;
if ( !parent )
return WERR_BADFID;
@@ -412,29 +289,22 @@ WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
/* check granted access first; what is the correct mask here? */
- if ( !(parent->access_granted & (SEC_RIGHTS_ENUM_SUBKEYS|SEC_RIGHTS_CREATE_SUBKEY|SEC_RIGHTS_QUERY_VALUE|SEC_RIGHTS_SET_VALUE)) )
+ check_rights = ( SEC_RIGHTS_ENUM_SUBKEYS|
+ SEC_RIGHTS_CREATE_SUBKEY|
+ SEC_RIGHTS_QUERY_VALUE|
+ SEC_RIGHTS_SET_VALUE);
+
+ if ( !(parent->access_granted & check_rights) )
return WERR_ACCESS_DENIED;
- /* open the key first to get the appropriate REGISTRY_HOOK
- and then check the premissions */
-
- if ( !W_ERROR_IS_OK(result = open_registry_key( p, &r_u->handle, parent, name, 0 )) )
- return result;
-
- newkey = find_regkey_index_by_hnd(p, &r_u->handle);
-
- /* finally allow the backend to check the access for the requested key */
-
- if ( !regkey_access_check( newkey, q_u->access, &access_granted, p->pipe_user.nt_user_token ) ) {
- close_registry_key( p, &r_u->handle );
- return WERR_ACCESS_DENIED;
- }
-
- /* if successful, save the granted access mask */
-
- newkey->access_granted = access_granted;
-
- return WERR_OK;
+ /*
+ * very crazy, but regedit.exe on Win2k will attempt to call
+ * REG_OPEN_ENTRY with a keyname of "". We should return a new
+ * (second) handle here on the key->name. regedt32.exe does
+ * not do this stupidity. --jerry
+ */
+
+ return open_registry_key( p, &r_u->handle, &newkey, parent, name, q_u->access );
}
/*******************************************************************
@@ -454,16 +324,93 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
return WERR_BADFID;
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
+ DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->type));
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));
+ DEBUG(5,("_reg_info: looking up value: [%s]\n", name));
if ( !(regvals = TALLOC_P( p->mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
- for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
+ /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
+ if(regkey->type == REG_KEY_HKPD)
+ {
+ if(strequal(name, "Global"))
+ {
+ uint32 outbuf_len;
+ prs_struct prs_hkpd;
+ prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL);
+ status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, NULL);
+ regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
+ prs_hkpd.data_p, outbuf_len);
+ val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
+ prs_mem_free(&prs_hkpd);
+ }
+ else if(strequal(name, "Counter 009"))
+ {
+ uint32 base_index;
+ uint32 buffer_size;
+ char *buffer;
+
+ buffer = NULL;
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Counter 009",
+ REG_MULTI_SZ, buffer, buffer_size);
+
+ val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
+
+ if(buffer_size > 0)
+ {
+ SAFE_FREE(buffer);
+ status = WERR_OK;
+ }
+ }
+ else if(strequal(name, "Explain 009"))
+ {
+ uint32 base_index;
+ uint32 buffer_size;
+ char *buffer;
+
+ buffer = NULL;
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Explain 009",
+ REG_MULTI_SZ, buffer, buffer_size);
+
+ val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
+
+ if(buffer_size > 0)
+ {
+ SAFE_FREE(buffer);
+ status = WERR_OK;
+ }
+ }
+ else if(isdigit(name[0]))
+ {
+ /* we probably have a request for a specific object here */
+ uint32 outbuf_len;
+ prs_struct prs_hkpd;
+ prs_init(&prs_hkpd, q_u->bufsize, p->mem_ctx, MARSHALL);
+ status = reg_perfcount_get_hkpd(&prs_hkpd, q_u->bufsize, &outbuf_len, name);
+ regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
+ prs_hkpd.data_p, outbuf_len);
+
+ val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
+ prs_mem_free(&prs_hkpd);
+ }
+ else
+ {
+ DEBUG(3,("Unsupported key name [%s] for HKPD.\n", name));
+ return WERR_BADFILE;
+ }
+ }
+ /* HKPT calls can be handled out of reg_dynamic.c with the hkpt_params handler */
+ else
{
+ for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
+ {
DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
if ( strequal( val->valuename, name ) ) {
DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
@@ -472,6 +419,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
}
free_registry_value( val );
+ }
}
init_reg_r_query_value(q_u->ptr_buf, r_u, val, status);
@@ -482,7 +430,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
return status;
}
-
/*****************************************************************************
Implementation of REG_QUERY_KEY
****************************************************************************/
@@ -998,7 +945,7 @@ static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
SEC_ACE ace[2]; /* at most 2 entries */
SEC_ACCESS mask;
SEC_ACL *psa = NULL;
- uint32 sd_size;
+ size_t sd_size;
/* set the owner to BUILTIN\Administrator */
@@ -1092,7 +1039,7 @@ WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u)
WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREATE_KEY_EX *r_u)
{
REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
- REGISTRY_KEY *newparent;
+ REGISTRY_KEY *newparentinfo, *keyinfo;
POLICY_HND newparent_handle;
REGSUBKEY_CTR *subkeys;
BOOL write_result;
@@ -1109,7 +1056,6 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
if ( strrchr( name, '\\' ) ) {
pstring newkeyname;
char *ptr;
- uint32 access_granted;
/* (1) check for enumerate rights on the parent handle. CLients can try
create things like 'SOFTWARE\Samba' on the HKLM handle.
@@ -1122,19 +1068,11 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
ptr = strrchr( newkeyname, '\\' );
*ptr = '\0';
- result = open_registry_key( p, &newparent_handle, parent, newkeyname, 0 );
+ result = open_registry_key( p, &newparent_handle, &newparentinfo,
+ parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) );
+
if ( !W_ERROR_IS_OK(result) )
return result;
-
- newparent = find_regkey_index_by_hnd(p, &newparent_handle);
- SMB_ASSERT( newparent != NULL );
-
- if ( !regkey_access_check( newparent, REG_KEY_READ|REG_KEY_WRITE, &access_granted, p->pipe_user.nt_user_token ) ) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- newparent->access_granted = access_granted;
/* copy the new key name (just the lower most keyname) */
@@ -1142,13 +1080,13 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
}
else {
/* use the existing open key information */
- newparent = parent;
+ newparentinfo = parent;
memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) );
}
/* (3) check for create subkey rights on the correct parent */
- if ( !(newparent->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) {
+ if ( !(newparentinfo->access_granted & SEC_RIGHTS_CREATE_SUBKEY) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
@@ -1160,12 +1098,12 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
/* (4) lookup the current keys and add the new one */
- fetch_reg_keys( newparent, subkeys );
+ fetch_reg_keys( newparentinfo, subkeys );
regsubkey_ctr_addkey( subkeys, name );
/* now write to the registry backend */
- write_result = store_reg_keys( newparent, subkeys );
+ write_result = store_reg_keys( newparentinfo, subkeys );
TALLOC_FREE( subkeys );
@@ -1173,16 +1111,15 @@ WERROR _reg_create_key_ex(pipes_struct *p, REG_Q_CREATE_KEY_EX *q_u, REG_R_CREAT
return WERR_REG_IO_FAILURE;
/* (5) open the new key and return the handle. Note that it is probably
- not correct to grant full access on this open handle. We should pass
- the new open through the regkey_access_check() like we do for
- _reg_open_entry() but this is ok for now. */
+ not correct to grant full access on this open handle. */
- result = open_registry_key( p, &r_u->handle, newparent, name, REG_KEY_ALL );
+ result = open_registry_key( p, &r_u->handle, &keyinfo, newparentinfo, name, REG_KEY_READ );
+ keyinfo->access_granted = REG_KEY_ALL;
done:
/* close any intermediate key handles */
- if ( newparent != parent )
+ if ( newparentinfo != parent )
close_registry_key( p, &newparent_handle );
return result;
@@ -1243,7 +1180,7 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r
WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY *r_u)
{
REGISTRY_KEY *parent = find_regkey_index_by_hnd(p, &q_u->handle);
- REGISTRY_KEY *newparent;
+ REGISTRY_KEY *newparentinfo;
POLICY_HND newparent_handle;
REGSUBKEY_CTR *subkeys;
BOOL write_result;
@@ -1252,6 +1189,15 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
if ( !parent )
return WERR_BADFID;
+
+ /* MSDN says parent the handle must have been opened with DELETE access */
+
+ /* (1) check for delete rights on the parent */
+
+ if ( !(parent->access_granted & STD_RIGHT_DELETE_ACCESS) ) {
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
rpcstr_pull( name, q_u->name.string->buffer, sizeof(name), q_u->name.string->uni_str_len*2, 0 );
@@ -1260,50 +1206,24 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
if ( strrchr( name, '\\' ) ) {
pstring newkeyname;
char *ptr;
- uint32 access_granted;
- /* (1) check for enumerate rights on the parent handle. CLients can try
- create things like 'SOFTWARE\Samba' on the HKLM handle.
- (2) open the path to the child parent key if necessary */
+ /* (2) open the path to the child parent key if necessary */
+ /* split the registry path and save the subkeyname */
- if ( !(parent->access_granted & SEC_RIGHTS_ENUM_SUBKEYS) )
- return WERR_ACCESS_DENIED;
-
pstrcpy( newkeyname, name );
ptr = strrchr( newkeyname, '\\' );
*ptr = '\0';
+ pstrcpy( name, ptr+1 );
- result = open_registry_key( p, &newparent_handle, parent, newkeyname, 0 );
+ result = open_registry_key( p, &newparent_handle, &newparentinfo, parent, newkeyname, (REG_KEY_READ|REG_KEY_WRITE) );
if ( !W_ERROR_IS_OK(result) )
return result;
-
- newparent = find_regkey_index_by_hnd(p, &newparent_handle);
- SMB_ASSERT( newparent != NULL );
-
- if ( !regkey_access_check( newparent, REG_KEY_READ|REG_KEY_WRITE, &access_granted, p->pipe_user.nt_user_token ) ) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- newparent->access_granted = access_granted;
-
- /* copy the new key name (just the lower most keyname) */
-
- pstrcpy( name, ptr+1 );
}
else {
/* use the existing open key information */
- newparent = parent;
- memcpy( &newparent_handle, &q_u->handle, sizeof(POLICY_HND) );
+ newparentinfo = parent;
}
- /* (3) check for create subkey rights on the correct parent */
-
- if ( !(newparent->access_granted & STD_RIGHT_DELETE_ACCESS) ) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
if ( !(subkeys = TALLOC_ZERO_P( p->mem_ctx, REGSUBKEY_CTR )) ) {
result = WERR_NOMEM;
goto done;
@@ -1311,13 +1231,13 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
/* lookup the current keys and delete the new one */
- fetch_reg_keys( newparent, subkeys );
+ fetch_reg_keys( newparentinfo, subkeys );
regsubkey_ctr_delkey( subkeys, name );
/* now write to the registry backend */
- write_result = store_reg_keys( newparent, subkeys );
+ write_result = store_reg_keys( newparentinfo, subkeys );
TALLOC_FREE( subkeys );
@@ -1326,7 +1246,7 @@ WERROR _reg_delete_key(pipes_struct *p, REG_Q_DELETE_KEY *q_u, REG_R_DELETE_KEY
done:
/* close any intermediate key handles */
- if ( newparent != parent )
+ if ( newparentinfo != parent )
close_registry_key( p, &newparent_handle );
return result;
@@ -1414,5 +1334,3 @@ WERROR _reg_set_key_sec(pipes_struct *p, REG_Q_SET_KEY_SEC *q_u, REG_R_SET_KEY_
return WERR_ACCESS_DENIED;
}
-
-
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 656241a73f..b69f03a3a2 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -6,7 +6,7 @@
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Marc Jacobsen 1999,
* Copyright (C) Jeremy Allison 2001-2002,
- * Copyright (C) Jean François Micouleau 1998-2001,
+ * Copyright (C) Jean François Micouleau 1998-2001,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
* Copyright (C) Gerald (Jerry) Carter 2003-2004,
* Copyright (C) Simo Sorce 2003.
@@ -88,17 +88,17 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
SEC_ACL *psa = NULL;
/* basic access for Everyone */
-
+
init_sec_access(&mask, map->generic_execute | map->generic_read );
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
/* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
-
+
init_sec_access(&mask, map->generic_all);
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
/* Add Full Access for Domain Admins if we are a DC */
if ( IS_DC ) {
@@ -108,14 +108,14 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
}
/* if we have a sid, give it some special access */
-
+
if ( sid ) {
init_sec_access( &mask, sid_access );
init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- }
-
+}
+
/* create the security descriptor */
-
+
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -347,7 +347,7 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
uint32 acc_granted;
uint32 des_access = q_u->flags;
NTSTATUS status;
- size_t sd_size;
+ size_t sd_size;
SE_PRIV se_rights;
r_u->status = NT_STATUS_OK;
@@ -421,7 +421,6 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u,
return r_u->status;
}
-
/*******************************************************************
_samr_set_sec_obj
********************************************************************/
@@ -1456,11 +1455,13 @@ static NTSTATUS get_user_info_18(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_
BOOL ret;
NTSTATUS nt_status;
- if (!p->ntlmssp_auth_validated)
+ if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
return NT_STATUS_ACCESS_DENIED;
+ }
- if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
+ if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
return NT_STATUS_ACCESS_DENIED;
+ }
/*
* Do *NOT* do become_root()/unbecome_root() here ! JRA.
@@ -1794,11 +1795,12 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
time_t u_lock_duration, u_reset_time;
NTTIME nt_lock_duration, nt_reset_time;
uint32 lockout;
-
time_t u_logout;
NTTIME nt_logout;
uint32 account_policy_temp;
+
+ time_t seq_num;
uint32 server_role;
uint32 num_users=0, num_groups=0, num_aliases=0;
@@ -1819,19 +1821,19 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
switch (q_u->switch_value) {
case 0x01:
- account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
+ pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
min_pass_len = account_policy_temp;
- account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
pass_hist = account_policy_temp;
- account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
+ pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
flag = account_policy_temp;
- account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
unix_to_nt_time_abs(&nt_expire, u_expire);
@@ -1847,21 +1849,23 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
num_groups=count_sam_groups(&info->disp_info);
unbecome_root();
- account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
u_logout = account_policy_temp;
unix_to_nt_time_abs(&nt_logout, u_logout);
+ if (!pdb_get_seq_num(&seq_num))
+ seq_num = time(NULL);
+
server_role = ROLE_DOMAIN_PDC;
if (lp_server_role() == ROLE_DOMAIN_BDC)
server_role = ROLE_DOMAIN_BDC;
- /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
+ init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), seq_num,
num_users, num_groups, num_aliases, nt_logout, server_role);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
unix_to_nt_time_abs(&nt_logout, u_logout);
init_unk_info3(&ctr->info.inf3, nt_logout);
@@ -1880,18 +1884,21 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
init_unk_info7(&ctr->info.inf7, server_role);
break;
case 0x08:
- init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ if (!pdb_get_seq_num(&seq_num))
+ seq_num = time(NULL);
+
+ init_unk_info8(&ctr->info.inf8, (uint32) seq_num);
break;
case 0x0c:
- account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1)
u_lock_duration *= 60;
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
lockout = account_policy_temp;
unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
@@ -1955,7 +1962,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
strlower_m(account);
-
+
pdb_init_sam(&sam_pass);
become_root();
@@ -1968,7 +1975,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
}
pdb_free_sam(&sam_pass);
-
+
/*********************************************************************
* HEADS UP! If we have to create a new user account, we have to get
* a new RID from somewhere. This used to be done by the passdb
@@ -1979,7 +1986,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
* of what ever passdb backend people may use.
* --jerry (2003-07-10)
*********************************************************************/
-
+
pw = Get_Pwnam(account);
/* determine which user right we need to check based on the acb_info */
@@ -2005,27 +2012,27 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
/* only Domain Admins can add a BDC or domain trust */
se_priv_copy( &se_rights, &se_priv_none );
can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
- }
}
-
+ }
+
DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
p->pipe_user_name, can_add_account ? "True":"False" ));
/********** BEGIN Admin BLOCK **********/
-
+
if ( can_add_account )
become_root();
-
+
if ( !pw ) {
if (*add_script) {
- int add_ret;
-
- all_string_sub(add_script, "%u", account, sizeof(add_script));
- add_ret = smbrun(add_script,NULL);
- DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
- }
+ int add_ret;
+
+ all_string_sub(add_script, "%u", account, sizeof(add_script));
+ add_ret = smbrun(add_script,NULL);
+ DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
+ }
}
-
+
/* implicit call to getpwnam() next. we have a valid SID coming out of this call */
flush_pwnam_cache();
@@ -2147,7 +2154,7 @@ NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u
uint32 acc_granted;
uint32 des_access = q_u->access_mask;
NTSTATUS nt_status;
- size_t sd_size;
+ size_t sd_size;
DEBUG(5,("_samr_connect: %d\n", __LINE__));
@@ -2198,7 +2205,7 @@ NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *
uint32 acc_granted;
uint32 des_access = q_u->access_mask;
NTSTATUS nt_status;
- size_t sd_size;
+ size_t sd_size;
DEBUG(5,("_samr_connect4: %d\n", __LINE__));
@@ -2734,7 +2741,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
return r_u->status;
}
-
+
DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
if (ctr == NULL) {
@@ -2765,7 +2772,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
if ( lp_enable_privileges() )
has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
}
-
+
DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
p->pipe_user_name, has_enough_rights ? "" : " not"));
@@ -2905,7 +2912,7 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
if ( lp_enable_privileges() )
has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
}
-
+
DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
p->pipe_user_name, has_enough_rights ? "" : " not"));
@@ -3597,7 +3604,7 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
gid=map.gid;
/* check if group really exists */
- if ( (grp=getgrgid(gid)) == NULL)
+ if ( (grp=getgrgid(gid)) == NULL)
return NT_STATUS_NO_SUCH_GROUP;
se_priv_copy( &se_rights, &se_add_users );
@@ -4195,6 +4202,8 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
uint32 num_users=0, num_groups=0, num_aliases=0;
uint32 account_policy_temp;
+
+ time_t seq_num;
uint32 server_role;
if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
@@ -4212,19 +4221,19 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
switch (q_u->switch_value) {
case 0x01:
- account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
+ pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
min_pass_len = account_policy_temp;
- account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
pass_hist = account_policy_temp;
- account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
+ pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
flag = account_policy_temp;
- account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
unix_to_nt_time_abs(&nt_expire, u_expire);
@@ -4242,21 +4251,23 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
free_samr_db(info);
- account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
u_logout = account_policy_temp;
unix_to_nt_time_abs(&nt_logout, u_logout);
+ if (!pdb_get_seq_num(&seq_num))
+ seq_num = time(NULL);
+
server_role = ROLE_DOMAIN_PDC;
if (lp_server_role() == ROLE_DOMAIN_BDC)
server_role = ROLE_DOMAIN_BDC;
- /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
+ init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), seq_num,
num_users, num_groups, num_aliases, nt_logout, server_role);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
u_logout = account_policy_temp;
unix_to_nt_time_abs(&nt_logout, u_logout);
@@ -4273,21 +4284,25 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
server_role = ROLE_DOMAIN_PDC;
if (lp_server_role() == ROLE_DOMAIN_BDC)
server_role = ROLE_DOMAIN_BDC;
+
init_unk_info7(&ctr->info.inf7, server_role);
break;
case 0x08:
- init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ if (!pdb_get_seq_num(&seq_num))
+ seq_num = time(NULL);
+
+ init_unk_info8(&ctr->info.inf8, (uint32) seq_num);
break;
case 0x0c:
- account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1)
u_lock_duration *= 60;
- account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
lockout = account_policy_temp;
unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
@@ -4331,17 +4346,17 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R
u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
- account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
- account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
- account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
- account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
- account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
+ pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
+ pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
+ pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
+ pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
+ pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
break;
case 0x02:
break;
case 0x03:
u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
- account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
+ pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
break;
case 0x05:
break;
@@ -4356,9 +4371,9 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R
u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
- account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
- account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
- account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
+ pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
+ pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
+ pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
break;
default:
return NT_STATUS_INVALID_INFO_CLASS;
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 24869d5d2b..1d9a8ecd1d 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -291,7 +291,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
uint32 expire;
time_t new_time;
if (pdb_get_pass_must_change_time(to) == 0) {
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
+ if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
|| expire == (uint32)-1) {
new_time = get_time_t_max();
} else {
@@ -531,7 +531,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
uint32 expire;
time_t new_time;
if (pdb_get_pass_must_change_time(to) == 0) {
- if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire)
+ if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
|| expire == (uint32)-1) {
new_time = get_time_t_max();
} else {
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index cda3f26137..5233d6c252 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -75,7 +75,7 @@ typedef struct _counter_printer_0 {
static counter_printer_0 *counter_list;
-static struct cli_state notify_cli; /* print notify back-channel */
+static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
static uint32 smb_connections=0;
@@ -166,7 +166,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
return;
}
- result = cli_spoolss_reply_close_printer(&notify_cli, notify_cli.mem_ctx, handle);
+ result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle);
if (!W_ERROR_IS_OK(result))
DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
@@ -174,9 +174,8 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
/* if it's the last connection, deconnect the IPC$ share */
if (smb_connections==1) {
- cli_nt_session_close(&notify_cli);
- cli_ulogoff(&notify_cli);
- cli_shutdown(&notify_cli);
+ cli_shutdown(notify_cli_pipe->cli);
+ notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
message_deregister(MSG_PRINTER_NOTIFY2);
/* Tell the connections db we're no longer interested in
@@ -688,7 +687,7 @@ static void notify_system_time(struct spoolss_notify_msg *msg,
return;
}
- if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
+ if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
DEBUG(5, ("notify_system_time: prs_init() failed\n"));
return;
}
@@ -1021,7 +1020,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
}
if ( sending_msg_count ) {
- cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd,
+ rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
data_len, data, p->notify.change, 0 );
}
}
@@ -1075,7 +1074,8 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
Receive a notify2 message list
********************************************************************/
-static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, size_t len)
+static void receive_notify2_message_list(int msg_type, struct process_id src,
+ void *msg, size_t len)
{
size_t msg_count, i;
char *buf = (char *)msg;
@@ -1176,7 +1176,8 @@ static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
drivername));
- message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
return True;
}
@@ -1186,7 +1187,7 @@ static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
over all printers, upgrading ones as necessary
**********************************************************************/
-void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
+void do_drv_upgrade_printer(int msg_type, struct process_id src, void *buf, size_t len)
{
fstring drivername;
int snum;
@@ -1272,7 +1273,8 @@ static BOOL srv_spoolss_reset_printerdata(char* drivername)
DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
drivername));
- message_send_pid(sys_getpid(), MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
return True;
}
@@ -1282,7 +1284,8 @@ static BOOL srv_spoolss_reset_printerdata(char* drivername)
over all printers, resetting printer data as neessary
**********************************************************************/
-void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len)
+void reset_all_printerdata(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
fstring drivername;
int snum;
@@ -2001,7 +2004,10 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* this should not have failed---if it did, report to client */
if ( !W_ERROR_IS_OK(status_win2k) )
+ {
+ status = status_win2k;
goto done;
+ }
}
}
@@ -2479,9 +2485,10 @@ done:
Connect to the client machine.
**********************************************************/
-static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
+static BOOL spoolss_connect_to_client(struct cli_state *the_cli, struct rpc_pipe_client **pp_pipe,
struct in_addr *client_ip, const char *remote_machine)
{
+ NTSTATUS ret;
ZERO_STRUCTP(the_cli);
if(cli_initialise(the_cli) == NULL) {
@@ -2563,10 +2570,10 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
* Now start the NT Domain stuff :-).
*/
- if(cli_nt_session_open(the_cli, PI_SPOOLSS) == False) {
- DEBUG(0,("spoolss_connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli)));
- cli_nt_session_close(the_cli);
- cli_ulogoff(the_cli);
+ *pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret);
+ if(!*pp_pipe) {
+ DEBUG(0,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
+ remote_machine, nt_errstr(ret)));
cli_shutdown(the_cli);
return False;
}
@@ -2589,13 +2596,14 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
* and connect to the IPC$ share anonymously
*/
if (smb_connections==0) {
+ struct cli_state notify_cli; /* print notify back-channel */
fstring unix_printer;
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
ZERO_STRUCT(notify_cli);
- if(!spoolss_connect_to_client(&notify_cli, client_ip, unix_printer))
+ if(!spoolss_connect_to_client(&notify_cli, &notify_cli_pipe, client_ip, unix_printer))
return False;
message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
@@ -2614,7 +2622,7 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
smb_connections++;
- result = cli_spoolss_reply_open_printer(&notify_cli, notify_cli.mem_ctx, printer, localprinter,
+ result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter,
type, handle);
if (!W_ERROR_IS_OK(result))
@@ -6117,17 +6125,12 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
{
+ /* add_printer_hook() will call reload_services() */
+
if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
-
- /*
- * make sure we actually reload the services after
- * this as smb.conf could have a new section in it
- * .... shouldn't .... but could
- */
- reload_services(False);
}
/*
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index e9dd015421..9643b2a724 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -113,7 +113,8 @@ static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int sn
What to do when smb.conf is updated.
********************************************************************/
-static void smb_conf_updated(int msg_type, pid_t src, void *buf, size_t len)
+static void smb_conf_updated(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
DEBUG(10,("smb_conf_updated: Got message saying smb.conf was updated. Reloading.\n"));
reload_services(False);
@@ -1394,7 +1395,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES
become_root();
}
- if (message_send_pid(session_list[snum].pid, MSG_SHUTDOWN, NULL, 0, False))
+ if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
r_u->status = WERR_OK;
if (not_root)
diff --git a/source3/rpc_server/srv_svcctl.c b/source3/rpc_server/srv_svcctl.c
index 6ba26414d3..31d8bbe9b3 100644
--- a/source3/rpc_server/srv_svcctl.c
+++ b/source3/rpc_server/srv_svcctl.c
@@ -310,23 +310,75 @@ static BOOL api_svcctl_query_service_config2(pipes_struct *p)
}
/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_lock_service_db(pipes_struct *p)
+{
+ SVCCTL_Q_LOCK_SERVICE_DB q_u;
+ SVCCTL_R_LOCK_SERVICE_DB 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_lock_service_db("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_lock_service_db(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_lock_service_db("", &r_u, rdata, 0))
+ return False;
+
+ return True;
+}
+
+
+/*******************************************************************
+ ********************************************************************/
+
+static BOOL api_svcctl_unlock_service_db(pipes_struct *p)
+{
+ SVCCTL_Q_UNLOCK_SERVICE_DB q_u;
+ SVCCTL_R_UNLOCK_SERVICE_DB 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_unlock_service_db("", &q_u, data, 0))
+ return False;
+
+ r_u.status = _svcctl_unlock_service_db(p, &q_u, &r_u);
+
+ if(!svcctl_io_r_unlock_service_db("", &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_QUERY_SERVICE_CONFIG2_W", SVCCTL_QUERY_SERVICE_CONFIG2_W, api_svcctl_query_service_config2 },
- { "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 },
- { "SVCCTL_QUERY_SERVICE_STATUSEX_W", SVCCTL_QUERY_SERVICE_STATUSEX_W, api_svcctl_query_service_status_ex }
+ { "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_QUERY_SERVICE_CONFIG2_W" , SVCCTL_QUERY_SERVICE_CONFIG2_W , api_svcctl_query_service_config2 },
+ { "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 },
+ { "SVCCTL_QUERY_SERVICE_STATUSEX_W" , SVCCTL_QUERY_SERVICE_STATUSEX_W , api_svcctl_query_service_status_ex },
+ { "SVCCTL_LOCK_SERVICE_DB" , SVCCTL_LOCK_SERVICE_DB , api_svcctl_lock_service_db },
+ { "SVCCTL_UNLOCK_SERVICE_DB" , SVCCTL_UNLOCK_SERVICE_DB , api_svcctl_unlock_service_db }
};
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index 538b97a2b1..e8df2acb22 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -1,8 +1,11 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Gerald (Jerry) Carter 2005,
+ *
* Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * Largely Rewritten (Again) by:
+ * 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
@@ -19,51 +22,97 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* TODO - Do the OpenService service name matching case-independently, or at least make it an option. */
-
-
#include "includes.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
-#define SERVICEDB_VERSION_V1 1 /* Will there be more? */
-#define INTERNAL_SERVICES_LIST "NETLOGON Spooler"
-
-/* */
-/* scripts will execute from the following libdir, if they are in the enable svcctl=<list of scripts> */
-/* these should likely be symbolic links. Note that information about them will be extracted from the files themselves */
-/* using the LSB standard keynames for various information */
-
-#define SVCCTL_SCRIPT_DIR "/svcctl/"
-
-
-struct service_control_op_table {
+struct service_control_op {
const char *name;
SERVICE_CONTROL_OPS *ops;
};
extern SERVICE_CONTROL_OPS spoolss_svc_ops;
+extern SERVICE_CONTROL_OPS rcinit_svc_ops;
+extern SERVICE_CONTROL_OPS netlogon_svc_ops;
+extern SERVICE_CONTROL_OPS winreg_svc_ops;
-struct service_control_op_table svcctl_ops[] = {
- { "Spooler", &spoolss_svc_ops },
- { "NETLOGON", NULL },
- { NULL, NULL }
-};
+struct service_control_op *svcctl_ops;
+
+static struct generic_mapping scm_generic_map =
+ { SC_MANAGER_READ_ACCESS, SC_MANAGER_WRITE_ACCESS, SC_MANAGER_EXECUTE_ACCESS, SC_MANAGER_ALL_ACCESS };
+static struct generic_mapping svc_generic_map =
+ { SERVICE_READ_ACCESS, SERVICE_WRITE_ACCESS, SERVICE_EXECUTE_ACCESS, SERVICE_ALL_ACCESS };
/********************************************************************
********************************************************************/
+BOOL init_service_op_table( void )
+{
+ const char **service_list = lp_svcctl_list();
+ int num_services = 3 + str_list_count( service_list );
+ int i;
+
+ if ( !(svcctl_ops = TALLOC_ARRAY( NULL, struct service_control_op, num_services+1)) ) {
+ DEBUG(0,("init_service_op_table: talloc() failed!\n"));
+ return False;
+ }
+
+ /* services listed in smb.conf get the rc.init interface */
+
+ for ( i=0; service_list[i]; i++ ) {
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] );
+ svcctl_ops[i].ops = &rcinit_svc_ops;
+ }
+
+ /* add builtin services */
+
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" );
+ svcctl_ops[i].ops = &spoolss_svc_ops;
+ i++;
+
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" );
+ svcctl_ops[i].ops = &netlogon_svc_ops;
+ i++;
+
+ svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" );
+ svcctl_ops[i].ops = &winreg_svc_ops;
+ i++;
+
+ /* NULL terminate the array */
+
+ svcctl_ops[i].name = NULL;
+ svcctl_ops[i].ops = NULL;
+
+ return True;
+}
+
+/********************************************************************
+********************************************************************/
+
+static struct service_control_op* find_service_by_name( const char *name )
+{
+ int i;
+
+ for ( i=0; svcctl_ops[i].name; i++ ) {
+ if ( strequal( name, svcctl_ops[i].name ) )
+ return &svcctl_ops[i];
+ }
+
+ return NULL;
+}
+/********************************************************************
+********************************************************************/
+
static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token,
uint32 access_desired, uint32 *access_granted )
{
NTSTATUS result;
if ( geteuid() == sec_initial_uid() ) {
- DEBUG(5,("svcctl_access_check: access check bypassed for 'root'\n"));
- *access_granted = access_desired;
- return NT_STATUS_OK;
+ DEBUG(5,("svcctl_access_check: using root's token\n"));
+ token = get_root_nt_token();
}
se_access_check( sec_desc, token, access_desired, access_granted, &result );
@@ -81,7 +130,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
size_t i = 0;
SEC_DESC *sd;
SEC_ACL *acl;
- uint32 sd_size;
+ size_t sd_size;
/* basic access for Everyone */
@@ -105,51 +154,13 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
return sd;
}
-/********************************************************************
-********************************************************************/
-
-static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
-{
- SEC_ACE ace[4];
- SEC_ACCESS mask;
- size_t i = 0;
- SEC_DESC *sd;
- SEC_ACL *acl;
- uint32 sd_size;
-
- /* basic access for Everyone */
-
- init_sec_access(&mask, SERVICE_READ_ACCESS );
- init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- init_sec_access(&mask,SERVICE_EXECUTE_ACCESS );
- init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- init_sec_access(&mask,SERVICE_ALL_ACCESS );
- init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
- /* create the security descriptor */
-
- if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
- return NULL;
-
- if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
- return NULL;
-
- return sd;
-}
-
/******************************************************************
free() function for REGISTRY_KEY
*****************************************************************/
static void free_service_handle_info(void *ptr)
{
- SERVICE_INFO *info = (SERVICE_INFO*)ptr;
-
- SAFE_FREE(info->name);
- SAFE_FREE(info);
+ TALLOC_FREE( ptr );
}
/******************************************************************
@@ -171,44 +182,50 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd)
/******************************************************************
*****************************************************************/
-static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle,
+static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, uint32 type,
const char *service, uint32 access_granted )
{
SERVICE_INFO *info = NULL;
WERROR result = WERR_OK;
+ struct service_control_op *s_op;
- if ( !(info = SMB_MALLOC_P( SERVICE_INFO )) )
+ if ( !(info = TALLOC_ZERO_P( NULL, SERVICE_INFO )) )
return WERR_NOMEM;
- ZERO_STRUCTP( info );
-
/* the Service Manager has a NULL name */
- if ( !service ) {
+ info->type = SVC_HANDLE_IS_SCM;
+
+ switch ( type ) {
+ case SVC_HANDLE_IS_SCM:
info->type = SVC_HANDLE_IS_SCM;
- } else {
- int i;
+ break;
+ case SVC_HANDLE_IS_DBLOCK:
+ info->type = SVC_HANDLE_IS_DBLOCK;
+ break;
+
+ case SVC_HANDLE_IS_SERVICE:
info->type = SVC_HANDLE_IS_SERVICE;
/* lookup the SERVICE_CONTROL_OPS */
- for ( i=0; svcctl_ops[i].name; i++ ) {
- if ( strequal( svcctl_ops[i].name, service ) ) {
- info->ops = svcctl_ops[i].ops;
- break;
- }
- }
-
- if ( !svcctl_ops[i].name ) {
+ if ( !(s_op = find_service_by_name( service )) ) {
result = WERR_NO_SUCH_SERVICE;
goto done;
}
+
+ info->ops = s_op->ops;
- if ( !(info->name = SMB_STRDUP( service )) ) {
+ if ( !(info->name = talloc_strdup( info, s_op->name )) ) {
result = WERR_NOMEM;
goto done;
}
+ break;
+
+ default:
+ result = WERR_NO_SUCH_SERVICE;
+ goto done;
}
info->access_granted = access_granted;
@@ -241,11 +258,12 @@ WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVC
if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) )
return WERR_NOMEM;
+ se_map_generic( &q_u->access, &scm_generic_map );
status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
if ( !NT_STATUS_IS_OK(status) )
return ntstatus_to_werror( status );
- return create_open_service_handle( p, &r_u->handle, NULL, access_granted );
+ return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SCM, NULL, access_granted );
}
/********************************************************************
@@ -268,21 +286,18 @@ WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_
if ( !find_service_info_by_hnd( p, &q_u->handle ) )
return WERR_BADFID;
- /* perform access checks */
+ /* perform access checks. Use the root token in order to ensure that we
+ retreive the security descriptor */
- if ( !(sec_desc = construct_service_sd( p->mem_ctx )) )
+ if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) )
return WERR_NOMEM;
+ se_map_generic( &q_u->access, &svc_generic_map );
status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted );
if ( !NT_STATUS_IS_OK(status) )
return ntstatus_to_werror( status );
-
-#if 0 /* FIXME!!! */
- if ( ! get_service_info(service_tdb, service, info) ) {
- return WERR_NO_SUCH_SERVICE;
-#endif
- return create_open_service_handle( p, &r_u->handle, service, access_granted );
+ return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted );
}
/********************************************************************
@@ -299,7 +314,7 @@ WERROR _svcctl_close_service(pipes_struct *p, SVCCTL_Q_CLOSE_SERVICE *q_u, SVCCT
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;
+ const char *display_name;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
/* can only use an SCM handle here */
@@ -308,12 +323,9 @@ WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u,
return WERR_BADFID;
rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0);
-
- /* need a tdb lookup here or something */
- fstrcpy( displayname, "FIX ME!" );
-
- init_svcctl_r_get_display_name( r_u, displayname );
+ display_name = svcctl_lookup_dispname( service, p->pipe_user.nt_user_token );
+ init_svcctl_r_get_display_name( r_u, display_name );
return WERR_OK;
}
@@ -335,87 +347,40 @@ WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_
/* try the service specific status call */
- if ( info->ops )
- return info->ops->service_status( &r_u->svc_status );
-
- /* default action for now */
-
- r_u->svc_status.type = 0x0020;
- r_u->svc_status.state = 0x0004;
- r_u->svc_status.controls_accepted = 0x0005;
-
- return WERR_OK;
+ return info->ops->service_status( info->name, &r_u->svc_status );
}
+/********************************************************************
+********************************************************************/
-/*********************************************************************
- TODO - for internal services, do similar to external services, except
- we have to call the right status routine...
-**********************************************************************/
-
-static WERROR enum_internal_services(TALLOC_CTX *ctx,ENUM_SERVICES_STATUS **svc_ptr, int existing_services, uint32 *added)
+static int enumerate_status( TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_USER_TOKEN *token )
{
- int num_services = 2;
- int i = 0;
- ENUM_SERVICES_STATUS *services=NULL;
-
- if (!svc_ptr || !(*svc_ptr))
- return WERR_NOMEM;
-
- services = *svc_ptr;
-
- if ( (existing_services > 0) && svc_ptr && *svc_ptr ) {
- ENUM_SERVICES_STATUS *tmp_services = NULL;
- uint32 total_svc = existing_services + num_services;
-
- if ( !(tmp_services = TALLOC_REALLOC_ARRAY( ctx, services, ENUM_SERVICES_STATUS, total_svc )) )
- return WERR_NOMEM;
-
- services = tmp_services;
- i += existing_services;
- }
- else {
- if ( !(services = TALLOC_ARRAY( ctx, ENUM_SERVICES_STATUS, num_services )) )
- return WERR_NOMEM;
+ int num_services = 0;
+ int i;
+ ENUM_SERVICES_STATUS *st;
+ const char *display_name;
+
+ /* just count */
+ while ( svcctl_ops[num_services].name )
+ num_services++;
+
+ if ( !(st = TALLOC_ARRAY( ctx, ENUM_SERVICES_STATUS, num_services )) ) {
+ DEBUG(0,("enumerate_status: talloc() failed!\n"));
+ return -1;
}
-
- DEBUG(8,("enum_internal_services: Creating %d services, starting index %d\n",
- num_services, existing_services));
-
- init_unistr( &services[i].servicename, "Spooler" );
- init_unistr( &services[i].displayname, "Print 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" );
+ for ( i=0; i<num_services; i++ ) {
+ init_unistr( &st[i].servicename, svcctl_ops[i].name );
+
+ display_name = svcctl_lookup_dispname( svcctl_ops[i].name, token );
+ init_unistr( &st[i].displayname, display_name );
+
+ svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status );
+ }
- 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;
-
- *added = num_services;
- *svc_ptr = services;
+ *status = st;
- return WERR_OK;
+ return num_services;
}
/********************************************************************
@@ -424,11 +389,12 @@ static WERROR enum_internal_services(TALLOC_CTX *ctx,ENUM_SERVICES_STATUS **svc_
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_int_services, num_ext_services, total_services;
+ uint32 num_services;
int i = 0;
size_t buffer_size = 0;
WERROR result = WERR_OK;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+ NT_USER_TOKEN *token = p->pipe_user.nt_user_token;
/* perform access checks */
@@ -438,50 +404,29 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT
if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) )
return WERR_ACCESS_DENIED;
- num_int_services = 0;
- num_ext_services = 0;
-
- /* num_services = str_list_count( lp_enable_svcctl() ); */
-
- /* here's where we'll read the db of external services */
- /* _svcctl_read_LSB_data(NULL,NULL); */
- /* init_svcctl_db(); */
-
- if ( !(services = TALLOC_ARRAY(p->mem_ctx, ENUM_SERVICES_STATUS, num_int_services+num_ext_services )) )
+ if ( (num_services = enumerate_status( p->mem_ctx, &services, token )) == -1 )
return WERR_NOMEM;
- if ( W_ERROR_IS_OK(enum_internal_services(p->mem_ctx, &services, 0, &num_int_services)) )
- DEBUG(8,("_svcctl_enum_services_status: Got %d internal services\n", num_int_services));
-
-#if 0
- if ( W_ERROR_IS_OK(enum_external_services(p->mem_ctx, &services, num_int_services, &num_ext_services)) )
- DEBUG(8,("_svcctl_enum_services_status: Got %d external services\n", num_ext_services));
-#endif
-
- total_services = num_int_services + num_ext_services;
-
- DEBUG(8,("_svcctl_enum_services_status: total of %d services\n", total_services ));
-
- for ( i=0; i<total_services; i++ ) {
+ 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 ) {
- total_services = 0;
+ num_services = 0;
result = WERR_MORE_DATA;
}
rpcbuf_init(&r_u->buffer, q_u->buffer_size, p->mem_ctx);
if ( W_ERROR_IS_OK(result) ) {
- for ( i=0; i<num_int_services+num_ext_services; i++ )
+ 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 = total_services;
+ r_u->returned = num_services;
if ( !(r_u->resume = TALLOC_P( p->mem_ctx, uint32 )) )
return WERR_NOMEM;
@@ -506,7 +451,7 @@ WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCT
if ( !(info->access_granted & SC_RIGHT_SVC_START) )
return WERR_ACCESS_DENIED;
- return info->ops->start_service();
+ return info->ops->start_service( info->name );
}
/********************************************************************
@@ -517,18 +462,27 @@ WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, S
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
/* perform access checks */
- /* we only support stop so don't get complicated */
-
+
if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) )
return WERR_BADFID;
- if ( q_u->control != SVCCTL_CONTROL_STOP )
- return WERR_ACCESS_DENIED;
-
- if ( !(info->access_granted & SC_RIGHT_SVC_STOP) )
- return WERR_ACCESS_DENIED;
+ switch ( q_u->control ) {
+ case SVCCTL_CONTROL_STOP:
+ if ( !(info->access_granted & SC_RIGHT_SVC_STOP) )
+ return WERR_ACCESS_DENIED;
+
+ return info->ops->stop_service( info->name, &r_u->svc_status );
- return info->ops->stop_service( &r_u->svc_status );
+ case SVCCTL_CONTROL_INTERROGATE:
+ if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) )
+ return WERR_ACCESS_DENIED;
+
+ return info->ops->service_status( info->name, &r_u->svc_status );
+ }
+
+ /* default control action */
+
+ return WERR_ACCESS_DENIED;
}
/********************************************************************
@@ -564,11 +518,8 @@ WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT
WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u )
{
- SERVICE_STATUS_PROCESS ssp;
- POLICY_HND *handle;
- SERVICE_INFO *service_info;
- pstring command;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+ uint32 buffer_size;
/* perform access checks */
@@ -579,68 +530,80 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_
return WERR_ACCESS_DENIED;
/* 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;
-
- /* need to find the service name by the handle that is open */
- handle = &(q_u->handle);
+ 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;
+
+ switch ( q_u->level ) {
+ case SVC_STATUS_PROCESS_INFO:
+ {
+ SERVICE_STATUS_PROCESS svc_stat_proc;
- /* get rid of the easy errors */
+ /* Get the status of the service.. */
+ info->ops->service_status( info->name, &svc_stat_proc.status );
+ svc_stat_proc.process_id = sys_getpid();
+ svc_stat_proc.service_flags = 0x0;
- if (q_u->info_level != SVC_STATUS_PROCESS_INFO) {
- DEBUG(10, ("_svcctl_query_service_status_ex : Invalid information level specified\n"));
- return WERR_UNKNOWN_LEVEL;
+ svcctl_io_service_status_process( "", &svc_stat_proc, &r_u->buffer, 0 );
+ buffer_size = sizeof(SERVICE_STATUS_PROCESS);
+ break;
+ }
+
+ default:
+ return WERR_UNKNOWN_LEVEL;
}
- service_info = find_service_info_by_hnd(p, handle);
-
- if (!service_info) {
- DEBUG(10, ("_svcctl_query_service_status_ex : Can't find the service for the handle\n"));
- return WERR_BADFID;
- }
- if (r_u->needed < (sizeof(SERVICE_STATUS_PROCESS)+sizeof(uint32)+sizeof(uint32))) {
- DEBUG(10, ("_svcctl_query_service_status_ex : buffer size of [%d] is too small.\n",r_u->needed));
- return WERR_INSUFFICIENT_BUFFER;
- }
-
- ZERO_STRUCT(ssp);
-
-#if 0
- if (!strwicmp(service_info->servicetype,"EXTERNAL"))
- ssp.type = SVCCTL_WIN32_OWN_PROC;
- else
- ssp.type = SVCCTL_WIN32_SHARED_PROC;
-#endif
+ buffer_size += buffer_size % 4;
+ r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
- /* Get the status of the service.. */
+ if (buffer_size > q_u->buffer_size )
+ return WERR_MORE_DATA;
+
+ return WERR_OK;
+}
- memset(command, 0, sizeof(command));
+/********************************************************************
+********************************************************************/
-#if 0
- slprintf(command, sizeof(command)-1, "%s%s%s %s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service_info->filename, "status");
+static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG *config, NT_USER_TOKEN *token )
+{
+ REGVAL_CTR *values;
+ REGISTRY_VALUE *val;
- DEBUG(10, ("_svcctl_query_service_status_ex: status command is [%s]\n", command));
+ /* retrieve the registry values for this service */
+
+ if ( !(values = svcctl_fetch_regvalues( name, token )) )
+ return WERR_REG_CORRUPT;
+
+ /* now fill in the individual values */
+
+ config->displayname = TALLOC_ZERO_P( ctx, UNISTR2 );
+ if ( (val = regval_ctr_getvalue( values, "DisplayName" )) != NULL )
+ init_unistr2( config->displayname, regval_sz( val ), UNI_STR_TERMINATE );
+ else
+ init_unistr2( config->displayname, name, UNI_STR_TERMINATE );
- /* TODO - wrap in privilege check */
+ if ( (val = regval_ctr_getvalue( values, "ObjectName" )) != NULL ) {
+ config->startname = TALLOC_ZERO_P( ctx, UNISTR2 );
+ init_unistr2( config->startname, regval_sz( val ), UNI_STR_TERMINATE );
+ }
+
+ if ( (val = regval_ctr_getvalue( values, "ImagePath" )) != NULL ) {
+ config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 );
+ init_unistr2( config->executablepath, regval_sz( val ), UNI_STR_TERMINATE );
+ }
- ret = smbrun(command, &fd);
- DEBUGADD(10, ("returned [%d]\n", ret));
- close(fd);
- if(ret != 0)
- DEBUG(10, ("_svcctl_query_service_status_ex: Command returned [%d]\n", ret));
+ /* a few hard coded values */
+ /* loadordergroup and dependencies are empty */
+
+ config->tag_id = 0x00000000; /* unassigned loadorder group */
+ config->service_type = SVCCTL_WIN32_OWN_PROC;
+ config->start_type = SVCCTL_DEMAND_START;
+ config->error_control = SVCCTL_SVC_ERROR_NORMAL;
- /* SET all service_stats bits here... */
- if (ret == 0) {
- ssp.state = SVCCTL_RUNNING;
- ssp.controls_accepted = SVCCTL_CONTROL_SHUTDOWN | SVCCTL_CONTROL_STOP;
- } else {
- ssp.state = SVCCTL_STOPPED;
- ssp.controls_accepted = 0;
- }
-#endif
+ TALLOC_FREE( values );
return WERR_OK;
}
@@ -650,10 +613,9 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_
WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG *r_u )
{
- POLICY_HND *handle;
- SERVICE_INFO *service_info;
- uint32 needed_size;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+ uint32 buffer_size;
+ WERROR wresult;
/* perform access checks */
@@ -667,89 +629,19 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON
incoming buffer size (even in the case of failure */
r_u->needed = q_u->buffer_size;
+
+ wresult = fill_svc_config( p->mem_ctx, info->name, &r_u->config, p->pipe_user.nt_user_token );
+ if ( !W_ERROR_IS_OK(wresult) )
+ return wresult;
+
+ buffer_size = svcctl_sizeof_service_config( &r_u->config );
+ r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
- /* need to find the service name by the handle that is open */
- handle = &(q_u->handle);
-
- service_info = find_service_info_by_hnd(p, handle);
-
-#if 0
- if (q_u->buffer_size < sizeof(Service_info)) {
- /* have to report need more... */
- /* TODO worst case -- should actualy calc what we need here. */
- r_u->needed = sizeof(Service_info)+sizeof(pstring)*5;
- DEBUG(10, ("_svcctl_query_service_config: NOT ENOUGH BUFFER ALLOCATED FOR RETURN DATA -- provided %d wanted %d\n",
- q_u->buffer_size,r_u->needed));
-
- return WERR_INSUFFICIENT_BUFFER;
- }
-#endif
- if (!service_info) {
- DEBUG(10, ("_svcctl_query_service_config : Can't find the service for the handle\n"));
- return WERR_BADFID;
- }
-
-#if 0
- if ( !(service_config = (SERVICE_CONFIG *)TALLOC_ZERO_P(p->mem_ctx, SERVICE_CONFIG)) )
- return WERR_NOMEM;
-#endif
-
- r_u->config.service_type = SVCCTL_WIN32_OWN_PROC;
- r_u->config.start_type = SVCCTL_DEMAND_START;
- r_u->config.error_control = SVCCTL_SVC_ERROR_IGNORE;
- r_u->config.tag_id = 0x00000000;
-
- /* Init the strings */
-
- r_u->config.executablepath = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
- r_u->config.loadordergroup = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
- r_u->config.dependencies = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
- r_u->config.startname = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
- r_u->config.displayname = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
-
-#if 0
- pstrcpy(fullpathinfo,dyn_LIBDIR);
- pstrcat(fullpathinfo,SVCCTL_SCRIPT_DIR);
- pstrcat(fullpathinfo,service_info->filename);
- /* Get and calculate the size of the fields. Note that we're still building the fields in the "too-small buffer case"
- even though we throw it away. */
-
- DEBUG(10, ("_svcctl_query_service_config: fullpath info [%s]\n",fullpathinfo));
- init_unistr2(r_u->config.executablepath,fullpathinfo,UNI_STR_TERMINATE);
- init_unistr2(r_u->config.loadordergroup,"",UNI_STR_TERMINATE);
- init_unistr2(r_u->config.dependencies,service_info->dependencies,UNI_STR_TERMINATE);
-
- /* TODO - if someone really cares, perhaps "LocalSystem" should be changed to something else here... */
-
- init_unistr2(r_u->config.startname,"LocalSystem",UNI_STR_TERMINATE);
- init_unistr2(r_u->config.displayname,service_info->servicename,UNI_STR_TERMINATE);
-#endif
-
- needed_size = 0x04 + sizeof(SERVICE_CONFIG)+ 2*(
- r_u->config.executablepath->uni_str_len +
- r_u->config.loadordergroup->uni_str_len +
- r_u->config.dependencies->uni_str_len +
- r_u->config.startname->uni_str_len +
- r_u->config.displayname->uni_str_len);
-
- DEBUG(10, ("_svcctl_query_service_config: ****** need to have a buffer of [%d], [%d] for struct \n",needed_size,
- sizeof(SERVICE_CONFIG)));
- DEBUG(10, ("\tsize of executable path : %d\n",r_u->config.executablepath->uni_str_len));
- DEBUG(10, ("\tsize of loadordergroup : %d\n", r_u->config.loadordergroup->uni_str_len));
- DEBUG(10, ("\tsize of dependencies : %d\n", r_u->config.dependencies->uni_str_len));
- DEBUG(10, ("\tsize of startname : %d\n", r_u->config.startname->uni_str_len));
- DEBUG(10, ("\tsize of displayname : %d\n", r_u->config.displayname->uni_str_len));
-
- if (q_u->buffer_size < needed_size) {
- /* have to report need more...*/
- r_u->needed = needed_size;
- DEBUG(10, ("_svcctl_query_service_config: ****** zeroing strings for return\n"));
- memset(&r_u->config,0,sizeof(SERVICE_CONFIG));
- DEBUG(10, ("_svcctl_query_service_config: Not enouh buffer provided for return -- provided %d wanted %d\n",
- q_u->buffer_size,needed_size));
- return WERR_INSUFFICIENT_BUFFER;
+ if (buffer_size > q_u->buffer_size ) {
+ ZERO_STRUCTP( &r_u->config );
+ return WERR_INSUFFICIENT_BUFFER;
}
-
+
return WERR_OK;
}
@@ -758,9 +650,8 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON
WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CONFIG2 *q_u, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u )
{
- POLICY_HND *handle;
- SERVICE_INFO *service_info;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+ uint32 buffer_size;
/* perform access checks */
@@ -773,55 +664,84 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO
/* 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;
- r_u->description = NULL;
- r_u->returned = q_u->buffer_size;
- r_u->offset = 4;
+ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
+ r_u->needed = q_u->buffer_size;
- handle = &(q_u->handle);
+ switch ( q_u->level ) {
+ case SERVICE_CONFIG_DESCRIPTION:
+ {
+ SERVICE_DESCRIPTION desc_buf;
+ const char *description;
+
+ description = svcctl_lookup_description( info->name, p->pipe_user.nt_user_token );
+
+ ZERO_STRUCTP( &desc_buf );
- service_info = find_service_info_by_hnd(p, handle);
+ init_service_description_buffer( &desc_buf, description );
+ svcctl_io_service_description( "", &desc_buf, &r_u->buffer, 0 );
+ buffer_size = svcctl_sizeof_service_description( &desc_buf );
- if (!service_info) {
- DEBUG(10, ("_svcctl_query_service_config2 : Can't find the service for the handle\n"));
- return WERR_BADFID;
- }
-
- /*
- TODO - perhaps move the RPC_DATA_BLOB into the R_QUERY_SERVICE_CONFIG structure, and to the processing in here, vs
- in the *r_query_config2 marshalling routine...
- */
-
-#if 0
- if (SERVICE_CONFIG_DESCRIPTION == q_u->info_level) {
- if (service_info && service_info->shortdescription) {
- /* length of the string, plus the terminator... */
- string_buffer_size = strlen(service_info->shortdescription)+1;
- DEBUG(10, ("_svcctl_query_service_config: copying the description [%s] length [%d]\n",
- service_info->shortdescription,string_buffer_size));
-
- if (q_u->buffer_size >= ((string_buffer_size)*2+4)) {
- r_u->description = TALLOC_ZERO_P(p->mem_ctx, UNISTR2);
- if (!r_u->description) return WERR_NOMEM;
- init_unistr2(r_u->description,service_info->shortdescription,UNI_STR_TERMINATE);
- }
+ break;
}
- else {
- string_buffer_size = 0;
- }
- DEBUG(10, ("_svcctl_query_service_config2: buffer needed is [%x], return buffer size is [%x]\n",
- string_buffer_size,q_u->buffer_size));
- if (((string_buffer_size)*2+4) > q_u->buffer_size) {
- r_u->needed = (string_buffer_size+1)*2+4;
- DEBUG(10, ("_svcctl_query_service_config2: INSUFFICIENT BUFFER\n"));
- return WERR_INSUFFICIENT_BUFFER;
+ break;
+ case SERVICE_CONFIG_FAILURE_ACTIONS:
+ {
+ SERVICE_FAILURE_ACTIONS actions;
+
+ /* nothing to say...just service the request */
+
+ ZERO_STRUCTP( &actions );
+ svcctl_io_service_fa( "", &actions, &r_u->buffer, 0 );
+ buffer_size = svcctl_sizeof_service_fa( &actions );
+
+ break;
}
- DEBUG(10, ("_svcctl_query_service_config2: returning ok, needed is [%x], buffer size is [%x]\n",
- r_u->needed,q_u->buffer_size));
+ break;
+
+ default:
+ return WERR_UNKNOWN_LEVEL;
+ }
+
+ buffer_size += buffer_size % 4;
+ r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
- return WERR_OK;
- }
-#endif
+ if (buffer_size > q_u->buffer_size )
+ return WERR_INSUFFICIENT_BUFFER;
- return WERR_ACCESS_DENIED;
+ return WERR_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_lock_service_db( pipes_struct *p, SVCCTL_Q_LOCK_SERVICE_DB *q_u, SVCCTL_R_LOCK_SERVICE_DB *r_u )
+{
+ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+
+ /* perform access checks */
+
+ if ( !info || (info->type != SVC_HANDLE_IS_SCM) )
+ return WERR_BADFID;
+
+ if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) )
+ return WERR_ACCESS_DENIED;
+
+ /* Just open a handle. Doesn't actually lock anything */
+
+ return create_open_service_handle( p, &r_u->h_lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 );
+;
+}
+
+/********************************************************************
+********************************************************************/
+
+WERROR _svcctl_unlock_service_db( pipes_struct *p, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, SVCCTL_R_UNLOCK_SERVICE_DB *r_u )
+{
+ SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->h_lock );
+
+
+ if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) )
+ return WERR_BADFID;
+
+ return close_policy_hnd( p, &q_u->h_lock) ? WERR_OK : WERR_BADFID;
}
diff --git a/source3/rpcclient/cmd_dfs.c b/source3/rpcclient/cmd_dfs.c
index 44e97f9881..956dbfa402 100644
--- a/source3/rpcclient/cmd_dfs.c
+++ b/source3/rpcclient/cmd_dfs.c
@@ -24,7 +24,7 @@
/* Check DFS is supported by the remote server */
-static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_dfs_exist(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
BOOL dfs_exists;
@@ -35,7 +35,7 @@ static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- result = cli_dfs_exist(cli, mem_ctx, &dfs_exists);
+ result = rpccli_dfs_exist(cli, mem_ctx, &dfs_exists);
if (NT_STATUS_IS_OK(result))
printf("dfs is %spresent\n", dfs_exists ? "" : "not ");
@@ -43,7 +43,7 @@ static NTSTATUS cmd_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-static NTSTATUS cmd_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_dfs_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
NTSTATUS result;
@@ -61,13 +61,13 @@ static NTSTATUS cmd_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
sharename = argv[3];
comment = argv[4];
- result = cli_dfs_add(cli, mem_ctx, entrypath, servername,
+ result = rpccli_dfs_add(cli, mem_ctx, entrypath, servername,
sharename, comment, flags);
return result;
}
-static NTSTATUS cmd_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_dfs_remove(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
NTSTATUS result;
@@ -82,7 +82,7 @@ static NTSTATUS cmd_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
servername = argv[2];
sharename = argv[3];
- result = cli_dfs_remove(cli, mem_ctx, entrypath, servername,
+ result = rpccli_dfs_remove(cli, mem_ctx, entrypath, servername,
sharename);
return result;
@@ -168,7 +168,7 @@ static void display_dfs_info_ctr(DFS_INFO_CTR *ctr)
/* Enumerate dfs shares */
-static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_dfs_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
DFS_INFO_CTR ctr;
@@ -183,7 +183,7 @@ static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc == 2)
info_level = atoi(argv[1]);
- result = cli_dfs_enum(cli, mem_ctx, info_level, &ctr);
+ result = rpccli_dfs_enum(cli, mem_ctx, info_level, &ctr);
if (NT_STATUS_IS_OK(result))
display_dfs_info_ctr(&ctr);
@@ -191,7 +191,7 @@ static NTSTATUS cmd_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
-static NTSTATUS cmd_dfs_getinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_dfs_getinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
NTSTATUS result;
@@ -212,7 +212,7 @@ static NTSTATUS cmd_dfs_getinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc == 5)
info_level = atoi(argv[4]);
- result = cli_dfs_get_info(cli, mem_ctx, entrypath, servername,
+ result = rpccli_dfs_get_info(cli, mem_ctx, entrypath, servername,
sharename, info_level, &ctr);
if (NT_STATUS_IS_OK(result))
@@ -227,11 +227,11 @@ struct cmd_set dfs_commands[] = {
{ "DFS" },
- { "dfsexist", RPC_RTYPE_NTSTATUS, cmd_dfs_exist, NULL, PI_NETDFS, "Query DFS support", "" },
- { "dfsadd", RPC_RTYPE_NTSTATUS, cmd_dfs_add, NULL, PI_NETDFS, "Add a DFS share", "" },
- { "dfsremove", RPC_RTYPE_NTSTATUS, cmd_dfs_remove, NULL, PI_NETDFS, "Remove a DFS share", "" },
- { "dfsgetinfo",RPC_RTYPE_NTSTATUS, cmd_dfs_getinfo, NULL, PI_NETDFS, "Query DFS share info", "" },
- { "dfsenum", RPC_RTYPE_NTSTATUS, cmd_dfs_enum, NULL, PI_NETDFS, "Enumerate dfs shares", "" },
+ { "dfsexist", RPC_RTYPE_NTSTATUS, cmd_dfs_exist, NULL, PI_NETDFS, NULL, "Query DFS support", "" },
+ { "dfsadd", RPC_RTYPE_NTSTATUS, cmd_dfs_add, NULL, PI_NETDFS, NULL, "Add a DFS share", "" },
+ { "dfsremove", RPC_RTYPE_NTSTATUS, cmd_dfs_remove, NULL, PI_NETDFS, NULL, "Remove a DFS share", "" },
+ { "dfsgetinfo",RPC_RTYPE_NTSTATUS, cmd_dfs_getinfo, NULL, PI_NETDFS, NULL, "Query DFS share info", "" },
+ { "dfsenum", RPC_RTYPE_NTSTATUS, cmd_dfs_enum, NULL, PI_NETDFS, NULL, "Enumerate dfs shares", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_ds.c b/source3/rpcclient/cmd_ds.c
index 0a1fd7e012..951d18a710 100644
--- a/source3/rpcclient/cmd_ds.c
+++ b/source3/rpcclient/cmd_ds.c
@@ -24,14 +24,14 @@
/* Look up domain related information on a remote host */
-static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct cli_state *cli,
+static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
NTSTATUS result;
DS_DOMINFO_CTR ctr;
- result = cli_ds_getprimarydominfo( cli, mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr );
+ result = rpccli_ds_getprimarydominfo( cli, mem_ctx, DsRolePrimaryDomainInfoBasic, &ctr );
if ( NT_STATUS_IS_OK(result) )
{
printf ("Machine Role = [%d]\n", ctr.basic->machine_role);
@@ -47,7 +47,7 @@ static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct cli_state *cli,
return result;
}
-static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli,
+static NTSTATUS cmd_ds_enum_domain_trusts(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -57,7 +57,7 @@ static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli,
unsigned int num_domains = 0;
int i;
- result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags,
+ result = rpccli_ds_enum_domain_trusts( cli, mem_ctx, cli->cli->desthost, flags,
&trusts, &num_domains );
printf( "%d domains returned\n", num_domains );
@@ -74,8 +74,8 @@ struct cmd_set ds_commands[] = {
{ "LSARPC-DS" },
- { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" },
- { "dsenumdomtrusts", RPC_RTYPE_NTSTATUS, cmd_ds_enum_domain_trusts, NULL, PI_NETLOGON, "Enumerate all trusted domains in an AD forest", "" },
+ { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, NULL, "Get Primary Domain Information", "" },
+ { "dsenumdomtrusts", RPC_RTYPE_NTSTATUS, cmd_ds_enum_domain_trusts, NULL, PI_NETLOGON, NULL, "Enumerate all trusted domains in an AD forest", "" },
- { NULL }
+{ NULL }
};
diff --git a/source3/rpcclient/cmd_echo.c b/source3/rpcclient/cmd_echo.c
index fce8e4c7b8..6d608ebaf1 100644
--- a/source3/rpcclient/cmd_echo.c
+++ b/source3/rpcclient/cmd_echo.c
@@ -22,7 +22,7 @@
#include "includes.h"
#include "rpcclient.h"
-static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_echo_add_one(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
uint32 request = 1, response;
@@ -36,7 +36,7 @@ static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (argc == 2)
request = atoi(argv[1]);
- result = cli_echo_add_one(cli, mem_ctx, request, &response);
+ result = rpccli_echo_add_one(cli, mem_ctx, request, &response);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -47,7 +47,7 @@ done:
return result;
}
-static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_echo_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
uint32 size, i;
@@ -65,7 +65,7 @@ static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
for (i = 0; i < size; i++)
in_data[i] = i & 0xff;
- result = cli_echo_data(cli, mem_ctx, size, in_data, &out_data);
+ result = rpccli_echo_data(cli, mem_ctx, size, in_data, &out_data);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -84,7 +84,7 @@ done:
return result;
}
-static NTSTATUS cmd_echo_source_data(struct cli_state *cli,
+static NTSTATUS cmd_echo_source_data(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -99,7 +99,7 @@ static NTSTATUS cmd_echo_source_data(struct cli_state *cli,
size = atoi(argv[1]);
- result = cli_echo_source_data(cli, mem_ctx, size, &out_data);
+ result = rpccli_echo_source_data(cli, mem_ctx, size, &out_data);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -116,7 +116,7 @@ done:
return result;
}
-static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_echo_sink_data(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
uint32 size, i;
@@ -134,7 +134,7 @@ static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
for (i = 0; i < size; i++)
in_data[i] = i & 0xff;
- result = cli_echo_sink_data(cli, mem_ctx, size, in_data);
+ result = rpccli_echo_sink_data(cli, mem_ctx, size, in_data);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -151,9 +151,9 @@ struct cmd_set echo_commands[] = {
{ "ECHO" },
- { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, "Add one to a number", "" },
- { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, "Echo data", "" },
- { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, "Sink data", "" },
- { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, "Source data", "" },
+ { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, NULL, "Add one to a number", "" },
+ { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, NULL, "Echo data", "" },
+ { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, NULL, "Sink data", "" },
+ { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, NULL, "Source data", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index b01f639247..00ed515245 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -26,7 +26,7 @@
/* useful function to allow entering a name instead of a SID and
* looking it up automatically */
-static NTSTATUS name_to_sid(struct cli_state *cli,
+static NTSTATUS name_to_sid(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
DOM_SID *sid, const char *name)
{
@@ -41,17 +41,17 @@ static NTSTATUS name_to_sid(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
+ result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
if (!NT_STATUS_IS_OK(result))
goto done;
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
*sid = sids[0];
@@ -62,7 +62,7 @@ done:
/* Look up domain related information on a remote host */
-static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
+static NTSTATUS cmd_lsa_query_info_policy(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -88,25 +88,25 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
/* Lookup info policy */
switch (info_class) {
case 12:
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol,
+ result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
info_class, &domain_name,
&dns_name, &forest_name,
&dom_guid, &dom_sid);
break;
default:
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_info_policy(cli, mem_ctx, &pol,
+ result = rpccli_lsa_query_info_policy(cli, mem_ctx, &pol,
info_class, &domain_name,
&dom_sid);
}
@@ -130,13 +130,16 @@ static NTSTATUS cmd_lsa_query_info_policy(struct cli_state *cli,
printf("domain GUID is ");
smb_uuid_string_static(*dom_guid);
}
+
+ rpccli_lsa_close(cli, mem_ctx, &pol);
+
done:
return result;
}
/* Resolve a list of names to a list of sids */
-static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
+static NTSTATUS cmd_lsa_lookup_names(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -151,14 +154,14 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
+ result = rpccli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
(const char**)(argv + 1), &sids, &types);
if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
@@ -176,7 +179,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
sid_type_lookup(types[i]), types[i]);
}
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
@@ -184,7 +187,7 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
/* Resolve a list of SIDs to a list of names */
-static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
POLICY_HND pol;
@@ -200,7 +203,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
@@ -224,7 +227,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Lookup the SIDs */
- result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
+ result = rpccli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
&domains, &names, &types);
if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) !=
@@ -244,7 +247,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
names[i] ? names[i] : "*unknown*", types[i]);
}
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
@@ -252,7 +255,7 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Enumerate list of trusted domains */
-static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
+static NTSTATUS cmd_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -275,7 +278,7 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
enum_ctx = atoi(argv[2]);
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
POLICY_VIEW_LOCAL_INFORMATION,
&pol);
@@ -288,7 +291,7 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
/* Lookup list of trusted domains */
- result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
+ result = rpccli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
&num_domains,
&domain_names, &domain_sids);
if (!NT_STATUS_IS_OK(result) &&
@@ -307,13 +310,14 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
}
}
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
/* Enumerates privileges */
-static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
+static NTSTATUS cmd_lsa_enum_privilege(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -339,14 +343,14 @@ static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
if (argc==3)
pref_max_length=atoi(argv[2]);
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_enum_privilege(cli, mem_ctx, &pol, &enum_context, pref_max_length,
+ result = rpccli_lsa_enum_privilege(cli, mem_ctx, &pol, &enum_context, pref_max_length,
&count, &privs_name, &privs_high, &privs_low);
if (!NT_STATUS_IS_OK(result))
@@ -360,13 +364,14 @@ static NTSTATUS cmd_lsa_enum_privilege(struct cli_state *cli,
privs_high[i], privs_low[i], privs_high[i], privs_low[i]);
}
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
/* Get privilege name */
-static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
+static NTSTATUS cmd_lsa_get_dispname(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -383,14 +388,14 @@ static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_get_dispname(cli, mem_ctx, &pol, argv[1], lang_id, lang_id_sys, description, &lang_id_desc);
+ result = rpccli_lsa_get_dispname(cli, mem_ctx, &pol, argv[1], lang_id, lang_id_sys, description, &lang_id_desc);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -398,13 +403,14 @@ static NTSTATUS cmd_lsa_get_dispname(struct cli_state *cli,
/* Print results */
printf("%s -> %s (language: 0x%x)\n", argv[1], description, lang_id_desc);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
/* Enumerate the LSA SIDS */
-static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
+static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -428,14 +434,14 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
if (argc==3)
pref_max_length=atoi(argv[2]);
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length,
+ result = rpccli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length,
&count, &sids);
if (!NT_STATUS_IS_OK(result))
@@ -451,13 +457,14 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
printf("%s\n", sid_str);
}
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
/* Create a new account */
-static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
+static NTSTATUS cmd_lsa_create_account(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -477,14 +484,14 @@ static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_create_account(cli, mem_ctx, &dom_pol, &sid, des_access, &user_pol);
+ result = rpccli_lsa_create_account(cli, mem_ctx, &dom_pol, &sid, des_access, &user_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -492,6 +499,7 @@ static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
printf("Account for SID %s successfully created\n\n", argv[1]);
result = NT_STATUS_OK;
+ rpccli_lsa_close(cli, mem_ctx, &dom_pol);
done:
return result;
}
@@ -499,7 +507,7 @@ static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
/* Enumerate the privileges of an SID */
-static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
+static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -522,19 +530,19 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol);
+ result = rpccli_lsa_open_account(cli, mem_ctx, &dom_pol, &sid, access_desired, &user_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set);
+ result = rpccli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -547,6 +555,7 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr);
}
+ rpccli_lsa_close(cli, mem_ctx, &dom_pol);
done:
return result;
}
@@ -554,7 +563,7 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
/* Enumerate the privileges of an SID via LsaEnumerateAccountRights */
-static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
+static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -576,14 +585,14 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, &sid, &count, &rights);
+ result = rpccli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, &sid, &count, &rights);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -594,6 +603,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
printf("\t%s\n", rights[i]);
}
+ rpccli_lsa_close(cli, mem_ctx, &dom_pol);
done:
return result;
}
@@ -601,7 +611,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
/* add some privileges to a SID via LsaAddAccountRights */
-static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli,
+static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -619,19 +629,20 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
+ result = rpccli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
argc-2, argv+2);
if (!NT_STATUS_IS_OK(result))
goto done;
+ rpccli_lsa_close(cli, mem_ctx, &dom_pol);
done:
return result;
}
@@ -639,7 +650,7 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct cli_state *cli,
/* remove some privileges to a SID via LsaRemoveAccountRights */
-static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli,
+static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -657,19 +668,21 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
+ result = rpccli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
False, argc-2, argv+2);
if (!NT_STATUS_IS_OK(result))
goto done;
+ rpccli_lsa_close(cli, mem_ctx, &dom_pol);
+
done:
return result;
}
@@ -677,7 +690,7 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli,
/* Get a privilege value given its name */
-static NTSTATUS cmd_lsa_lookup_priv_value(struct cli_state *cli,
+static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -690,14 +703,14 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_lookup_priv_value(cli, mem_ctx, &pol, argv[1], &luid);
+ result = rpccli_lsa_lookup_priv_value(cli, mem_ctx, &pol, argv[1], &luid);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -706,13 +719,14 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct cli_state *cli,
printf("%u:%u (0x%x:0x%x)\n", luid.high, luid.low, luid.high, luid.low);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
/* Query LSA security object */
-static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
+static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -726,14 +740,14 @@ static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_secobj(cli, mem_ctx, &pol, sec_info, &sdb);
+ result = rpccli_lsa_query_secobj(cli, mem_ctx, &pol, sec_info, &sdb);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -742,6 +756,7 @@ static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
display_sec_desc(sdb->sec);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
done:
return result;
}
@@ -800,7 +815,7 @@ static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_cl
}
}
-static NTSTATUS cmd_lsa_query_trustdominfobysid(struct cli_state *cli,
+static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -823,12 +838,12 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct cli_state *cli,
if (argc == 3)
info_class = atoi(argv[2]);
- result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, &pol,
+ result = rpccli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, &pol,
info_class, &dom_sid, &info);
if (!NT_STATUS_IS_OK(result))
@@ -838,12 +853,12 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct cli_state *cli,
done:
if (&pol)
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
return result;
}
-static NTSTATUS cmd_lsa_query_trustdominfobyname(struct cli_state *cli,
+static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -861,12 +876,12 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct cli_state *cli,
if (argc == 3)
info_class = atoi(argv[2]);
- result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_trusted_domain_info_by_name(cli, mem_ctx, &pol,
+ result = rpccli_lsa_query_trusted_domain_info_by_name(cli, mem_ctx, &pol,
info_class, argv[1], &info);
if (!NT_STATUS_IS_OK(result))
@@ -876,12 +891,12 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct cli_state *cli,
done:
if (&pol)
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
return result;
}
-static NTSTATUS cmd_lsa_query_trustdominfo(struct cli_state *cli,
+static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -904,18 +919,18 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct cli_state *cli,
if (argc == 3)
info_class = atoi(argv[2]);
- result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_open_trusted_domain(cli, mem_ctx, &pol,
+ result = rpccli_lsa_open_trusted_domain(cli, mem_ctx, &pol,
&dom_sid, access_mask, &trustdom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol,
+ result = rpccli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol,
info_class, &dom_sid, &info);
if (!NT_STATUS_IS_OK(result))
@@ -925,7 +940,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct cli_state *cli,
done:
if (&pol)
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(cli, mem_ctx, &pol);
return result;
}
@@ -938,27 +953,27 @@ struct cmd_set lsarpc_commands[] = {
{ "LSARPC" },
- { "lsaquery", RPC_RTYPE_NTSTATUS, cmd_lsa_query_info_policy, NULL, PI_LSARPC, "Query info policy", "" },
- { "lookupsids", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_sids, NULL, PI_LSARPC, "Convert SIDs to names", "" },
- { "lookupnames", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names, NULL, PI_LSARPC, "Convert names to SIDs", "" },
- { "enumtrust", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_trust_dom, NULL, PI_LSARPC, "Enumerate trusted domains", "Usage: [preferred max number] [enum context (0)]" },
- { "enumprivs", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege, NULL, PI_LSARPC, "Enumerate privileges", "" },
- { "getdispname", RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname, NULL, PI_LSARPC, "Get the privilege name", "" },
- { "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, "Enumerate the LSA SIDS", "" },
- { "lsacreateaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_create_account, NULL, PI_LSARPC, "Create a new lsa account", "" },
- { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID", "" },
- { "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, "Enumerate the rights of an SID", "" },
+ { "lsaquery", RPC_RTYPE_NTSTATUS, cmd_lsa_query_info_policy, NULL, PI_LSARPC, NULL, "Query info policy", "" },
+ { "lookupsids", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_sids, NULL, PI_LSARPC, NULL, "Convert SIDs to names", "" },
+ { "lookupnames", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_names, NULL, PI_LSARPC, NULL, "Convert names to SIDs", "" },
+ { "enumtrust", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_trust_dom, NULL, PI_LSARPC, NULL, "Enumerate trusted domains", "Usage: [preferred max number] [enum context (0)]" },
+ { "enumprivs", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege, NULL, PI_LSARPC, NULL, "Enumerate privileges", "" },
+ { "getdispname", RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname, NULL, PI_LSARPC, NULL, "Get the privilege name", "" },
+ { "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, NULL, "Enumerate the LSA SIDS", "" },
+ { "lsacreateaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_create_account, NULL, PI_LSARPC, NULL, "Create a new lsa account", "" },
+ { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, NULL, "Enumerate the privileges of an SID", "" },
+ { "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, NULL, "Enumerate the rights of an SID", "" },
#if 0
{ "lsaaddpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_add_priv, NULL, PI_LSARPC, "Assign a privilege to a SID", "" },
{ "lsadelpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_del_priv, NULL, PI_LSARPC, "Revoke a privilege from a SID", "" },
#endif
- { "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, "Add rights to an account", "" },
- { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" },
- { "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_priv_value, NULL, PI_LSARPC, "Get a privilege value given its name", "" },
- { "lsaquerysecobj", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj, NULL, PI_LSARPC, "Query LSA security object", "" },
- { "lsaquerytrustdominfo",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfo, NULL, PI_LSARPC, "Query LSA trusted domains info (given a SID)", "" },
- { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, PI_LSARPC, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
- { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, PI_LSARPC, "Query LSA trusted domains info (given a SID)", "" },
+ { "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, NULL, "Add rights to an account", "" },
+ { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, NULL, "Remove rights from an account", "" },
+ { "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_priv_value, NULL, PI_LSARPC, NULL, "Get a privilege value given its name", "" },
+ { "lsaquerysecobj", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj, NULL, PI_LSARPC, NULL, "Query LSA security object", "" },
+ { "lsaquerytrustdominfo",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfo, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a SID)", "" },
+ { "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
+ { "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, PI_LSARPC, NULL, "Query LSA trusted domains info (given a SID)", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index b55306ddc8..153daa5cf2 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -22,7 +22,7 @@
#include "includes.h"
#include "rpcclient.h"
-static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -34,7 +34,7 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_netlogon_logon_ctrl2(cli, mem_ctx, query_level);
+ result = rpccli_netlogon_logon_ctrl2(cli, mem_ctx, query_level);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -45,7 +45,7 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
return result;
}
-static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -57,7 +57,7 @@ static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_netlogon_getdcname(cli, mem_ctx, argv[1], dcname);
+ result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -70,7 +70,7 @@ static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli,
return result;
}
-static NTSTATUS cmd_netlogon_logon_ctrl(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -166,7 +166,7 @@ static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas,
/* Perform sam synchronisation */
-static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -174,7 +174,6 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
uint32 database_id = 0, num_deltas;
SAM_DELTA_HDR *hdr_deltas;
SAM_DELTA_CTR *deltas;
- DOM_CRED ret_creds;
if (argc > 2) {
fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
@@ -184,12 +183,9 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
if (argc == 2)
database_id = atoi(argv[1]);
- /* on first call the returnAuthenticator is empty */
- memset(&ret_creds, 0, sizeof(ret_creds));
-
/* Synchronise sam database */
- result = cli_netlogon_sam_sync(cli, mem_ctx, &ret_creds, database_id,
+ result = rpccli_netlogon_sam_sync(cli, mem_ctx, database_id,
0, &num_deltas, &hdr_deltas, &deltas);
if (!NT_STATUS_IS_OK(result))
@@ -205,7 +201,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
/* Perform sam delta synchronisation */
-static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -226,7 +222,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
seqnum.low = tmp & 0xffff;
seqnum.high = 0;
- result = cli_netlogon_sam_deltas(cli, mem_ctx, database_id,
+ result = rpccli_netlogon_sam_deltas(cli, mem_ctx, database_id,
seqnum, &num_deltas,
&hdr_deltas, &deltas);
@@ -243,7 +239,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
/* Log on a domain user */
-static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_sam_logon(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -252,7 +248,6 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
const char *username, *password;
uint32 neg_flags = 0x000001ff;
int auth_level = 2;
- DOM_CRED ret_creds;
/* Check arguments */
@@ -277,12 +272,8 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
/* Perform the sam logon */
- ZERO_STRUCT(ret_creds);
+ result = rpccli_netlogon_sam_logon(cli, mem_ctx, lp_workgroup(), username, password, logon_type);
- result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
-
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -292,12 +283,11 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
/* Change the trust account password */
-static NTSTATUS cmd_netlogon_change_trust_pw(struct cli_state *cli,
+static NTSTATUS cmd_netlogon_change_trust_pw(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- DOM_CRED ret_creds;
/* Check arguments */
@@ -308,13 +298,9 @@ static NTSTATUS cmd_netlogon_change_trust_pw(struct cli_state *cli,
/* Perform the sam logon */
- ZERO_STRUCT(ret_creds);
-
result = trust_pw_find_change_and_store_it(cli, mem_ctx,
lp_workgroup());
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
-
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -329,13 +315,13 @@ struct cmd_set netlogon_commands[] = {
{ "NETLOGON" },
- { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, "Logon Control 2", "" },
- { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, "Get trusted DC name", "" },
- { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, "Logon Control", "" },
- { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, "Sam Synchronisation", "" },
- { "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, "Query Sam Deltas", "" },
- { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon, NULL, PI_NETLOGON, "Sam Logon", "" },
- { "change_trust_pw", RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw, NULL, PI_NETLOGON, "Change Trust Account Password", "" },
+ { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2", "" },
+ { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, NULL, "Get trusted DC name", "" },
+ { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, NULL, "Logon Control", "" },
+ { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },
+ { "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, NULL, "Query Sam Deltas", "" },
+ { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon, NULL, PI_NETLOGON, NULL, "Sam Logon", "" },
+ { "change_trust_pw", RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw, NULL, PI_NETLOGON, NULL, "Change Trust Account Password", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index acb3927105..a05c2c8a0b 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -300,14 +300,14 @@ static void display_sam_info_5(SAM_ENTRY5 *e5, SAM_STR5 *s5)
/****************************************************************************
Try samr_connect4 first, then samr_conenct if it fails
****************************************************************************/
-static NTSTATUS try_samr_connects(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS try_samr_connects(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 access_mask, POLICY_HND *connect_pol)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = cli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
+ result = rpccli_samr_connect4(cli, mem_ctx, access_mask, connect_pol);
if (!NT_STATUS_IS_OK(result)) {
- result = cli_samr_connect(cli, mem_ctx, access_mask,
+ result = rpccli_samr_connect(cli, mem_ctx, access_mask,
connect_pol);
}
return result;
@@ -316,7 +316,7 @@ static NTSTATUS try_samr_connects(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/**********************************************************************
* Query user information
*/
-static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -342,7 +342,7 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
sscanf(argv[3], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -351,14 +351,14 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
access_mask,
user_rid, &user_pol);
@@ -367,7 +367,7 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
ZERO_STRUCT(user_ctr);
- result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
info_level, &user_ctr);
if (!NT_STATUS_IS_OK(result))
@@ -385,6 +385,10 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
break;
}
+ rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
+
done:
return result;
}
@@ -435,7 +439,7 @@ static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
/***********************************************************************
* Query group information
*/
-static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_group(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -460,7 +464,7 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
if (argc > 3)
sscanf(argv[3], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -469,21 +473,21 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
access_mask,
group_rid, &group_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
+ result = rpccli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
info_level, &group_ctr);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -491,13 +495,16 @@ static NTSTATUS cmd_samr_query_group(struct cli_state *cli,
display_group_info_ctr(group_ctr);
+ rpccli_samr_close(cli, mem_ctx, &group_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Query groups a user is a member of */
-static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_usergroups(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -522,7 +529,7 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
if (argc > 2)
sscanf(argv[2], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -531,21 +538,21 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
access_mask,
user_rid, &user_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
&num_groups, &user_gids);
if (!NT_STATUS_IS_OK(result))
@@ -556,13 +563,16 @@ static NTSTATUS cmd_samr_query_usergroups(struct cli_state *cli,
user_gids[i].g_rid, user_gids[i].attr);
}
+ rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Query aliases a user is a member of */
-static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -602,7 +612,7 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
sid2[i].num_auths = sid2[i].sid.num_auths;
}
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -612,11 +622,11 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
goto done;
if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&global_sid_Builtin,
&domain_pol);
@@ -628,7 +638,7 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_useraliases(cli, mem_ctx, &domain_pol,
num_sids, sid2,
&num_aliases, &alias_rids);
@@ -639,13 +649,15 @@ static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli,
printf("\tgroup rid:[0x%x]\n", alias_rids[i]);
}
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Query members of a group */
-static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -666,7 +678,7 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
if (argc > 2)
sscanf(argv[2], "%x", &access_mask);
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -675,21 +687,21 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(cli, mem_ctx, &domain_pol,
access_mask,
group_rid, &group_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
+ result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs);
@@ -701,13 +713,16 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
group_attrs[i]);
}
+ rpccli_samr_close(cli, mem_ctx, &group_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Enumerate domain users */
-static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
+static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -743,7 +758,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -758,7 +773,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
size = 0xffff;
do {
- result = cli_samr_enum_dom_users(
+ result = rpccli_samr_enum_dom_users(
cli, mem_ctx, &domain_pol, &start_idx, acb_mask,
size, &dom_users, &dom_rids, &num_dom_users);
@@ -774,17 +789,17 @@ static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
done:
if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
return result;
}
/* Enumerate domain groups */
-static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
+static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -815,7 +830,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -830,7 +845,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
size = 0xffff;
do {
- result = cli_samr_enum_dom_groups(
+ result = rpccli_samr_enum_dom_groups(
cli, mem_ctx, &domain_pol, &start_idx, size,
&dom_groups, &num_dom_groups);
@@ -847,17 +862,17 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
done:
if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
return result;
}
/* Enumerate alias groups */
-static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
+static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -889,11 +904,11 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
/* Get domain policy handle */
if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&global_sid_Builtin, &domain_pol);
else
@@ -910,7 +925,7 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
size = 0xffff; /* Number of groups to retrieve */
do {
- result = cli_samr_enum_als_groups(
+ result = rpccli_samr_enum_als_groups(
cli, mem_ctx, &domain_pol, &start_idx, size,
&als_groups, &num_als_groups);
@@ -926,17 +941,17 @@ static NTSTATUS cmd_samr_enum_als_groups(struct cli_state *cli,
done:
if (got_domain_pol)
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
if (got_connect_pol)
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
return result;
}
/* Query alias membership */
-static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_aliasmem(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -967,11 +982,11 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
/* Open handle on domain */
if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&global_sid_Builtin, &domain_pol);
else
@@ -982,13 +997,13 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
/* Open handle on alias */
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_alias(cli, mem_ctx, &domain_pol,
access_mask,
alias_rid, &alias_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
+ result = rpccli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
&num_members, &alias_sids);
if (!NT_STATUS_IS_OK(result))
@@ -1001,13 +1016,16 @@ static NTSTATUS cmd_samr_query_aliasmem(struct cli_state *cli,
printf("\tsid:[%s]\n", sid_str);
}
+ rpccli_samr_close(cli, mem_ctx, &alias_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Query display info */
-static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_dispinfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1059,7 +1077,7 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -1101,7 +1119,7 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
get_query_dispinfo_params(
loop_count, &max_entries, &max_size);
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
&start_idx, info_level,
&num_entries, max_entries,
max_size, &ctr);
@@ -1135,13 +1153,15 @@ static NTSTATUS cmd_samr_query_dispinfo(struct cli_state *cli,
}
} while ( NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Query domain info */
-static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_dominfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1172,7 +1192,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -1181,7 +1201,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
/* Query domain info */
- result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
switch_level, &ctr);
if (!NT_STATUS_IS_OK(result))
@@ -1213,14 +1233,14 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
done:
- cli_samr_close(cli, mem_ctx, &domain_pol);
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
return result;
}
/* Create domain user */
-static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
+static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1251,7 +1271,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -1263,20 +1283,20 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
acb_info = ACB_NORMAL;
unknown = 0xe005000b; /* No idea what this is - a permission mask? */
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
acct_name, acb_info, unknown,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_close(cli, mem_ctx, &user_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_close(cli, mem_ctx, &domain_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_close(cli, mem_ctx, &connect_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
done:
@@ -1285,7 +1305,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
/* Create domain group */
-static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
+static NTSTATUS cmd_samr_create_dom_group(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1314,7 +1334,7 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask,
&domain_sid, &domain_pol);
@@ -1323,20 +1343,20 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
/* Create domain user */
- result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
grp_name, MAXIMUM_ALLOWED_ACCESS,
&group_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_close(cli, mem_ctx, &group_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &group_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_close(cli, mem_ctx, &domain_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &domain_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_close(cli, mem_ctx, &connect_pol);
+ result = rpccli_samr_close(cli, mem_ctx, &connect_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
done:
@@ -1345,7 +1365,7 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
/* Lookup sam names */
-static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
+static NTSTATUS cmd_samr_lookup_names(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1372,11 +1392,11 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
goto done;
if (StrCaseCmp(argv[1], "domain")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
else if (StrCaseCmp(argv[1], "builtin")==0)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&global_sid_Builtin, &domain_pol);
else
@@ -1393,7 +1413,7 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
for (i = 0; i < argc - 2; i++)
names[i] = argv[i + 2];
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
flags, num_names, names,
&num_rids, &rids, &name_types);
@@ -1406,13 +1426,15 @@ static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
printf("name %s: 0x%x (%d)\n", names[i], rids[i],
name_types[i]);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Lookup sam rids */
-static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
+static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1435,7 +1457,7 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
@@ -1450,7 +1472,7 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
for (i = 0; i < argc - 1; i++)
sscanf(argv[i + 1], "%i", &rids[i]);
- result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
+ result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
&num_names, &names, &name_types);
if (!NT_STATUS_IS_OK(result) &&
@@ -1462,13 +1484,15 @@ static NTSTATUS cmd_samr_lookup_rids(struct cli_state *cli,
for (i = 0; i < num_names; i++)
printf("rid 0x%x: %s (%d)\n", rids[i], names[i], name_types[i]);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
/* Delete domain user */
-static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
+static NTSTATUS cmd_samr_delete_dom_user(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1492,7 +1516,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
@@ -1505,7 +1529,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
uint32 *user_rids, num_rids, *name_types;
uint32 flags = 0x000003e8; /* Unknown */
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
flags, 1, (const char **)&argv[1],
&num_rids, &user_rids,
&name_types);
@@ -1513,7 +1537,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
access_mask,
user_rids[0], &user_pol);
@@ -1523,13 +1547,17 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
/* Delete user */
- result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
+ result = rpccli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
/* Display results */
+ rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
+
done:
return result;
}
@@ -1537,7 +1565,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
/**********************************************************************
* Query user security object
*/
-static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
+static NTSTATUS cmd_samr_query_sec_obj(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1565,7 +1593,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
sscanf(argv[1], "%i", &user_rid);
}
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
+ slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
strupper_m(server);
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
@@ -1574,7 +1602,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
goto done;
if (domain || user_rid)
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol);
@@ -1582,7 +1610,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
goto done;
if (user_rid)
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rid, &user_pol);
@@ -1601,7 +1629,7 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
/* Query SAM security object */
- result = cli_samr_query_sec_obj(cli, mem_ctx, pol, info_level, ctx,
+ result = rpccli_samr_query_sec_obj(cli, mem_ctx, pol, info_level, ctx,
&sec_desc_buf);
if (!NT_STATUS_IS_OK(result))
@@ -1609,12 +1637,15 @@ static NTSTATUS cmd_samr_query_sec_obj(struct cli_state *cli,
display_sec_desc(sec_desc_buf->sec);
+ rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
talloc_destroy(ctx);
return result;
}
-static NTSTATUS cmd_samr_get_dom_pwinfo(struct cli_state *cli,
+static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1626,7 +1657,7 @@ static NTSTATUS cmd_samr_get_dom_pwinfo(struct cli_state *cli,
return NT_STATUS_OK;
}
- result = cli_samr_get_dom_pwinfo(cli, mem_ctx, &unk_0, &unk_1) ;
+ result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &unk_0, &unk_1) ;
if (NT_STATUS_IS_OK(result)) {
printf("unk_0 = 0x%08x\n", unk_0);
@@ -1638,7 +1669,7 @@ static NTSTATUS cmd_samr_get_dom_pwinfo(struct cli_state *cli,
/* Look up domain name */
-static NTSTATUS cmd_samr_lookup_domain(struct cli_state *cli,
+static NTSTATUS cmd_samr_lookup_domain(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1660,13 +1691,13 @@ static NTSTATUS cmd_samr_lookup_domain(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
access_mask, &domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_lookup_domain(
+ result = rpccli_samr_lookup_domain(
cli, mem_ctx, &connect_pol, domain_name, &sid);
sid_to_string(sid_string,&sid);
@@ -1675,6 +1706,8 @@ static NTSTATUS cmd_samr_lookup_domain(struct cli_state *cli,
printf("SAMR_LOOKUP_DOMAIN: Domain Name: %s Domain SID: %s\n",
domain_name,sid_string);
+ rpccli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(cli, mem_ctx, &connect_pol);
done:
return result;
}
@@ -1686,26 +1719,26 @@ struct cmd_set samr_commands[] = {
{ "SAMR" },
- { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, "Query user info", "" },
- { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, "Query group info", "" },
- { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, "Query user groups", "" },
- { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, "Query user aliases", "" },
- { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, "Query group membership", "" },
- { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, "Query alias membership", "" },
- { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, "Query display info", "" },
- { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, "Query domain info", "" },
- { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, "Enumerate domain users", "" },
- { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, "Enumerate domain groups", "" },
- { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, "Enumerate alias groups", "" },
-
- { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, "Create domain user", "" },
- { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, "Create domain group", "" },
- { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, "Look up names", "" },
- { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, "Look up names", "" },
- { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, "Delete domain user", "" },
- { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, "Query SAMR security object", "" },
- { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, "Retrieve domain password info", "" },
-
- { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, "Lookup Domain Name", "" },
+ { "queryuser", RPC_RTYPE_NTSTATUS, cmd_samr_query_user, NULL, PI_SAMR, NULL, "Query user info", "" },
+ { "querygroup", RPC_RTYPE_NTSTATUS, cmd_samr_query_group, NULL, PI_SAMR, NULL, "Query group info", "" },
+ { "queryusergroups", RPC_RTYPE_NTSTATUS, cmd_samr_query_usergroups, NULL, PI_SAMR, NULL, "Query user groups", "" },
+ { "queryuseraliases", RPC_RTYPE_NTSTATUS, cmd_samr_query_useraliases, NULL, PI_SAMR, NULL, "Query user aliases", "" },
+ { "querygroupmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_groupmem, NULL, PI_SAMR, NULL, "Query group membership", "" },
+ { "queryaliasmem", RPC_RTYPE_NTSTATUS, cmd_samr_query_aliasmem, NULL, PI_SAMR, NULL, "Query alias membership", "" },
+ { "querydispinfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dispinfo, NULL, PI_SAMR, NULL, "Query display info", "" },
+ { "querydominfo", RPC_RTYPE_NTSTATUS, cmd_samr_query_dominfo, NULL, PI_SAMR, NULL, "Query domain info", "" },
+ { "enumdomusers", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_users, NULL, PI_SAMR, NULL, "Enumerate domain users", "" },
+ { "enumdomgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_dom_groups, NULL, PI_SAMR, NULL, "Enumerate domain groups", "" },
+ { "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, NULL, "Enumerate alias groups", "" },
+
+ { "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, NULL, "Create domain user", "" },
+ { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, NULL, "Create domain group", "" },
+ { "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, NULL, "Look up names", "" },
+ { "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, NULL, "Look up names", "" },
+ { "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, NULL, "Delete domain user", "" },
+ { "samquerysecobj", RPC_RTYPE_NTSTATUS, cmd_samr_query_sec_obj, NULL, PI_SAMR, NULL, "Query SAMR security object", "" },
+ { "getdompwinfo", RPC_RTYPE_NTSTATUS, cmd_samr_get_dom_pwinfo, NULL, PI_SAMR, NULL, "Retrieve domain password info", "" },
+
+ { "lookupdomain", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_domain, NULL, PI_SAMR, NULL, "Lookup Domain Name", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 1b3d3b7e0c..0ae16e8f1a 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -93,7 +93,7 @@ static const char *cmd_spoolss_get_short_archi(const char *long_archi)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
+static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -110,20 +110,20 @@ static WERROR cmd_spoolss_open_printer_ex(struct cli_state *cli,
if (!cli)
return WERR_GENERAL_FAILURE;
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
fstrcpy(printername, argv[1]);
/* Open the printer handle */
- werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", PRINTER_ALL_ACCESS,
servername, user, &hnd);
if (W_ERROR_IS_OK(werror)) {
printf("Printer %s opened successfully\n", printername);
- werror = cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ werror = rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
if (!W_ERROR_IS_OK(werror)) {
printf("Error closing printer handle! (%s)\n",
@@ -298,7 +298,7 @@ static void display_print_info_7(PRINTER_INFO_7 *i7)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
+static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -320,13 +320,13 @@ static WERROR cmd_spoolss_enum_printers(struct cli_state *cli,
if (argc == 3)
fstrcpy(name, argv[2]);
else {
- slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
+ slprintf(name, sizeof(name)-1, "\\\\%s", cli->cli->desthost);
strupper_m(name);
}
ZERO_STRUCT(ctr);
- result = cli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
+ result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
info_level, &num_printers, &ctr);
if (W_ERROR_IS_OK(result)) {
@@ -419,7 +419,7 @@ static void display_port_info_2(PORT_INFO_2 *i2)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
+static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -440,7 +440,7 @@ static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
ZERO_STRUCT(ctr);
- result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
+ result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
if (W_ERROR_IS_OK(result)) {
int i;
@@ -466,7 +466,7 @@ static WERROR cmd_spoolss_enum_ports(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
+static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -491,13 +491,13 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
fstrcpy(comment, argv[2]);
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
fstrcpy(user, cli->user_name);
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ALL_ACCESS, servername,
user, &pol);
@@ -507,7 +507,7 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
opened_hnd = True;
/* Get printer info */
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -518,13 +518,13 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
ctr.printers_2->devmode = NULL;
ctr.printers_2->secdesc = NULL;
- result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
if (W_ERROR_IS_OK(result))
printf("Success in setting comment.\n");
done:
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -532,7 +532,7 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
+static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -557,13 +557,13 @@ static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
fstrcpy(new_printername, argv[2]);
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
fstrcpy(user, cli->user_name);
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ALL_ACCESS, servername,
user, &pol);
@@ -573,7 +573,7 @@ static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
opened_hnd = True;
/* Get printer info */
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -583,13 +583,13 @@ static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
ctr.printers_2->devmode = NULL;
ctr.printers_2->secdesc = NULL;
- result = cli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
+ result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0);
if (W_ERROR_IS_OK(result))
printf("Success in setting printername.\n");
done:
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -597,7 +597,7 @@ static WERROR cmd_spoolss_setprintername(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
+static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -620,14 +620,14 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
info_level = atoi(argv[2]);
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
fstrcpy(user, cli->user_name);
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &pol);
@@ -638,7 +638,7 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
/* Get printer info */
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -668,7 +668,7 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
done:
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -729,7 +729,7 @@ static void display_reg_value(REGISTRY_VALUE value)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
+static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -751,7 +751,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
/* Open a printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
if (strncmp(argv[1], ".", sizeof(".")) == 0)
fstrcpy(printername, servername);
@@ -762,7 +762,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &pol);
@@ -773,7 +773,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
/* Get printer info */
- result = cli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
+ result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -786,7 +786,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
done:
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -794,7 +794,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
+static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -818,7 +818,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
/* Open a printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
if (strncmp(argv[1], ".", sizeof(".")) == 0)
fstrcpy(printername, servername);
@@ -829,7 +829,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &pol);
@@ -840,7 +840,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
/* Get printer info */
- result = cli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
+ result = rpccli_spoolss_getprinterdataex(cli, mem_ctx, &pol, keyname,
valuename, &value);
if (!W_ERROR_IS_OK(result))
@@ -854,7 +854,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
done:
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -972,7 +972,7 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
+static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -994,7 +994,7 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
}
/* get the arguments need to open the printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
@@ -1003,7 +1003,7 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
/* Open a printer handle */
- werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ACCESS_USE,
servername, user, &pol);
@@ -1018,7 +1018,7 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
for (i=0; archi_table[i].long_archi!=NULL; i++) {
- werror = cli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
+ werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level,
archi_table[i].long_archi, archi_table[i].version,
&ctr);
@@ -1050,7 +1050,7 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
/* Cleanup */
if (opened_hnd)
- cli_spoolss_close_printer (cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer (cli, mem_ctx, &pol);
if ( success )
werror = WERR_OK;
@@ -1061,7 +1061,7 @@ static WERROR cmd_spoolss_getdriver(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
+static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1089,7 +1089,7 @@ static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
continue;
- werror = cli_spoolss_enumprinterdrivers(
+ werror = rpccli_spoolss_enumprinterdrivers(
cli, mem_ctx, info_level,
archi_table[i].long_archi, &returned, &ctr);
@@ -1154,7 +1154,7 @@ static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
+static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1176,7 +1176,7 @@ static WERROR cmd_spoolss_getdriverdir(struct cli_state *cli,
/* Get the directory. Only use Info level 1 */
- result = cli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
+ result = rpccli_spoolss_getprinterdriverdir(cli, mem_ctx, 1, env, &ctr);
if (W_ERROR_IS_OK(result))
display_printdriverdir_1(ctr.info1);
@@ -1293,7 +1293,7 @@ static BOOL init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
+static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1344,7 +1344,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
ctr.info3 = &info3;
- result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
+ result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
if (W_ERROR_IS_OK(result)) {
rpcstr_pull(driver_name, info3.name.buffer,
@@ -1360,7 +1360,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
+static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1377,7 +1377,7 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
return WERR_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
/* Fill in the DRIVER_INFO_2 struct */
@@ -1407,7 +1407,7 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
*/
ctr.printers_2 = &info2;
- result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
+ result = rpccli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
if (W_ERROR_IS_OK(result))
printf ("Printer %s successfully installed.\n", argv[1]);
@@ -1418,7 +1418,7 @@ static WERROR cmd_spoolss_addprinterex(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
+static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1439,14 +1439,14 @@ static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
return WERR_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
slprintf(printername, sizeof(printername)-1, "%s\\%s", servername, argv[1]);
fstrcpy(user, cli->user_name);
/* Get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ALL_ACCESS,
servername, user, &pol);
@@ -1460,7 +1460,7 @@ static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
ZERO_STRUCT (info2);
ctr.printers_2 = &info2;
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
if (!W_ERROR_IS_OK(result)) {
printf ("Unable to retrieve printer information!\n");
@@ -1471,7 +1471,7 @@ static WERROR cmd_spoolss_setdriver(struct cli_state *cli,
init_unistr(&ctr.printers_2->drivername, argv[2]);
- result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
+ result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
if (!W_ERROR_IS_OK(result)) {
printf("SetPrinter call failed!\n");
@@ -1484,7 +1484,7 @@ done:
/* Cleanup */
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -1493,7 +1493,7 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_deletedriverex(struct cli_state *cli,
+static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1526,7 +1526,7 @@ static WERROR cmd_spoolss_deletedriverex(struct cli_state *cli,
continue;
/* make the call to remove the driver */
- result = cli_spoolss_deleteprinterdriverex(
+ result = rpccli_spoolss_deleteprinterdriverex(
cli, mem_ctx, archi_table[i].long_archi, argv[1], archi_table[i].version);
if ( !W_ERROR_IS_OK(result) )
@@ -1551,7 +1551,7 @@ static WERROR cmd_spoolss_deletedriverex(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
+static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1566,14 +1566,14 @@ static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
return WERR_OK;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
/* delete the driver for all architectures */
for (i=0; archi_table[i].long_archi; i++)
{
/* make the call to remove the driver */
- result = cli_spoolss_deleteprinterdriver(
+ result = rpccli_spoolss_deleteprinterdriver(
cli, mem_ctx, archi_table[i].long_archi, argv[1]);
if ( !W_ERROR_IS_OK(result) ) {
@@ -1596,7 +1596,7 @@ static WERROR cmd_spoolss_deletedriver(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
+static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1610,7 +1610,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
return WERR_OK;
}
- if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
+ if (asprintf(&servername, "\\\\%s", cli->cli->desthost) < 0)
return WERR_NOMEM;
strupper_m(servername);
@@ -1620,7 +1620,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
return WERR_NOMEM;
}
- result = cli_spoolss_getprintprocessordirectory(
+ result = rpccli_spoolss_getprintprocessordirectory(
cli, mem_ctx, servername, environment, procdir);
if (W_ERROR_IS_OK(result))
@@ -1635,7 +1635,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
POLICY_HND handle;
@@ -1653,11 +1653,11 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Get a printer handle */
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
- werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ werror = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
PRINTER_ALL_ACCESS,
servername, cli->user_name, &handle);
@@ -1680,11 +1680,11 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Add the form */
- werror = cli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
+ werror = rpccli_spoolss_addform(cli, mem_ctx, &handle, 1, &form);
done:
if (got_handle)
- cli_spoolss_close_printer(cli, mem_ctx, &handle);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
SAFE_FREE(servername);
SAFE_FREE(printername);
@@ -1695,7 +1695,7 @@ static WERROR cmd_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
POLICY_HND handle;
@@ -1713,11 +1713,11 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Get a printer handle */
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
- werror = cli_spoolss_open_printer_ex(
+ werror = rpccli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
servername, cli->user_name, &handle);
@@ -1739,11 +1739,11 @@ static WERROR cmd_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Set the form */
- werror = cli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
+ werror = rpccli_spoolss_setform(cli, mem_ctx, &handle, 1, argv[2], &form);
done:
if (got_handle)
- cli_spoolss_close_printer(cli, mem_ctx, &handle);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
SAFE_FREE(servername);
SAFE_FREE(printername);
@@ -1792,7 +1792,7 @@ static void display_form(FORM_1 *form)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
POLICY_HND handle;
@@ -1810,11 +1810,11 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Get a printer handle */
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
- werror = cli_spoolss_open_printer_ex(
+ werror = rpccli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
servername, cli->user_name, &handle);
@@ -1825,7 +1825,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Get the form */
- werror = cli_spoolss_getform(cli, mem_ctx, &handle, argv[2], 1, &form);
+ werror = rpccli_spoolss_getform(cli, mem_ctx, &handle, argv[2], 1, &form);
if (!W_ERROR_IS_OK(werror))
goto done;
@@ -1834,7 +1834,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
done:
if (got_handle)
- cli_spoolss_close_printer(cli, mem_ctx, &handle);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
SAFE_FREE(servername);
SAFE_FREE(printername);
@@ -1845,7 +1845,7 @@ static WERROR cmd_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
+static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -1863,11 +1863,11 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
/* Get a printer handle */
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
- werror = cli_spoolss_open_printer_ex(
+ werror = rpccli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
servername, cli->user_name, &handle);
@@ -1878,11 +1878,11 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
/* Delete the form */
- werror = cli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
+ werror = rpccli_spoolss_deleteform(cli, mem_ctx, &handle, argv[2]);
done:
if (got_handle)
- cli_spoolss_close_printer(cli, mem_ctx, &handle);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
SAFE_FREE(servername);
SAFE_FREE(printername);
@@ -1893,7 +1893,7 @@ static WERROR cmd_spoolss_deleteform(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
+static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -1913,11 +1913,11 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
/* Get a printer handle */
- asprintf(&servername, "\\\\%s", cli->desthost);
+ asprintf(&servername, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
asprintf(&printername, "%s\\%s", servername, argv[1]);
- werror = cli_spoolss_open_printer_ex(
+ werror = rpccli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
servername, cli->user_name, &handle);
@@ -1929,7 +1929,7 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
/* Enumerate forms */
offered = needed = 0;
- werror = cli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
+ werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
if (!W_ERROR_IS_OK(werror))
goto done;
@@ -1944,7 +1944,7 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
done:
if (got_handle)
- cli_spoolss_close_printer(cli, mem_ctx, &handle);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &handle);
SAFE_FREE(servername);
SAFE_FREE(printername);
@@ -1955,7 +1955,7 @@ static WERROR cmd_spoolss_enum_forms(struct cli_state *cli,
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
+static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -1975,7 +1975,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
return WERR_INVALID_PARAM;
}
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
slprintf(printername, sizeof(servername)-1, "%s\\%s", servername, argv[1]);
fstrcpy(user, cli->user_name);
@@ -2004,7 +2004,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
}
/* get a printer handle */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
MAXIMUM_ALLOWED_ACCESS, servername,
user, &pol);
if (!W_ERROR_IS_OK(result))
@@ -2014,7 +2014,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
ctr.printers_0 = &info;
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2082,7 +2082,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
goto done;
}
- result = cli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
+ result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
if (!W_ERROR_IS_OK(result)) {
printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
@@ -2090,7 +2090,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
}
printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
- result = cli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
+ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2101,7 +2101,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
done:
/* cleanup */
if (opened_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &pol);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
return result;
}
@@ -2151,7 +2151,7 @@ static void display_job_info_2(JOB_INFO_2 *job)
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
+static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -2173,14 +2173,14 @@ static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
/* Open printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->desthost);
+ slprintf(printername, sizeof(servername)-1, "\\\\%s\\", cli->cli->desthost);
strupper_m(printername);
pstrcat(printername, argv[1]);
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &hnd);
@@ -2192,7 +2192,7 @@ static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
/* Enumerate ports */
offered = needed = 0;
- result = cli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
+ result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
&num_jobs, &ctr);
if (!W_ERROR_IS_OK(result))
@@ -2214,7 +2214,7 @@ static WERROR cmd_spoolss_enum_jobs(struct cli_state *cli,
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
return result;
}
@@ -2222,7 +2222,7 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
+static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -2240,14 +2240,14 @@ static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
/* Open printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
strupper_m(printername);
pstrcat(printername, argv[1]);
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &hnd);
@@ -2258,12 +2258,12 @@ static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
/* Enumerate data */
- result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
+ result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
&val_needed, &data_needed,
NULL);
while (W_ERROR_IS_OK(result)) {
REGISTRY_VALUE value;
- result = cli_spoolss_enumprinterdata(
+ result = rpccli_spoolss_enumprinterdata(
cli, mem_ctx, &hnd, i++, val_needed,
data_needed, 0, 0, &value);
if (W_ERROR_IS_OK(result))
@@ -2274,7 +2274,7 @@ static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
return result;
}
@@ -2282,7 +2282,7 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
+static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -2304,14 +2304,14 @@ static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
/* Open printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
strupper_m(printername);
pstrcat(printername, argv[1]);
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &hnd);
@@ -2325,7 +2325,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
return WERR_NOMEM;
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
+ result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2338,7 +2338,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct cli_state *cli,
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
return result;
}
@@ -2346,7 +2346,7 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
+static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -2370,14 +2370,14 @@ static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
/* Open printer handle */
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
fstrcpy(user, cli->user_name);
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->desthost);
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\", cli->cli->desthost);
strupper_m(printername);
pstrcat(printername, argv[1]);
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
+ result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
"", MAXIMUM_ALLOWED_ACCESS,
servername, user, &hnd);
@@ -2388,7 +2388,7 @@ static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
/* Enumerate subkeys */
- result = cli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
+ result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2406,7 +2406,7 @@ static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
return result;
}
@@ -2414,7 +2414,7 @@ done:
/****************************************************************************
****************************************************************************/
-static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
+static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
@@ -2432,14 +2432,14 @@ static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
/* Open printer */
- slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->cli->desthost);
strupper_m(servername);
- slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->desthost,
+ slprintf(printername, sizeof(printername) - 1, "\\\\%s\\%s", cli->cli->desthost,
argv[1]);
strupper_m(printername);
- result = cli_spoolss_open_printer_ex(
+ result = rpccli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS,
servername, cli->user_name, &hnd);
@@ -2477,7 +2477,7 @@ static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
slprintf(servername, sizeof(servername) - 1, "\\\\%s", myhostname());
strupper_m(servername);
- result = cli_spoolss_rffpcnex(
+ result = rpccli_spoolss_rffpcnex(
cli, mem_ctx, &hnd, 0, 0, servername, 123, &option);
if (!W_ERROR_IS_OK(result)) {
@@ -2487,44 +2487,236 @@ static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
return result;
}
+/****************************************************************************
+****************************************************************************/
+
+static BOOL compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
+ struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
+{
+ PRINTER_INFO_CTR ctr1, ctr2;
+ WERROR werror;
+ TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
+
+ printf("Retrieving printer propertiesfor %s...", cli1->cli->desthost);
+ werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1);
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+ printf("ok\n");
+
+ printf("Retrieving printer properties for %s...", cli2->cli->desthost);
+ werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2);
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+ printf("ok\n");
+
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static BOOL compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
+ struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
+{
+ PRINTER_INFO_CTR ctr1, ctr2;
+ WERROR werror;
+ TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
+ SEC_DESC *sd1, *sd2;
+ BOOL result = True;
+
+
+ printf("Retreiving printer security for %s...", cli1->cli->desthost);
+ werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1);
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ result = False;
+ goto done;
+ }
+ printf("ok\n");
+
+ printf("Retrieving printer security for %s...", cli2->cli->desthost);
+ werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2);
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ result = False;
+ goto done;
+ }
+ printf("ok\n");
+
+
+ printf("++ ");
+
+ if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) {
+ printf("NULL PRINTER_INFO_3!\n");
+ result = False;
+ goto done;
+ }
+
+ sd1 = ctr1.printers_3->secdesc;
+ sd2 = ctr2.printers_3->secdesc;
+
+ if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
+ printf("NULL secdesc!\n");
+ result = False;
+ goto done;
+ }
+
+ if ( (ctr1.printers_3->flags != ctr1.printers_3->flags ) || !sec_desc_equal( sd1, sd2 ) ) {
+ printf("Security Descriptors *not* equal!\n");
+ result = False;
+ goto done;
+ }
+
+ printf("Security descriptors match\n");
+
+done:
+ talloc_destroy(mem_ctx);
+ return result;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
+static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ fstring printername, servername1, servername2;
+ pstring printername_path;
+ struct cli_state *cli_server1 = cli->cli;
+ struct cli_state *cli_server2 = NULL;
+ struct rpc_pipe_client *cli2 = NULL;
+ POLICY_HND hPrinter1, hPrinter2;
+ NTSTATUS nt_status;
+ WERROR werror;
+
+ if ( argc != 3 ) {
+ printf("Usage: %s <printer> <server>\n", argv[0]);
+ return WERR_OK;
+ }
+
+ fstrcpy( printername, argv[1] );
+
+ fstr_sprintf( servername1, cli->cli->desthost );
+ fstrcpy( servername2, argv[2] );
+ strupper_m( servername1 );
+ strupper_m( servername2 );
+
+
+ /* first get the connection to the remote server */
+
+ nt_status = cli_full_connection(&cli_server2, global_myname(), servername2,
+ NULL, 0,
+ "IPC$", "IPC",
+ cmdline_auth_info.username,
+ lp_workgroup(),
+ cmdline_auth_info.password,
+ cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
+ cmdline_auth_info.signing_state, NULL);
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
+ return WERR_GENERAL_FAILURE;
+
+ cli2 = cli_rpc_pipe_open_noauth(cli_server2, PI_SPOOLSS, &nt_status);
+ if (!cli2) {
+ printf("failed to open spoolss pipe on server %s (%s)\n",
+ servername2, nt_errstr(nt_status));
+ return WERR_GENERAL_FAILURE;
+ }
+
+ /* now open up both printers */
+
+ pstr_sprintf( printername_path, "\\\\%s\\%s", servername1, printername );
+ printf("Opening %s...", printername_path);
+ werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path,
+ "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1);
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ goto done;
+ }
+ printf("ok\n");
+
+ pstr_sprintf( printername_path, "\\\\%s\\%s", servername2, printername );
+ printf("Opening %s...", printername_path);
+ werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path,
+ "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 );
+ if ( !W_ERROR_IS_OK(werror) ) {
+ printf("failed (%s)\n", dos_errstr(werror));
+ goto done;
+ }
+ printf("ok\n");
+
+
+ compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
+ compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
+#if 0
+ compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
+#endif
+
+
+done:
+ /* cleanup */
+
+ printf("Closing printers...");
+ rpccli_spoolss_close_printer( cli, mem_ctx, &hPrinter1 );
+ rpccli_spoolss_close_printer( cli2, mem_ctx, &hPrinter2 );
+ printf("ok\n");
+
+ /* close the second remote connection */
+
+ cli_shutdown( cli_server2 );
+
+ return WERR_OK;
+}
+
/* List of commands exported by this module */
struct cmd_set spoolss_commands[] = {
{ "SPOOLSS" },
- { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, "Add a print driver", "" },
- { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, "Add a printer", "" },
- { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, "Delete a printer driver", "" },
- { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, PI_SPOOLSS, "Delete a printer driver with files", "" },
- { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, "Enumerate printer data", "" },
- { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, "Enumerate printer data for a key", "" },
- { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, "Enumerate printer keys", "" },
- { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, "Enumerate print jobs", "" },
- { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, "Enumerate printer ports", "" },
- { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, "Enumerate installed printer drivers", "" },
- { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, "Enumerate printers", "" },
- { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, "Get print driver data", "" },
- { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, "Get printer driver data with keyname", ""},
- { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, "Get print driver information", "" },
- { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, "Get print driver upload directory", "" },
- { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, "Get printer info", "" },
- { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, "Open printer handle", "" },
- { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, "Set printer driver", "" },
- { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, "Get print processor directory", "" },
- { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, "Add form", "" },
- { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, "Set form", "" },
- { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, "Get form", "" },
- { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, "Delete form", "" },
- { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, "Enumerate forms", "" },
- { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, "Set printer comment", "" },
- { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, "Set printername", "" },
- { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, "Set REG_SZ printer data", "" },
- { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, "Rffpcnex test", "" },
+ { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, PI_SPOOLSS, NULL, "Add a print driver", "" },
+ { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, PI_SPOOLSS, NULL, "Add a printer", "" },
+ { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, PI_SPOOLSS, NULL, "Delete a printer driver", "" },
+ { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, PI_SPOOLSS, NULL, "Delete a printer driver with files", "" },
+ { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, PI_SPOOLSS, NULL, "Enumerate printer data", "" },
+ { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, PI_SPOOLSS, NULL, "Enumerate printer data for a key", "" },
+ { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, PI_SPOOLSS, NULL, "Enumerate printer keys", "" },
+ { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, PI_SPOOLSS, NULL, "Enumerate print jobs", "" },
+ { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, PI_SPOOLSS, NULL, "Enumerate printer ports", "" },
+ { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, PI_SPOOLSS, NULL, "Enumerate installed printer drivers", "" },
+ { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, PI_SPOOLSS, NULL, "Enumerate printers", "" },
+ { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, PI_SPOOLSS, NULL, "Get print driver data", "" },
+ { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, PI_SPOOLSS, NULL, "Get printer driver data with keyname", ""},
+ { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, PI_SPOOLSS, NULL, "Get print driver information", "" },
+ { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, PI_SPOOLSS, NULL, "Get print driver upload directory", "" },
+ { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, PI_SPOOLSS, NULL, "Get printer info", "" },
+ { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, PI_SPOOLSS, NULL, "Open printer handle", "" },
+ { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, PI_SPOOLSS, NULL, "Set printer driver", "" },
+ { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, PI_SPOOLSS, NULL, "Get print processor directory", "" },
+ { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, PI_SPOOLSS, NULL, "Add form", "" },
+ { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, PI_SPOOLSS, NULL, "Set form", "" },
+ { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, PI_SPOOLSS, NULL, "Get form", "" },
+ { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, PI_SPOOLSS, NULL, "Delete form", "" },
+ { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, PI_SPOOLSS, NULL, "Enumerate forms", "" },
+ { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, PI_SPOOLSS, NULL, "Set printer comment", "" },
+ { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, PI_SPOOLSS, NULL, "Set printername", "" },
+ { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, PI_SPOOLSS, NULL, "Set REG_SZ printer data", "" },
+ { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, PI_SPOOLSS, NULL, "Rffpcnex test", "" },
+ { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, PI_SPOOLSS, NULL, "Printer comparison test", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c
index 1d173ffdff..da81a82c8d 100644
--- a/source3/rpcclient/cmd_srvsvc.c
+++ b/source3/rpcclient/cmd_srvsvc.c
@@ -179,7 +179,7 @@ static void display_srv_info_102(SRV_INFO_102 *sv102)
}
/* Server query info */
-static WERROR cmd_srvsvc_srv_query_info(struct cli_state *cli,
+static WERROR cmd_srvsvc_srv_query_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -195,7 +195,7 @@ static WERROR cmd_srvsvc_srv_query_info(struct cli_state *cli,
if (argc == 2)
info_level = atoi(argv[1]);
- result = cli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
+ result = rpccli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
&ctr);
if (!W_ERROR_IS_OK(result)) {
@@ -270,7 +270,7 @@ static void display_share_info_502(SRV_SHARE_INFO_502 *info502)
}
-static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
+static WERROR cmd_srvsvc_net_share_enum(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -290,7 +290,7 @@ static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
init_enum_hnd(&hnd, 0);
- result = cli_srvsvc_net_share_enum(
+ result = rpccli_srvsvc_net_share_enum(
cli, mem_ctx, info_level, &ctr, preferred_len, &hnd);
if (!W_ERROR_IS_OK(result) || !ctr.num_entries)
@@ -320,7 +320,7 @@ static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
return result;
}
-static WERROR cmd_srvsvc_net_share_get_info(struct cli_state *cli,
+static WERROR cmd_srvsvc_net_share_get_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -336,7 +336,7 @@ static WERROR cmd_srvsvc_net_share_get_info(struct cli_state *cli,
if (argc == 3)
info_level = atoi(argv[2]);
- result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info);
+ result = rpccli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -362,7 +362,7 @@ static WERROR cmd_srvsvc_net_share_get_info(struct cli_state *cli,
return result;
}
-static WERROR cmd_srvsvc_net_share_set_info(struct cli_state *cli,
+static WERROR cmd_srvsvc_net_share_set_info(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -376,7 +376,7 @@ static WERROR cmd_srvsvc_net_share_set_info(struct cli_state *cli,
}
/* retrieve share info */
- result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info_get);
+ result = rpccli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info_get);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -385,13 +385,13 @@ static WERROR cmd_srvsvc_net_share_set_info(struct cli_state *cli,
init_unistr2(&(info_get.share.info502.info_502_str.uni_remark), argv[2], UNI_STR_TERMINATE);
/* set share info */
- result = cli_srvsvc_net_share_set_info(cli, mem_ctx, argv[1], info_level, &info_get);
+ result = rpccli_srvsvc_net_share_set_info(cli, mem_ctx, argv[1], info_level, &info_get);
if (!W_ERROR_IS_OK(result))
goto done;
/* re-retrieve share info and display */
- result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info_get);
+ result = rpccli_srvsvc_net_share_get_info(cli, mem_ctx, argv[1], info_level, &info_get);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -401,11 +401,12 @@ static WERROR cmd_srvsvc_net_share_set_info(struct cli_state *cli,
return result;
}
-static WERROR cmd_srvsvc_net_remote_tod(struct cli_state *cli,
+static WERROR cmd_srvsvc_net_remote_tod(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
TIME_OF_DAY_INFO tod;
+ fstring srv_name_slash;
WERROR result;
if (argc > 1) {
@@ -413,8 +414,9 @@ static WERROR cmd_srvsvc_net_remote_tod(struct cli_state *cli,
return WERR_OK;
}
- result = cli_srvsvc_net_remote_tod(
- cli, mem_ctx, cli->srv_name_slash, &tod);
+ fstr_sprintf(srv_name_slash, "\\\\%s", cli->cli->desthost);
+ result = rpccli_srvsvc_net_remote_tod(
+ cli, mem_ctx, srv_name_slash, &tod);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -423,7 +425,7 @@ static WERROR cmd_srvsvc_net_remote_tod(struct cli_state *cli,
return result;
}
-static WERROR cmd_srvsvc_net_file_enum(struct cli_state *cli,
+static WERROR cmd_srvsvc_net_file_enum(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
@@ -445,7 +447,7 @@ static WERROR cmd_srvsvc_net_file_enum(struct cli_state *cli,
ZERO_STRUCT(ctr);
- result = cli_srvsvc_net_file_enum(
+ result = rpccli_srvsvc_net_file_enum(
cli, mem_ctx, info_level, NULL, &ctr, preferred_len, &hnd);
if (!W_ERROR_IS_OK(result))
@@ -461,12 +463,12 @@ struct cmd_set srvsvc_commands[] = {
{ "SRVSVC" },
- { "srvinfo", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_srv_query_info, PI_SRVSVC, "Server query info", "" },
- { "netshareenum",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_enum, PI_SRVSVC, "Enumerate shares", "" },
- { "netsharegetinfo",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_get_info, PI_SRVSVC, "Get Share Info", "" },
- { "netsharesetinfo",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_set_info, PI_SRVSVC, "Set Share Info", "" },
- { "netfileenum", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_file_enum, PI_SRVSVC, "Enumerate open files", "" },
- { "netremotetod",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_remote_tod, PI_SRVSVC, "Fetch remote time of day", "" },
+ { "srvinfo", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_srv_query_info, PI_SRVSVC, NULL, "Server query info", "" },
+ { "netshareenum",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_enum, PI_SRVSVC, NULL, "Enumerate shares", "" },
+ { "netsharegetinfo",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_get_info, PI_SRVSVC, NULL, "Get Share Info", "" },
+ { "netsharesetinfo",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_share_set_info, PI_SRVSVC, NULL, "Set Share Info", "" },
+ { "netfileenum", RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_file_enum, PI_SRVSVC, NULL, "Enumerate open files", "" },
+ { "netremotetod",RPC_RTYPE_WERROR, NULL, cmd_srvsvc_net_remote_tod, PI_SRVSVC, NULL, "Fetch remote time of day", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_test.c b/source3/rpcclient/cmd_test.c
new file mode 100644
index 0000000000..94545dc74e
--- /dev/null
+++ b/source3/rpcclient/cmd_test.c
@@ -0,0 +1,68 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+
+ Copyright (C) Volker Lendecke 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+static NTSTATUS cmd_testme(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ struct rpc_pipe_client *lsa_pipe = NULL, *samr_pipe = NULL;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND pol;
+
+ d_printf("testme\n");
+
+ lsa_pipe = cli_rpc_pipe_open_noauth(cli->cli, PI_LSARPC, &status);
+ if (lsa_pipe == NULL) goto done;
+
+ samr_pipe = cli_rpc_pipe_open_noauth(cli->cli, PI_SAMR, &status);
+ if (samr_pipe == NULL) goto done;
+
+ status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
+ SEC_RIGHTS_QUERY_VALUE, &pol);
+
+ if (!NT_STATUS_IS_OK(status))
+ goto done;
+
+ status = rpccli_lsa_close(lsa_pipe, mem_ctx, &pol);
+
+ if (!NT_STATUS_IS_OK(status))
+ goto done;
+
+ done:
+ if (lsa_pipe != NULL) cli_rpc_pipe_close(lsa_pipe);
+ if (samr_pipe != NULL) cli_rpc_pipe_close(samr_pipe);
+
+ return status;
+}
+
+/* List of commands exported by this module */
+
+struct cmd_set test_commands[] = {
+
+ { "TESTING" },
+
+ { "testme", RPC_RTYPE_NTSTATUS, cmd_testme, NULL,
+ -1, NULL, "Sample test", "testme" },
+
+ { NULL }
+};
diff --git a/source3/rpcclient/cmd_wkssvc.c b/source3/rpcclient/cmd_wkssvc.c
index 137ff3bdae..a65cd1f799 100644
--- a/source3/rpcclient/cmd_wkssvc.c
+++ b/source3/rpcclient/cmd_wkssvc.c
@@ -19,6 +19,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+THIS IS NO LONGER USED - NEEDS REMOVAL.
+
#include "includes.h"
#define DEBUG_TESTING
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 34e81cafe6..630add0e9b 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -25,6 +25,8 @@
DOM_SID domain_sid;
+static enum pipe_auth_type pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
+static enum pipe_auth_level pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
/* List to hold groups of commands.
*
@@ -128,29 +130,28 @@ static void fetch_machine_sid(struct cli_state *cli)
static BOOL got_domain_sid;
TALLOC_CTX *mem_ctx;
DOM_SID *dom_sid = NULL;
+ struct rpc_pipe_client *lsapipe = NULL;
if (got_domain_sid) return;
- if (!(mem_ctx=talloc_init("fetch_machine_sid")))
- {
+ if (!(mem_ctx=talloc_init("fetch_machine_sid"))) {
DEBUG(0,("fetch_machine_sid: talloc_init returned NULL!\n"));
goto error;
}
-
- if (!cli_nt_session_open (cli, PI_LSARPC)) {
- fprintf(stderr, "could not initialise lsa pipe\n");
+ if ((lsapipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result)) == NULL) {
+ fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) );
goto error;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result)) {
goto error;
}
- result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
+ result = rpccli_lsa_query_info_policy(lsapipe, mem_ctx, &pol, info_class,
&domain_name, &dom_sid);
if (!NT_STATUS_IS_OK(result)) {
goto error;
@@ -159,13 +160,18 @@ static void fetch_machine_sid(struct cli_state *cli)
got_domain_sid = True;
sid_copy( &domain_sid, dom_sid );
- cli_lsa_close(cli, mem_ctx, &pol);
- cli_nt_session_close(cli);
+ rpccli_lsa_close(lsapipe, mem_ctx, &pol);
+ cli_rpc_pipe_close(lsapipe);
talloc_destroy(mem_ctx);
return;
error:
+
+ if (lsapipe) {
+ cli_rpc_pipe_close(lsapipe);
+ }
+
fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
if (!NT_STATUS_IS_OK(result)) {
@@ -177,7 +183,7 @@ static void fetch_machine_sid(struct cli_state *cli)
/* List the available commands on a given pipe */
-static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
struct cmd_list *tmp;
@@ -222,7 +228,7 @@ static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Display help on commands */
-static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
struct cmd_list *tmp;
@@ -282,7 +288,7 @@ static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Change the debug level */
-static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_debuglevel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
if (argc > 2) {
@@ -299,114 +305,118 @@ static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS cmd_quit(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_quit(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
exit(0);
return NT_STATUS_OK; /* NOTREACHED */
}
-static NTSTATUS cmd_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS cmd_set_ss_level(void)
{
- if (cli->pipe_auth_flags == (AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN)) {
- return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- if (cli->pipes[cli->pipe_idx].fnum != 0)
- cli_nt_session_close(cli);
- }
+ struct cmd_list *tmp;
- return NT_STATUS_OK;
-}
+ /* Close any existing connections not at this level. */
-static NTSTATUS cmd_seal(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
-{
- if (cli->pipe_auth_flags == (AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) {
- return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
- if (cli->pipes[cli->pipe_idx].fnum != 0)
- cli_nt_session_close(cli);
- }
- return NT_STATUS_OK;
+ for (tmp = cmd_list; tmp; tmp = tmp->next) {
+ struct cmd_set *tmp_set;
+
+ for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
+ if (tmp_set->rpc_pipe == NULL) {
+ continue;
+ }
+
+ if (tmp_set->rpc_pipe->auth.auth_type != pipe_default_auth_type ||
+ tmp_set->rpc_pipe->auth.auth_level != pipe_default_auth_level) {
+ cli_rpc_pipe_close(tmp_set->rpc_pipe);
+ tmp_set->rpc_pipe = NULL;
+ }
+ }
+ }
+ return NT_STATUS_OK;
}
-static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
- if (cli->pipe_auth_flags == 0) {
+ pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
+ pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+
+ if (argc > 2) {
+ printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
return NT_STATUS_OK;
- } else {
- /* still have session, just need to use it again */
- cli->pipe_auth_flags = 0;
- if (cli->pipes[cli->pipe_idx].fnum != 0)
- cli_nt_session_close(cli);
}
- cli->pipe_auth_flags = 0;
- return NT_STATUS_OK;
-}
-
-static NTSTATUS setup_schannel(struct cli_state *cli, int pipe_auth_flags,
- int argc, const char **argv)
-{
- NTSTATUS ret;
- static uchar zeros[16];
- uchar trust_password[16];
- uint32 sec_channel_type;
if (argc == 2) {
- strhex_to_str(cli->sess_key, strlen(argv[1]), argv[1]);
- cli->pipe_auth_flags = pipe_auth_flags;
- return NT_STATUS_OK;
+ if (strequal(argv[1], "NTLMSSP")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+ } else if (strequal(argv[1], "NTLMSSP_SPNEGO")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+ } else if (strequal(argv[1], "SCHANNEL")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+ } else {
+ printf("unknown type %s\n", argv[1]);
+ return NT_STATUS_INVALID_LEVEL;
+ }
}
- /* Cleanup */
+ printf("debuglevel is %d\n", DEBUGLEVEL);
+ return cmd_set_ss_level();
+}
- if ((memcmp(cli->sess_key, zeros, sizeof(cli->sess_key)) != 0) &&
- (cli->pipe_auth_flags == pipe_auth_flags)) {
- /* already in this mode nothing to do */
- return NT_STATUS_OK;
- }
-
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password,
- NULL, &sec_channel_type)) {
- return NT_STATUS_UNSUCCESSFUL;
+static NTSTATUS cmd_seal(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
+ pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+
+ if (argc > 2) {
+ printf("Usage: %s [NTLMSSP|NTLMSSP_SPNEGO|SCHANNEL]\n", argv[0]);
+ return NT_STATUS_OK;
}
- ret = cli_nt_setup_netsec(cli, sec_channel_type, pipe_auth_flags, trust_password);
- if (NT_STATUS_IS_OK(ret)) {
- char *hex_session_key;
- hex_session_key = hex_encode(NULL, cli->pipes[cli->pipe_idx].auth_info.sess_key,
- sizeof(cli->pipes[cli->pipe_idx].auth_info.sess_key));
- printf("Got Session key: %s\n", hex_session_key);
- talloc_free(hex_session_key);
+ if (argc == 2) {
+ if (strequal(argv[1], "NTLMSSP")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+ } else if (strequal(argv[1], "NTLMSSP_SPNEGO")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+ } else if (strequal(argv[1], "SCHANNEL")) {
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+ } else {
+ printf("unknown type %s\n", argv[1]);
+ return NT_STATUS_INVALID_LEVEL;
+ }
}
- return ret;
+ return cmd_set_ss_level();
}
+static NTSTATUS cmd_none(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ pipe_default_auth_level = PIPE_AUTH_LEVEL_NONE;
+ pipe_default_auth_type = PIPE_AUTH_TYPE_NONE;
+
+ return cmd_set_ss_level();
+}
-static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_schannel(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
d_printf("Setting schannel - sign and seal\n");
- return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL,
- argc, argv);
+ pipe_default_auth_level = PIPE_AUTH_LEVEL_PRIVACY;
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+
+ return cmd_set_ss_level();
}
-static NTSTATUS cmd_schannel_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+static NTSTATUS cmd_schannel_sign(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
d_printf("Setting schannel - sign only\n");
- return setup_schannel(cli, AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN,
- argc, argv);
+ pipe_default_auth_level = PIPE_AUTH_LEVEL_INTEGRITY;
+ pipe_default_auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+
+ return cmd_set_ss_level();
}
@@ -416,23 +426,23 @@ static struct cmd_set rpcclient_commands[] = {
{ "GENERAL OPTIONS" },
- { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, "Get help on commands", "[command]" },
- { "?", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, "Get help on commands", "[command]" },
- { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL, -1, "Set debug level", "level" },
- { "list", RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, -1, "List available commands on <pipe>", "pipe" },
- { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, "Exit program", "" },
- { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, "Exit program", "" },
- { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL, -1, "Force RPC pipe connections to be signed", "" },
- { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL, -1, "Force RPC pipe connections to be sealed", "" },
- { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL, -1, "Force RPC pipe connections to be sealed with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
- { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL, -1, "Force RPC pipe connections to be signed (not sealed) with 'schannel' (NETSEC). Assumes valid machine account to this domain controller.", "" },
- { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL, -1, "Force RPC pipe connections to have no special properties", "" },
+ { "help", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, NULL, "Get help on commands", "[command]" },
+ { "?", RPC_RTYPE_NTSTATUS, cmd_help, NULL, -1, NULL, "Get help on commands", "[command]" },
+ { "debuglevel", RPC_RTYPE_NTSTATUS, cmd_debuglevel, NULL, -1, NULL, "Set debug level", "level" },
+ { "list", RPC_RTYPE_NTSTATUS, cmd_listcommands, NULL, -1, NULL, "List available commands on <pipe>", "pipe" },
+ { "exit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, NULL, "Exit program", "" },
+ { "quit", RPC_RTYPE_NTSTATUS, cmd_quit, NULL, -1, NULL, "Exit program", "" },
+ { "sign", RPC_RTYPE_NTSTATUS, cmd_sign, NULL, -1, NULL, "Force RPC pipe connections to be signed", "" },
+ { "seal", RPC_RTYPE_NTSTATUS, cmd_seal, NULL, -1, NULL, "Force RPC pipe connections to be sealed", "" },
+ { "schannel", RPC_RTYPE_NTSTATUS, cmd_schannel, NULL, -1, NULL, "Force RPC pipe connections to be sealed with 'schannel'. Assumes valid machine account to this domain controller.", "" },
+ { "schannelsign", RPC_RTYPE_NTSTATUS, cmd_schannel_sign, NULL, -1, NULL, "Force RPC pipe connections to be signed (not sealed) with 'schannel'. Assumes valid machine account to this domain controller.", "" },
+ { "none", RPC_RTYPE_NTSTATUS, cmd_none, NULL, -1, NULL, "Force RPC pipe connections to have no special properties", "" },
{ NULL }
};
static struct cmd_set separator_command[] = {
- { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL, -1, "----------------------" },
+ { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL, -1, NULL, "----------------------" },
{ NULL }
};
@@ -449,6 +459,7 @@ extern struct cmd_set reg_commands[];
extern struct cmd_set ds_commands[];
extern struct cmd_set echo_commands[];
extern struct cmd_set shutdown_commands[];
+extern struct cmd_set test_commands[];
static struct cmd_set *rpcclient_command_list[] = {
rpcclient_commands,
@@ -462,6 +473,7 @@ static struct cmd_set *rpcclient_command_list[] = {
reg_commands,
echo_commands,
shutdown_commands,
+ test_commands,
NULL
};
@@ -492,7 +504,6 @@ static NTSTATUS do_cmd(struct cli_state *cli,
{
NTSTATUS ntresult;
WERROR wresult;
- uchar trust_password[16];
TALLOC_CTX *mem_ctx;
@@ -505,57 +516,93 @@ static NTSTATUS do_cmd(struct cli_state *cli,
/* Open pipe */
- if (cmd_entry->pipe_idx != -1
- && cmd_entry->pipe_idx != cli->pipe_idx) {
- if (cli->pipes[cli->pipe_idx].fnum != 0)
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(cmd_entry->pipe_idx)));
- return NT_STATUS_UNSUCCESSFUL;
+ if (cmd_entry->pipe_idx != -1 && cmd_entry->rpc_pipe == NULL) {
+ switch (pipe_default_auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ cmd_entry->rpc_pipe = cli_rpc_pipe_open_noauth(cli,
+ cmd_entry->pipe_idx,
+ &ntresult);
+ break;
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ cmd_entry->rpc_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli,
+ cmd_entry->pipe_idx,
+ pipe_default_auth_level,
+ lp_workgroup(),
+ cmdline_auth_info.username,
+ cmdline_auth_info.password,
+ &ntresult);
+ break;
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ cmd_entry->rpc_pipe = cli_rpc_pipe_open_ntlmssp(cli,
+ cmd_entry->pipe_idx,
+ pipe_default_auth_level,
+ lp_workgroup(),
+ cmdline_auth_info.username,
+ cmdline_auth_info.password,
+ &ntresult);
+ break;
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ cmd_entry->rpc_pipe = cli_rpc_pipe_open_schannel(cli,
+ cmd_entry->pipe_idx,
+ pipe_default_auth_level,
+ lp_workgroup(),
+ &ntresult);
+ break;
+ default:
+ DEBUG(0, ("Could not initialise %s. Invalid auth type %u\n",
+ cli_get_pipe_name(cmd_entry->pipe_idx),
+ pipe_default_auth_type ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (!cmd_entry->rpc_pipe) {
+ DEBUG(0, ("Could not initialise %s. Error was %s\n",
+ cli_get_pipe_name(cmd_entry->pipe_idx),
+ nt_errstr(ntresult) ));
+ return ntresult;
}
- }
-
- /* some of the DsXXX commands use the netlogon pipe */
- if (lp_client_schannel() && (cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
- uint32 sec_channel_type;
+ if (cmd_entry->pipe_idx == PI_NETLOGON) {
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 sec_channel_type;
+ uchar trust_password[16];
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_password,
- NULL, &sec_channel_type)) {
- return NT_STATUS_UNSUCCESSFUL;
- }
+ if (!secrets_fetch_trust_account_password(lp_workgroup(),
+ trust_password,
+ NULL, &sec_channel_type)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- ntresult = cli_nt_setup_creds(cli, sec_channel_type,
- trust_password,
- &neg_flags, 2);
- if (!NT_STATUS_IS_OK(ntresult)) {
- ZERO_STRUCT(cli->pipes[cli->pipe_idx].auth_info.sess_key);
- printf("nt_setup_creds failed with %s\n", nt_errstr(ntresult));
- return ntresult;
+ ntresult = rpccli_netlogon_setup_creds(cmd_entry->rpc_pipe,
+ cli->desthost,
+ lp_workgroup(),
+ global_myname(),
+ trust_password,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(ntresult)) {
+ DEBUG(0, ("Could not initialise credentials for %s.\n",
+ cli_get_pipe_name(cmd_entry->pipe_idx)));
+ return ntresult;
+ }
}
-
}
- /* Run command */
+ /* Run command */
- if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
- ntresult = cmd_entry->ntfn(cli, mem_ctx, argc, (const char **) argv);
- if (!NT_STATUS_IS_OK(ntresult)) {
- printf("result was %s\n", nt_errstr(ntresult));
- }
- } else {
- wresult = cmd_entry->wfn( cli, mem_ctx, argc, (const char **) argv);
- /* print out the DOS error */
- if (!W_ERROR_IS_OK(wresult)) {
- printf( "result was %s\n", dos_errstr(wresult));
- }
- ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
- }
-
+ if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
+ ntresult = cmd_entry->ntfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
+ if (!NT_STATUS_IS_OK(ntresult)) {
+ printf("result was %s\n", nt_errstr(ntresult));
+ }
+ } else {
+ wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv);
+ /* print out the DOS error */
+ if (!W_ERROR_IS_OK(wresult)) {
+ printf( "result was %s\n", dos_errstr(wresult));
+ }
+ ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
+ }
/* Cleanup */
@@ -736,7 +783,9 @@ out_free:
return 1;
}
+#if 0 /* COMMENT OUT FOR TESTING */
memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
+#endif
/* Load command lists */
diff --git a/source3/rpcclient/rpcclient.h b/source3/rpcclient/rpcclient.h
index e1e61dc43d..3c86c0be62 100644
--- a/source3/rpcclient/rpcclient.h
+++ b/source3/rpcclient/rpcclient.h
@@ -30,11 +30,12 @@ typedef enum {
struct cmd_set {
const char *name;
- RPC_RETURN_TYPE returntype;
- NTSTATUS (*ntfn)(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc,
- const char **argv);
- WERROR (*wfn)(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv);
- int pipe_idx;
+ RPC_RETURN_TYPE returntype;
+ NTSTATUS (*ntfn)(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc,
+ const char **argv);
+ WERROR (*wfn)(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv);
+ int pipe_idx;
+ struct rpc_pipe_client *rpc_pipe;
const char *description;
const char *usage;
};
diff --git a/source3/sam/idmap_rid.c b/source3/sam/idmap_rid.c
index 0ba9794696..4a1ae141b1 100644
--- a/source3/sam/idmap_rid.c
+++ b/source3/sam/idmap_rid.c
@@ -142,6 +142,7 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
struct cli_state *cli;
+ struct rpc_pipe_client *pipe_hnd;
TALLOC_CTX *mem_ctx;
POLICY_HND pol;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -233,18 +234,22 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
}
/* query the lsa-pipe */
- if (!cli_nt_session_open (cli, PI_LSARPC)) {
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &status);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("rid_idmap_get_domains: could not setup connection to dc\n"));
goto out;
}
/* query policies */
- status = cli_lsa_open_policy(cli, mem_ctx, False, des_access, &pol);
+ status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False, des_access,
+ &pol);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- status = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, &domain_name, &domain_sid);
+ status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &pol,
+ info_class, &domain_name,
+ &domain_sid);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("rid_idmap_get_domains: cannot retrieve domain-info\n"));
goto out;
@@ -255,10 +260,10 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
/* scan trusted domains */
DEBUG(10, ("rid_idmap_get_domains: enumerating trusted domains\n"));
- status = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
- &trusted_num_domains,
- &trusted_domain_names,
- &trusted_domain_sids);
+ status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &pol, &enum_ctx,
+ &trusted_num_domains,
+ &trusted_domain_names,
+ &trusted_domain_sids);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES) &&
@@ -315,8 +320,8 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
status = NT_STATUS_OK;
out:
- cli_lsa_close(cli, mem_ctx, &pol);
- cli_nt_session_close(cli);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
+ cli_rpc_pipe_close(pipe_hnd);
talloc_destroy(mem_ctx);
cli_shutdown(cli);
diff --git a/source3/sam/idmap_smbldap.c b/source3/sam/idmap_smbldap.c
new file mode 100644
index 0000000000..b1aae2b86f
--- /dev/null
+++ b/source3/sam/idmap_smbldap.c
@@ -0,0 +1,453 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ idmap LDAP backend
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Gerald Carter 2003
+
+ 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_IDMAP
+
+struct ldap_connection *ldap_conn = NULL;
+
+/* number tries while allocating new id */
+#define LDAP_MAX_ALLOC_ID 128
+
+
+/***********************************************************************
+ This function cannot be called to modify a mapping, only set a new one
+***********************************************************************/
+
+static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ pstring id_str;
+ const char *type;
+ fstring sid_string;
+ struct ldap_message *msg;
+ struct ldap_message *mod_res = NULL;
+ char *mod;
+
+ type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
+
+ sid_to_string( sid_string, sid );
+
+ pstr_sprintf(id_str, "%lu",
+ ((id_type & ID_USERID) ?
+ (unsigned long)id.uid : (unsigned long)id.gid));
+
+ asprintf(&mod,
+ "dn: sambaSID=%s,%s\n"
+ "changetype: add\n"
+ "objectClass: sambaIdmapEntry\n"
+ "objectClass: sambaSidEntry\n"
+ "sambaSID: %s\n"
+ "%s: %lu\n",
+ sid_string, lp_ldap_idmap_suffix(), sid_string, type,
+ ((id_type & ID_USERID) ?
+ (unsigned long)id.uid : (unsigned long)id.gid));
+
+ msg = ldap_ldif2msg(mod);
+
+ SAFE_FREE(mod);
+
+ if (msg == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ mod_res = ldap_transaction(ldap_conn, msg);
+
+ if ((mod_res == NULL) || (mod_res->r.ModifyResponse.resultcode != 0))
+ goto out;
+
+ ret = NT_STATUS_OK;
+ out:
+ destroy_ldap_message(msg);
+ destroy_ldap_message(mod_res);
+ return ret;
+}
+
+/*****************************************************************************
+ Allocate a new RID
+*****************************************************************************/
+
+static NTSTATUS ldap_allocate_rid(uint32 *rid, int rid_type)
+{
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+/*****************************************************************************
+ Allocate a new uid or gid
+*****************************************************************************/
+
+static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ uid_t luid, huid;
+ gid_t lgid, hgid;
+ const char *attrs[] = { "uidNumber", "gidNumber" };
+ struct ldap_message *idpool_s = NULL;
+ struct ldap_message *idpool = NULL;
+ struct ldap_message *mod_msg = NULL;
+ struct ldap_message *mod_res = NULL;
+ int value;
+ const char *id_attrib;
+ char *mod;
+
+ id_attrib = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
+
+ idpool_s = new_ldap_search_message(lp_ldap_suffix(),
+ LDAP_SEARCH_SCOPE_SUB,
+ "(objectclass=sambaUnixIdPool)",
+ 2, attrs);
+
+ if (idpool_s == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ idpool = ldap_searchone(ldap_conn, idpool_s, NULL);
+
+ if (idpool == NULL)
+ goto out;
+
+ if (!ldap_find_single_int(idpool, id_attrib, &value))
+ goto out;
+
+ /* this must succeed or else we wouldn't have initialized */
+
+ lp_idmap_uid( &luid, &huid);
+ lp_idmap_gid( &lgid, &hgid);
+
+ /* make sure we still have room to grow */
+
+ if (id_type & ID_USERID) {
+ id->uid = value;
+ if (id->uid > huid ) {
+ DEBUG(0,("ldap_allocate_id: Cannot allocate uid "
+ "above %lu!\n", (unsigned long)huid));
+ goto out;
+ }
+ }
+ else {
+ id->gid = value;
+ if (id->gid > hgid ) {
+ DEBUG(0,("ldap_allocate_id: Cannot allocate gid "
+ "above %lu!\n", (unsigned long)hgid));
+ goto out;
+ }
+ }
+
+ asprintf(&mod,
+ "dn: %s\n"
+ "changetype: modify\n"
+ "delete: %s\n"
+ "%s: %d\n"
+ "-\n"
+ "add: %s\n"
+ "%s: %d\n",
+ idpool->r.SearchResultEntry.dn, id_attrib, id_attrib, value,
+ id_attrib, id_attrib, value+1);
+
+ mod_msg = ldap_ldif2msg(mod);
+
+ SAFE_FREE(mod);
+
+ if (mod_msg == NULL)
+ goto out;
+
+ mod_res = ldap_transaction(ldap_conn, mod_msg);
+
+ if ((mod_res == NULL) || (mod_res->r.ModifyResponse.resultcode != 0))
+ goto out;
+
+ ret = NT_STATUS_OK;
+out:
+ destroy_ldap_message(idpool_s);
+ destroy_ldap_message(idpool);
+ destroy_ldap_message(mod_msg);
+ destroy_ldap_message(mod_res);
+
+ return ret;
+}
+
+/*****************************************************************************
+ get a sid from an id
+*****************************************************************************/
+
+static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
+{
+ pstring filter;
+ const char *type;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ const char *attr_list[] = { "sambaSID" };
+ struct ldap_message *msg;
+ struct ldap_message *entry = NULL;
+ char *sid_str;
+
+ type = (id_type & ID_USERID) ? "uidNumber" : "gidNumber";
+
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))", "sambaIdmapEntry",
+ type,
+ ((id_type & ID_USERID) ?
+ (unsigned long)id.uid : (unsigned long)id.gid));
+
+ msg = new_ldap_search_message(lp_ldap_idmap_suffix(),
+ LDAP_SEARCH_SCOPE_SUB,
+ filter, 1, attr_list);
+
+ if (msg == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ entry = ldap_searchone(ldap_conn, msg, NULL);
+
+ if (entry == NULL)
+ goto out;
+
+ if (!ldap_find_single_string(entry, "sambaSID", entry->mem_ctx,
+ &sid_str))
+ goto out;
+
+ if (!string_to_sid(sid, sid_str))
+ goto out;
+
+ ret = NT_STATUS_OK;
+out:
+ destroy_ldap_message(msg);
+ destroy_ldap_message(entry);
+
+ return ret;
+}
+
+/***********************************************************************
+ Get an id from a sid
+***********************************************************************/
+
+static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type,
+ const DOM_SID *sid)
+{
+ pstring filter;
+ const char *type;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ struct ldap_message *msg;
+ struct ldap_message *entry = NULL;
+ int i;
+
+ DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_string_static(sid),
+ (*id_type & ID_GROUPID ? "group" : "user") ));
+
+ type = ((*id_type) & ID_USERID) ? "uidNumber" : "gidNumber";
+
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
+ "sambaIdmapEntry", "sambaSID", sid_string_static(sid));
+
+ msg = new_ldap_search_message(lp_ldap_idmap_suffix(),
+ LDAP_SEARCH_SCOPE_SUB,
+ filter, 1, &type);
+
+ if (msg == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ entry = ldap_searchone(ldap_conn, msg, NULL);
+
+ if (entry != NULL) {
+ int value;
+
+ if (!ldap_find_single_int(entry, type, &value))
+ goto out;
+
+ if ((*id_type) & ID_USERID)
+ id->uid = value;
+ else
+ id->gid = value;
+
+ ret = NT_STATUS_OK;
+ goto out;
+ }
+
+ if ((*id_type) & ID_QUERY_ONLY)
+ goto out;
+
+ /* Allocate a new RID */
+
+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
+ ret = ldap_allocate_id(id, *id_type);
+ if ( NT_STATUS_IS_OK(ret) )
+ break;
+ }
+
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("Could not allocate id\n"));
+ goto out;
+ }
+
+ DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
+ (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
+
+ ret = ldap_set_mapping(sid, *id, *id_type);
+
+out:
+ destroy_ldap_message(msg);
+ destroy_ldap_message(entry);
+
+ return ret;
+}
+
+/**********************************************************************
+ Verify the sambaUnixIdPool entry in the directory.
+**********************************************************************/
+static NTSTATUS verify_idpool(void)
+{
+ const char *attr_list[3] = { "uidnumber", "gidnumber", "objectclass" };
+ BOOL result;
+ char *mod;
+ struct ldap_message *msg, *entry, *res;
+
+ uid_t luid, huid;
+ gid_t lgid, hgid;
+
+ msg = new_ldap_search_message(lp_ldap_suffix(),
+ LDAP_SEARCH_SCOPE_SUB,
+ "(objectClass=sambaUnixIdPool)",
+ 3, attr_list);
+
+ if (msg == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ entry = ldap_searchone(ldap_conn, msg, NULL);
+
+ result = (entry != NULL);
+
+ destroy_ldap_message(msg);
+ destroy_ldap_message(entry);
+
+ if (result)
+ return NT_STATUS_OK;
+
+ if ( !lp_idmap_uid(&luid, &huid) || !lp_idmap_gid( &lgid, &hgid ) ) {
+ DEBUG(3,("ldap_idmap_init: idmap uid/gid parameters not "
+ "specified\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ asprintf(&mod,
+ "dn: %s\n"
+ "changetype: modify\n"
+ "add: objectClass\n"
+ "objectClass: sambaUnixIdPool\n"
+ "-\n"
+ "add: uidNumber\n"
+ "uidNumber: %lu\n"
+ "-\n"
+ "add: gidNumber\n"
+ "gidNumber: %lu\n",
+ lp_ldap_idmap_suffix(),
+ (unsigned long)luid, (unsigned long)lgid);
+
+ msg = ldap_ldif2msg(mod);
+
+ SAFE_FREE(mod);
+
+ if (msg == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ res = ldap_transaction(ldap_conn, msg);
+
+ if ((res == NULL) || (res->r.ModifyResponse.resultcode != 0)) {
+ destroy_ldap_message(msg);
+ destroy_ldap_message(res);
+ DEBUG(5, ("Could not add sambaUnixIdPool\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ destroy_ldap_message(msg);
+ destroy_ldap_message(res);
+ return NT_STATUS_OK;
+}
+
+/*****************************************************************************
+ Initialise idmap database.
+*****************************************************************************/
+
+static NTSTATUS ldap_idmap_init( char *params )
+{
+ NTSTATUS nt_status;
+ char *dn, *pw;
+
+ ldap_conn = new_ldap_connection();
+
+ if (!fetch_ldap_pw(&dn, &pw))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ ldap_conn->auth_dn = talloc_strdup(ldap_conn->mem_ctx, dn);
+ ldap_conn->simple_pw = talloc_strdup(ldap_conn->mem_ctx, pw);
+
+ SAFE_FREE(dn);
+ SAFE_FREE(pw);
+
+ if (!ldap_setup_connection(ldap_conn, params, NULL, NULL))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ /* see if the idmap suffix and sub entries exists */
+
+ nt_status = verify_idpool();
+ if ( !NT_STATUS_IS_OK(nt_status) )
+ return nt_status;
+
+ return NT_STATUS_OK;
+}
+
+/*****************************************************************************
+ End the LDAP session
+*****************************************************************************/
+
+static NTSTATUS ldap_idmap_close(void)
+{
+
+ DEBUG(5,("The connection to the LDAP server was closed\n"));
+ /* maybe free the results here --metze */
+
+ return NT_STATUS_OK;
+}
+
+
+/* This function doesn't make as much sense in an LDAP world since the calling
+ node doesn't really control the ID ranges */
+static void ldap_idmap_status(void)
+{
+ DEBUG(0, ("LDAP IDMAP Status not available\n"));
+}
+
+static struct idmap_methods ldap_methods = {
+ ldap_idmap_init,
+ ldap_allocate_rid,
+ ldap_allocate_id,
+ ldap_get_sid_from_id,
+ ldap_get_id_from_sid,
+ ldap_set_mapping,
+ ldap_idmap_close,
+ ldap_idmap_status
+
+};
+
+NTSTATUS idmap_smbldap_init(void)
+{
+ return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "smbldap", &ldap_methods);
+}
diff --git a/source3/script/installman.sh b/source3/script/installman.sh
index 9cd9100839..5564ac0231 100755
--- a/source3/script/installman.sh
+++ b/source3/script/installman.sh
@@ -13,7 +13,7 @@ if [ $# -ge 4 ] ; then
GROFF=$4 # sh cmd line, including options
fi
-if test ! -d ../docs/manpages; then
+if test ! -d docs/manpages; then
echo "No manpages present. SVN development version maybe?"
exit 0
fi
diff --git a/source3/script/installswat.sh b/source3/script/installswat.sh
index 2b99b9c57f..cba3a294f8 100755
--- a/source3/script/installswat.sh
+++ b/source3/script/installswat.sh
@@ -3,7 +3,7 @@
SWATDIR=`echo $1 | sed 's/\/\//\//g'`
SRCDIR=$2/
-BOOKDIR=$SWATDIR/help/using_samba
+BOOKDIR=$SWATDIR/using_samba
echo Installing SWAT in $SWATDIR
echo Installing the Samba Web Administration Tool
@@ -14,7 +14,7 @@ echo Installing langs are `cd $SRCDIR../swat/lang/; /bin/echo ??`
for ln in $LANGS; do
SWATLANGDIR=$SWATDIR/$ln
for d in $SWATLANGDIR $SWATLANGDIR/help $SWATLANGDIR/images \
- $SWATLANGDIR/include; do
+ $SWATLANGDIR/include $SWATLANGDIR/js; do
if [ ! -d $d ]; then
mkdir -p $d
if [ ! -d $d ]; then
@@ -28,7 +28,7 @@ done
# Install images
for ln in $LANGS; do
- for f in $SRCDIR../swat/$ln/images/*.gif; do
+ for f in $SRCDIR../swat/$ln/images/*.png; do
if [ ! -f $f ] ; then
continue
fi
@@ -59,7 +59,7 @@ for ln in $LANGS; do
# Install "server-side" includes
- for f in $SRCDIR../swat/$ln/include/*.html; do
+ for f in $SRCDIR../swat/$ln/include/*; do
if [ ! -f $f ] ; then
continue
fi
@@ -69,13 +69,25 @@ for ln in $LANGS; do
chmod 0644 $FNAME
done
+ # Install javascripts
+
+ for f in $SRCDIR../swat/$ln/js/*.js; do
+ if [ ! -f $f ] ; then
+ continue
+ fi
+ FNAME=$SWATDIR/$ln/js/`basename $f`
+ echo $FNAME
+ cp $f $FNAME || echo Cannot install $FNAME. Does $USER have privileges?
+ chmod 0644 $FNAME
+ done
+
done
# Install html documentation (if html documentation tree is here)
if [ -d $SRCDIR../docs/htmldocs/ ]; then
- for dir in htmldocs/manpages htmldocs/Samba3-ByExample htmldocs/Samba3-Developers-Guide htmldocs/Samba3-HOWTO
+ for dir in htmldocs/ htmldocs/Samba-HOWTO-Collection htmldocs/Samba-Guide htmldocs/Samba-Developers-Guide
do
if [ ! -d $SRCDIR../docs/$dir ]; then
diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk
index 3940c34700..73a1c2b3f0 100644
--- a/source3/script/mkproto.awk
+++ b/source3/script/mkproto.awk
@@ -128,7 +128,7 @@ END {
gotstart = 1;
}
- if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^DEVICEMODE|^PAC_DATA|^NET_USER_INFO_3|^smb_event_id_t/ ) {
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^REGVAL_CTR|^DEVICEMODE|^PAC_DATA|^NET_USER_INFO_3|^smb_event_id_t/ ) {
gotstart = 1;
}
diff --git a/source3/script/tests/functions b/source3/script/tests/functions
index 0981d9e29e..40e185e153 100644
--- a/source3/script/tests/functions
+++ b/source3/script/tests/functions
@@ -2,16 +2,13 @@
## library file for test functions
##
-
-SMBCONTROL="smbcontrol -t 3"
-
##
## start/stop smbd daemon
##
check_smbd_running()
{
## the smbcontrol ping will return a 0 on success
- $SMBCONTROL $CONFIGURATION smbd ping 2>&1 > /dev/null
+ smbcontrol $CONFIGURATION smbd ping 2>&1 > /dev/null
}
start_smbd()
@@ -22,7 +19,7 @@ start_smbd()
sleep 1
- $SMBCONTROL $CONFIGURATION `cat $PIDDIR/smbd.pid` ping 2>&1 > /dev/null || return $?
+ smbcontrol $CONFIGURATION `cat $PIDDIR/smbd.pid` ping 2>&1 > /dev/null || return $?
}
stop_smbd()
@@ -33,7 +30,7 @@ stop_smbd()
## belt and braces; first kill and then send a shutdown message
kill -TERM $smbd_pid
- $SMBCONTROL $CONFIGURATION smbd shutdown
+ smbcontrol $CONFIGURATION smbd shutdown
## check to see if smbd is already running
check_smbd_running
@@ -43,23 +40,14 @@ stop_smbd()
fi
}
-check_ret_value()
-{
- ret=$@
-
- if test $ret != 0; then
- stop_smbd
- exit $ret
- fi
-}
##
-## start/stop nmbd daemon
+## start/stop smbd daemon
##
check_nmbd_running()
{
## the smbcontrol ping will return a 0 on success
- $SMBCONTROL $CONFIGURATION nmbd ping 2>&1 > /dev/null
+ smbcontrol $CONFIGURATION nmbd ping 2>&1 > /dev/null
}
start_nmbd()
diff --git a/source3/script/tests/t_001.sh b/source3/script/tests/t_001.sh
index 7db2abe226..6d54d0e489 100644
--- a/source3/script/tests/t_001.sh
+++ b/source3/script/tests/t_001.sh
@@ -22,27 +22,9 @@ chmod 1777 $PREFIX_ABS/tmp
start_smbd || exit $?
-## share enumeration
-
smbclient $CONFIGURATION -L localhost -N -p 139
-check_ret_value $?
-
-testfile=`echo $CONFIGURATION | awk '{print $2}'`
-filename=`basename $testfile`
-dirname=`dirname $testfile`
-
-
-# file get/put
-
-smbclient //localhost/test $PASSWORD $CONFIGURATION -c "lcd $dirname; put $filename"
-check_ret_value $?
-
-smbclient //localhost/test $PASSWORD $CONFIGURATION -c "get $filename; rm $filename"
-check_ret_value $?
-
-diff $filename $testfile 2> /dev/null > /dev/null
-check_ret_value $?
+ret=$?
stop_smbd
-exit 0
+exit $ret
diff --git a/source3/services/services_db.c b/source3/services/services_db.c
index 29c5a9f6e6..b59cd5330e 100644
--- a/source3/services/services_db.c
+++ b/source3/services/services_db.c
@@ -1,8 +1,10 @@
/*
* Unix SMB/CIFS implementation.
* Service Control API Implementation
- * Copyright (C) Gerald Carter 2005.
+ *
* Copyright (C) Marcin Krzysztof Porwit 2005.
+ * Largely Rewritten by:
+ * Copyright (C) Gerald (Jerry) Carter 2005.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,544 +23,431 @@
#include "includes.h"
-#if 0
-
-/* backend database routines for services.tdb */
-
-#define SERVICEDB_VERSION_V1 1 /* Will there be more? */
-#define INTERNAL_SERVICES_LIST "NETLOGON Spooler"
-
-/* */
-/* scripts will execute from the following libdir, if they are in the enable svcctl=<list of scripts> */
-/* these should likely be symbolic links. Note that information about them will be extracted from the files themselves */
-/* using the LSB standard keynames for various information */
-
-#define SCVCTL_DATABASE_VERSION_V1 1
-static TDB_CONTEXT *service_tdb; /* used for services tdb file */
-
-/* there are two types of services -- internal, and external.
- Internal services are "built-in" to samba -- there may be
- functions that exist to provide the control and enumeration
- functions. There certainly is information returned to be
- displayed in the typical management console.
-
- External services are those that can be specified in the smb.conf
- file -- and they conform to the LSB specification as to having
- particular keywords in the scripts. Note that these "scripts" are
- located in the lib directory, and are likely links to LSB-compliant
- init.d scripts, such as those that might come with Suse. Note
- that the spec is located http://www.linuxbase.org/spec/ */
-
-
-
-/* Expand this to include what can and can't be done
- with a particular internal service. Expand as necessary
- to add other infromation like what can be controlled,
- etc. */
+/********************************************************************
+********************************************************************/
-typedef struct Internal_service_struct
+static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
{
- const char *filename; /* internal name "index" */
- const char *displayname;
- const char *description;
- const uint32 statustype;
- void *status_fn;
- void *control_fn;
-} Internal_service_description;
-
+ SEC_ACE ace[4];
+ SEC_ACCESS mask;
+ size_t i = 0;
+ SEC_DESC *sd;
+ SEC_ACL *acl;
+ size_t sd_size;
+
+ /* basic access for Everyone */
+
+ init_sec_access(&mask, SERVICE_READ_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ init_sec_access(&mask,SERVICE_EXECUTE_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ init_sec_access(&mask,SERVICE_ALL_ACCESS );
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* create the security descriptor */
+
+ if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ return NULL;
-static const Internal_service_description ISD[] = {
- { "NETLOGON", "Net Logon", "Provides logon and authentication service to the network", 0x110, NULL, NULL},
- { "Spooler", "Spooler", "Printing Services", 0x0020, NULL, NULL},
- { NULL, NULL, NULL, 0, NULL, NULL}
-};
+ if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
+ return NULL;
+ return sd;
+}
/********************************************************************
- allocate an array of external services and return them. Null return
- is okay, make sure &added is also zero!
+ This is where we do the dirty work of filling in things like the
+ Display name, Description, etc...
********************************************************************/
-int num_external_services(void)
+static void fill_service_values( const char *name, REGVAL_CTR *values )
{
- int num_services;
- char **svc_list;
- pstring keystring, external_services_string;
- TDB_DATA key_data;
-
-
- if (!service_tdb) {
- DEBUG(8,("enum_external_services: service database is not open!!!\n"));
- num_services = 0;
- } else {
- pstrcpy(keystring,"EXTERNAL_SERVICES");
- key_data = tdb_fetch_bystring(service_tdb, keystring);
-
- if ((key_data.dptr != NULL) && (key_data.dsize != 0)) {
- strncpy(external_services_string,key_data.dptr,key_data.dsize);
- external_services_string[key_data.dsize] = 0;
- DEBUG(8,("enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize));
- }
- }
- svc_list = str_list_make(external_services_string,NULL);
-
- num_services = str_list_count( (const char **)svc_list);
+ UNISTR2 data, dname, ipath, description;
+ uint32 dword;
+ pstring pstr;
+
+ /* These values are hardcoded in all QueryServiceConfig() replies.
+ I'm just storing them here for cosmetic purposes */
+
+ dword = SVCCTL_AUTO_START;
+ regval_ctr_addvalue( values, "Start", REG_DWORD, (char*)&dword, sizeof(uint32));
+
+ dword = SVCCTL_WIN32_OWN_PROC;
+ regval_ctr_addvalue( values, "Type", REG_DWORD, (char*)&dword, sizeof(uint32));
- return num_services;
+ dword = SVCCTL_SVC_ERROR_NORMAL;
+ regval_ctr_addvalue( values, "ErrorControl", REG_DWORD, (char*)&dword, sizeof(uint32));
+
+ /* everything runs as LocalSystem */
+
+ init_unistr2( &data, "LocalSystem", UNI_STR_TERMINATE );
+ regval_ctr_addvalue( values, "ObjectName", REG_SZ, (char*)data.buffer, data.uni_str_len*2);
+
+ /* special considerations for internal services and the DisplayName value */
+
+ if ( strequal(name, "Spooler") ) {
+ pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ init_unistr2( &description, "Internal service for spooling files to print devices", UNI_STR_TERMINATE );
+ init_unistr2( &dname, "Print Spooler", UNI_STR_TERMINATE );
+ }
+ else if ( strequal(name, "NETLOGON") ) {
+ pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ init_unistr2( &description, "File service providing access to policy and profile data", UNI_STR_TERMINATE );
+ init_unistr2( &dname, "Net Logon", UNI_STR_TERMINATE );
+ }
+ else if ( strequal(name, "RemoteRegistry") ) {
+ pstr_sprintf( pstr, "%s/%s/smbd",dyn_LIBDIR, SVCCTL_SCRIPT_DIR );
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ init_unistr2( &description, "Internal service providing remote access to the Samba registry", UNI_STR_TERMINATE );
+ init_unistr2( &dname, "Remote Registry Service", UNI_STR_TERMINATE );
+ }
+ else {
+ pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, name );
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE );
+ init_unistr2( &dname, name, UNI_STR_TERMINATE );
+ }
+ regval_ctr_addvalue( values, "DisplayName", REG_SZ, (char*)dname.buffer, dname.uni_str_len*2);
+ regval_ctr_addvalue( values, "ImagePath", REG_SZ, (char*)ipath.buffer, ipath.uni_str_len*2);
+ regval_ctr_addvalue( values, "Description", REG_SZ, (char*)description.buffer, description.uni_str_len*2);
+
+ return;
}
-
-
/********************************************************************
- Gather information on the "external services". These are services
- listed in the smb.conf file, and found to exist through checks in
- this code. Note that added will be incremented on the basis of the
- number of services added. svc_ptr should have enough memory allocated
- to accommodate all of the services that exist.
-
- Typically num_external_services is used to "size" the amount of
- memory allocated, but does little/no work.
-
- enum_external_services() actually examines each of the specified
- external services, populates the memory structures, and returns.
-
- ** note that 'added' may end up with less than the number of services
- found in _num_external_services, such as the case when a service is
- called out, but the actual service doesn't exist or the file can't be
- read for the service information.
********************************************************************/
-WERROR enum_external_services(TALLOC_CTX *tcx,ENUM_SERVICES_STATUS **svc_ptr, int existing_services,int *added)
+static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
+ const char *name )
{
- /* *svc_ptr must have pre-allocated memory */
- int num_services = 0;
- int i = 0;
- ENUM_SERVICES_STATUS *services=NULL;
- char **svc_list,**svcname;
- pstring command, keystring, external_services_string;
- int ret;
- int fd = -1;
- Service_info *si;
- TDB_DATA key_data;
-
- *added = num_services;
-
- if (!service_tdb) {
- DEBUG(8,("enum_external_services: service database is not open!!!\n"));
- } else {
- pstrcpy(keystring,"EXTERNAL_SERVICES");
- key_data = tdb_fetch_bystring(service_tdb, keystring);
- if ((key_data.dptr != NULL) && (key_data.dsize != 0)) {
- strncpy(external_services_string,key_data.dptr,key_data.dsize);
- external_services_string[key_data.dsize] = 0;
- DEBUG(8,("enum_external_services: services list is %s, size is %d\n",external_services_string,key_data.dsize));
- }
- }
- svc_list = str_list_make(external_services_string,NULL);
-
- num_services = str_list_count( (const char **)svc_list);
-
- if (0 == num_services) {
- DEBUG(8,("enum_external_services: there are no external services\n"));
- *added = num_services;
- return WERR_OK;
+ REGISTRY_KEY *key_service, *key_secdesc;
+ WERROR wresult;
+ pstring path;
+ REGVAL_CTR *values;
+ REGSUBKEY_CTR *svc_subkeys;
+ SEC_DESC *sd;
+ prs_struct ps;
+
+ /* add to the list and create the subkey path */
+
+ regsubkey_ctr_addkey( subkeys, name );
+ store_reg_keys( key_parent, subkeys );
+
+ /* open the new service key */
+
+ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ wresult = regkey_open_internal( &key_service, path, get_root_nt_token(),
+ REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return;
}
- DEBUG(8,("enum_external_services: there are [%d] external services\n",num_services));
- si=TALLOC_ARRAY( tcx, Service_info, 1 );
- if (si == NULL) {
- DEBUG(8,("enum_external_services: Failed to alloc si\n"));
- return WERR_NOMEM;
+
+ /* add the 'Security' key */
+
+ if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) {
+ DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
+ return;
}
+
+ fetch_reg_keys( key_service, svc_subkeys );
+ regsubkey_ctr_addkey( svc_subkeys, "Security" );
+ store_reg_keys( key_service, svc_subkeys );
-#if 0
-/* *svc_ptr has the pointer to the array if there is one already. NULL if not. */
- if ((existing_services>0) && svc_ptr && *svc_ptr) { /* reallocate vs. allocate */
- DEBUG(8,("enum_external_services: REALLOCing %x to %d services\n", *svc_ptr, existing_services+num_services));
+ /* now for the service values */
+
+ if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) {
+ DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
+ return;
+ }
- services=TALLOC_REALLOC_ARRAY(tcx,*svc_ptr,ENUM_SERVICES_STATUS,existing_services+num_services);
- DEBUG(8,("enum_external_services: REALLOCed to %x services\n", services));
+ fill_service_values( name, values );
+ store_reg_values( key_service, values );
- if (!services) return WERR_NOMEM;
- *svc_ptr = services;
- } else {
- if ( !(services = TALLOC_ARRAY( tcx, ENUM_SERVICES_STATUS, num_services )) )
- return WERR_NOMEM;
- }
-#endif
+ /* cleanup the service key*/
+
+ TALLOC_FREE( key_service );
+
+ /* now add the security descriptor */
- if (!svc_ptr || !(*svc_ptr))
- return WERR_NOMEM;
- services = *svc_ptr;
- if (existing_services > 0) {
- i+=existing_services;
+ pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+ wresult = regkey_open_internal( &key_secdesc, path, get_root_nt_token(),
+ REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return;
}
- svcname = svc_list;
- DEBUG(8,("enum_external_services: enumerating %d external services starting at index %d\n", num_services,existing_services));
-
- while (*svcname) {
- DEBUG(10,("enum_external_services: Reading information on service %s, index %d\n",*svcname,i));
- /* get_LSB_data(*svcname,si); */
- if (!get_service_info(service_tdb,*svcname, si)) {
- DEBUG(1,("enum_external_services: CAN'T FIND INFO FOR SERVICE %s in the services DB\n",*svcname));
- }
-
- if ((si->filename == NULL) || (*si->filename == 0)) {
- init_unistr(&services[i].servicename, *svcname );
- } else {
- init_unistr( &services[i].servicename, si->filename );
- /* init_unistr( &services[i].servicename, si->servicename ); */
- }
-
- if ((si->provides == NULL) || (*si->provides == 0)) {
- init_unistr(&services[i].displayname, *svcname );
- } else {
- init_unistr( &services[i].displayname, si->provides );
- }
-
- /* TODO - we could keep the following info in the DB, too... */
-
- DEBUG(8,("enum_external_services: Service name [%s] displayname [%s]\n",
- si->filename, si->provides));
- services[i].status.type = SVCCTL_WIN32_OWN_PROC;
- 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;
-
- /* TODO - do callout here to get the status */
-
- memset(command, 0, sizeof(command));
- slprintf(command, sizeof(command)-1, "%s%s%s %s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, *svcname, "status");
-
- DEBUG(10, ("enum_external_services: status command is [%s]\n", command));
-
- /* TODO - wrap in privilege check */
-
- ret = smbrun(command, &fd);
- DEBUGADD(10, ("returned [%d]\n", ret));
- close(fd);
- if(ret != 0)
- DEBUG(10, ("enum_external_services: Command returned [%d]\n", ret));
- services[i].status.state = SVCCTL_STOPPED;
- if (ret == 0) {
- services[i].status.state = SVCCTL_RUNNING;
- services[i].status.controls_accepted = SVCCTL_CONTROL_SHUTDOWN | SVCCTL_CONTROL_STOP;
- } else {
- services[i].status.state = SVCCTL_STOPPED;
- services[i].status.controls_accepted = 0;
- }
- svcname++;
- i++;
- }
+ if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) {
+ DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
+ return;
+ }
- DEBUG(10,("enum_external_services: Read services %d\n",num_services));
- *added = num_services;
+ if ( !(sd = construct_service_sd(key_secdesc)) ) {
+ DEBUG(0,("add_new_svc_name: Failed to create default sec_desc!\n"));
+ TALLOC_FREE( key_secdesc );
+ return;
+ }
+
+ /* stream the printer security descriptor */
+
+ prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key_secdesc, MARSHALL);
+
+ if ( sec_io_desc("sec_desc", &sd, &ps, 0 ) ) {
+ uint32 offset = prs_offset( &ps );
+ regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset );
+ store_reg_values( key_secdesc, values );
+ }
+
+ /* finally cleanup the Security key */
+
+ prs_mem_free( &ps );
+ TALLOC_FREE( key_secdesc );
- return WERR_OK;
+ return;
}
/********************************************************************
********************************************************************/
-int num_internal_services(void)
+void svcctl_init_keys( void )
{
- int num_services;
- char **svc_list;
- pstring keystring, internal_services_string;
- TDB_DATA key_data;
-
- if (!service_tdb) {
- DEBUG(8,("enum_internal_services: service database is not open!!!\n"));
- num_services = 0;
- } else {
- pstrcpy(keystring,"INTERNAL_SERVICES");
- key_data = tdb_fetch_bystring(service_tdb, keystring);
-
- if ((key_data.dptr != NULL) && (key_data.dsize != 0)) {
- strncpy(internal_services_string,key_data.dptr,key_data.dsize);
- internal_services_string[key_data.dsize] = 0;
- DEBUG(8,("enum_internal_services: services list is %s, size is %d\n",internal_services_string,key_data.dsize));
- }
- }
- svc_list = str_list_make(internal_services_string,NULL);
-
- num_services = str_list_count( (const char **)svc_list);
-
- return num_services;
-}
-
-#if 0
-/*********************************************************************
- given a service nice name, find the underlying service name
-*********************************************************************/
-
-static BOOL convert_service_displayname(TDB_CONTEXT *stdb,pstring service_nicename, pstring servicename,int szsvcname)
-{
- pstring keystring;
- TDB_DATA key_data;
-
- if ((stdb == NULL) || (service_nicename==NULL) || (servicename == NULL))
- return False;
+ const char **service_list = lp_svcctl_list();
+ int i;
+ REGSUBKEY_CTR *subkeys;
+ REGISTRY_KEY *key = NULL;
+ WERROR wresult;
+ BOOL new_services = False;
+
+ /* bad mojo here if the lookup failed. Should not happen */
+
+ wresult = regkey_open_internal( &key, KEY_SERVICES, get_root_nt_token(),
+ REG_KEY_ALL );
- pstr_sprintf(keystring,"SERVICE_NICENAME/%s", servicename);
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("init_services_keys: key lookup failed! (%s)\n",
+ dos_errstr(wresult)));
+ return;
+ }
+
+ /* lookup the available subkeys */
+
+ if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
+ DEBUG(0,("init_services_keys: talloc() failed!\n"));
+ return;
+ }
+
+ fetch_reg_keys( key, subkeys );
+
+ /* the builting services exist */
+
+ add_new_svc_name( key, subkeys, "Spooler" );
+ add_new_svc_name( key, subkeys, "NETLOGON" );
+ add_new_svc_name( key, subkeys, "RemoteRegistry" );
+
+ for ( i=0; service_list[i]; i++ ) {
+
+ /* only add new services */
+ if ( regsubkey_ctr_key_exists( subkeys, service_list[i] ) )
+ continue;
- DEBUG(5, ("convert_service_displayname: Looking for service name [%s], key [%s]\n",
- service_nicename, keystring));
+ /* Add the new service key and initialize the appropriate values */
- key_data = tdb_fetch_bystring(stdb,keystring);
+ add_new_svc_name( key, subkeys, service_list[i] );
- if (key_data.dsize == 0) {
- DEBUG(5, ("convert_service_displayname: [%s] Not found, tried key [%s]\n",service_nicename,keystring));
- return False;
+ new_services = True;
}
- strncpy(servicename,key_data.dptr,szsvcname);
- servicename[(key_data.dsize > szsvcname ? szsvcname : key_data.dsize)] = 0;
- DEBUG(5, ("convert_service_displayname: Found service name [%s], name is [%s]\n",
- service_nicename,servicename));
+ TALLOC_FREE( key );
- return True;
-}
-#endif
+ /* initialize the control hooks */
-/*******************************************************************************
- Get the INTERNAL services information for the given service name.
-*******************************************************************************/
+ init_service_op_table();
-static BOOL get_internal_service_data(const Internal_service_description *isd, Service_info *si)
-{
- ZERO_STRUCTP( si );
-#if 0
-
- pstrcpy( si->servicename, isd->displayname);
- pstrcpy( si->servicetype, "INTERNAL");
- pstrcpy( si->filename, isd->filename);
- pstrcpy( si->provides, isd->displayname);
- pstrcpy( si->description, isd->description);
- pstrcpy( si->shortdescription, isd->description);
-#endif
-
- return True;
+ return;
}
/********************************************************************
+ This is where we do the dirty work of filling in things like the
+ Display name, Description, etc...Always return a default secdesc
+ in case of any failure.
********************************************************************/
-BOOL get_service_info(TDB_CONTEXT *stdb,char *service_name, Service_info *si)
-{
-
- pstring keystring;
- TDB_DATA key_data;
-
- if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0))
- return False;
-
- /* TODO - error handling -- what if the service isn't in the DB? */
-
- pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->servicetype,key_data.dptr,key_data.dsize);
- si->servicetype[key_data.dsize] = 0;
-
- /* crude check to see if the service exists... */
- DEBUG(3,("Size of the TYPE field is %d\n",key_data.dsize));
- if (key_data.dsize == 0)
- return False;
-
- pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->filename,key_data.dptr,key_data.dsize);
- si->filename[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->provides,key_data.dptr,key_data.dsize);
- si->provides[key_data.dsize] = 0;
- strncpy(si->servicename,key_data.dptr,key_data.dsize);
- si->servicename[key_data.dsize] = 0;
-
-
- pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->dependencies,key_data.dptr,key_data.dsize);
- si->dependencies[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->shouldstart,key_data.dptr,key_data.dsize);
- si->shouldstart[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/SHOULD_STOP", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->shouldstop,key_data.dptr,key_data.dsize);
- si->shouldstop[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->requiredstart,key_data.dptr,key_data.dsize);
- si->requiredstart[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->requiredstop,key_data.dptr,key_data.dsize);
- si->requiredstop[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->description,key_data.dptr,key_data.dsize);
- si->description[key_data.dsize] = 0;
-
- pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name);
- key_data = tdb_fetch_bystring(stdb,keystring);
- strncpy(si->shortdescription,key_data.dptr,key_data.dsize);
- si->shortdescription[key_data.dsize] = 0;
-
- return True;
-}
-
-/*********************************************************************
-*********************************************************************/
-
-BOOL store_service_info(TDB_CONTEXT *stdb,char *service_name, Service_info *si)
+SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token )
{
- pstring keystring;
-
- /* Note -- when we write to the tdb, we "index" on the filename
- field, not the nice name. when a service is "opened", it is
- opened by the nice (SERVICENAME) name, not the file name.
- So there needs to be a mapping from nice name back to the file name. */
-
- if ((stdb == NULL) || (si == NULL) || (service_name==NULL) || (*service_name == 0))
- return False;
-
-
- /* Store the nicename */
-
- pstr_sprintf(keystring,"SERVICE_NICENAME/%s", si->servicename);
- tdb_store_bystring(stdb,keystring,string_tdb_data(service_name),TDB_REPLACE);
-
- pstr_sprintf(keystring,"SERVICE/%s/TYPE", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicetype),TDB_REPLACE);
-
- pstr_sprintf(keystring,"SERVICE/%s/FILENAME", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->filename),TDB_REPLACE);
-
- pstr_sprintf(keystring,"SERVICE/%s/PROVIDES", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->provides),TDB_REPLACE);
+ REGISTRY_KEY *key;
+ prs_struct ps;
+ REGVAL_CTR *values;
+ REGISTRY_VALUE *val;
+ SEC_DESC *sd = NULL;
+ SEC_DESC *ret_sd = NULL;
+ pstring path;
+ WERROR wresult;
+
+ /* now add the security descriptor */
+
+ pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+ wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return NULL;
+ }
- pstr_sprintf(keystring,"SERVICE/%s/SERVICENAME", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->servicename),TDB_REPLACE);
+ if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
+ DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
+ TALLOC_FREE( key );
+ return NULL;
+ }
- pstr_sprintf(keystring,"SERVICE/%s/DEPENDENCIES", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->dependencies),TDB_REPLACE);
+ fetch_reg_values( key, values );
+
+ if ( !(val = regval_ctr_getvalue( values, "Security" )) ) {
+ DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n",
+ name));
+ TALLOC_FREE( key );
+ return construct_service_sd( ctx );
+ }
+
- pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTART", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstart),TDB_REPLACE);
+ /* stream the printer security descriptor */
+
+ prs_init( &ps, 0, key, UNMARSHALL);
+ prs_give_memory( &ps, regval_data_p(val), regval_size(val), False );
+
+ if ( !sec_io_desc("sec_desc", &sd, &ps, 0 ) ) {
+ TALLOC_FREE( key );
+ return construct_service_sd( ctx );
+ }
+
+ ret_sd = dup_sec_desc( ctx, sd );
+
+ /* finally cleanup the Security key */
+
+ prs_mem_free( &ps );
+ TALLOC_FREE( key );
- pstr_sprintf(keystring,"SERVICE/%s/SHOULDSTOP", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->shouldstop),TDB_REPLACE);
+ return ret_sd;
+}
- pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTART", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstart),TDB_REPLACE);
+/********************************************************************
+********************************************************************/
- pstr_sprintf(keystring,"SERVICE/%s/REQUIREDSTOP", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->requiredstop),TDB_REPLACE);
+char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
+{
+ static fstring display_name;
+ REGISTRY_KEY *key;
+ REGVAL_CTR *values;
+ REGISTRY_VALUE *val;
+ pstring path;
+ WERROR wresult;
+
+ /* now add the security descriptor */
+
+ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return NULL;
+ }
- pstr_sprintf(keystring,"SERVICE/%s/DESCRIPTION", service_name);
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE);
+ if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
+ DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
+ TALLOC_FREE( key );
+ return NULL;
+ }
- pstr_sprintf(keystring,"SERVICE/%s/SHORTDESC", service_name);
- if (si->shortdescription && *si->shortdescription)
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->shortdescription),TDB_REPLACE);
+ fetch_reg_values( key, values );
+
+ if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) )
+ fstrcpy( display_name, name );
else
- tdb_store_bystring(stdb,keystring,string_tdb_data(si->description),TDB_REPLACE);
+ rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 );
- return True;
+ TALLOC_FREE( key );
+
+ return display_name;
}
-/****************************************************************************
- Create/Open the service control manager tdb. This code a clone of init_group_mapping.
-****************************************************************************/
+/********************************************************************
+********************************************************************/
-BOOL init_svcctl_db(void)
+char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
{
- const char *vstring = "INFO/version";
- uint32 vers_id;
- char **svc_list;
- char **svcname;
- pstring keystring;
- pstring external_service_list;
- pstring internal_service_list;
- Service_info si;
- const Internal_service_description *isd_ptr;
- /* svc_list = str_list_make( "etc/init.d/skeleton etc/init.d/syslog", NULL ); */
- svc_list=(char **)lp_enable_svcctl();
-
- if (service_tdb)
- return True;
-
- pstrcpy(external_service_list,"");
-
- service_tdb = tdb_open_log(lock_path("services.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
- if (!service_tdb) {
- DEBUG(0,("Failed to open service db\n"));
- service_tdb = tdb_open_log(lock_path("services.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!service_tdb) return False;
- DEBUG(0,("Created new services db\n"));
+ static fstring description;
+ REGISTRY_KEY *key;
+ REGVAL_CTR *values;
+ REGISTRY_VALUE *val;
+ pstring path;
+ WERROR wresult;
+
+ /* now add the security descriptor */
+
+ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return NULL;
}
- if ((-1 == tdb_fetch_uint32(service_tdb, vstring,&vers_id)) || (vers_id != SERVICEDB_VERSION_V1)) {
- /* wrong version of DB, or db was just created */
- tdb_traverse(service_tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_uint32(service_tdb, vstring, SERVICEDB_VERSION_V1);
+ if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
+ DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
+ TALLOC_FREE( key );
+ return NULL;
}
- tdb_unlock_bystring(service_tdb, vstring);
- DEBUG(0,("Initializing services db\n"));
+ fetch_reg_values( key, values );
+
+ if ( !(val = regval_ctr_getvalue( values, "Description" )) )
+ fstrcpy( description, "Unix Service");
+ else
+ rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 );
+
+ TALLOC_FREE( key );
- svcname = svc_list;
+ return description;
+}
- /* Get the EXTERNAL services as mentioned by line in smb.conf */
- while (*svcname) {
- DEBUG(10,("Reading information on service %s\n",*svcname));
- if (get_LSB_data(*svcname,&si));{
- /* write the information to the TDB */
- store_service_info(service_tdb,*svcname,&si);
- /* definitely not efficient to do it this way. */
- pstrcat(external_service_list,"\"");
- pstrcat(external_service_list,*svcname);
- pstrcat(external_service_list,"\" ");
- }
- svcname++;
+/********************************************************************
+********************************************************************/
+
+REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
+{
+ REGISTRY_KEY *key;
+ REGVAL_CTR *values;
+ pstring path;
+ WERROR wresult;
+
+ /* now add the security descriptor */
+
+ pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+ if ( !W_ERROR_IS_OK(wresult) ) {
+ DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n",
+ path, dos_errstr(wresult)));
+ return NULL;
}
- pstrcpy(keystring,"EXTERNAL_SERVICES");
- DEBUG(8,("Storing external service list [%s]\n",external_service_list));
- tdb_store_bystring(service_tdb,keystring,string_tdb_data(external_service_list),TDB_REPLACE);
-
- /* Get the INTERNAL services */
-
- pstrcpy(internal_service_list,"");
- isd_ptr = ISD;
-
- while (isd_ptr && (isd_ptr->filename)) {
- DEBUG(10,("Reading information on service %s\n",isd_ptr->filename));
- if (get_internal_service_data(isd_ptr,&si)){
- /* write the information to the TDB */
- store_service_info(service_tdb,(char *)isd_ptr->filename,&si);
- /* definitely not efficient to do it this way. */
- pstrcat(internal_service_list,"\"");
- pstrcat(internal_service_list,isd_ptr->filename);
- pstrcat(internal_service_list,"\" ");
-
- }
- isd_ptr++;
+
+ if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
+ DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n"));
+ TALLOC_FREE( key );
+ return NULL;
}
- pstrcpy(keystring,"INTERNAL_SERVICES");
- DEBUG(8,("Storing internal service list [%s]\n",internal_service_list));
- tdb_store_bystring(service_tdb,keystring,string_tdb_data(internal_service_list),TDB_REPLACE);
+
+ fetch_reg_values( key, values );
- return True;
+ TALLOC_FREE( key );
+
+ return values;
}
-#endif
+
diff --git a/source3/services/svc_netlogon.c b/source3/services/svc_netlogon.c
new file mode 100644
index 0000000000..2aa5a31cde
--- /dev/null
+++ b/source3/services/svc_netlogon.c
@@ -0,0 +1,66 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * 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"
+
+/* Implementation for internal netlogon service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_stop( const char *service, SERVICE_STATUS *service_status )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_start( const char *service )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR netlogon_status( const char *service, SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = 0x20;
+ if ( lp_servicenumber("NETLOGON") != -1 )
+ service_status->state = SVCCTL_RUNNING;
+ else
+ service_status->state = SVCCTL_STOPPED;
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate netlogon service */
+
+SERVICE_CONTROL_OPS netlogon_svc_ops = {
+ netlogon_stop,
+ netlogon_start,
+ netlogon_status
+};
diff --git a/source3/services/svc_rcinit.c b/source3/services/svc_rcinit.c
index c856ae2a99..5801d076c4 100644
--- a/source3/services/svc_rcinit.c
+++ b/source3/services/svc_rcinit.c
@@ -171,24 +171,78 @@ BOOL get_LSB_data(char *fname,Service_info *si )
/*********************************************************************
*********************************************************************/
-static WERROR rcinit_stop( SERVICE_STATUS *service_status )
+static WERROR rcinit_stop( const char *service, SERVICE_STATUS *status )
{
- return WERR_OK;
+ pstring command;
+ int ret, fd;
+
+ pstr_sprintf( command, "%s/%s/%s stop", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
+
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ ZERO_STRUCTP( status );
+ status->type = 0x0020;
+ status->state = (ret == 0 ) ? 0x0001 : 0x0004;
+ status->controls_accepted = 0x0005;
+
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
}
/*********************************************************************
*********************************************************************/
-static WERROR rcinit_start( void )
+static WERROR rcinit_start( const char *service )
{
- return WERR_OK;
+ pstring command;
+ int ret, fd;
+
+ pstr_sprintf( command, "%s/%s/%s start", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
+
+ /* we've already performed the access check when the service was opened */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
}
/*********************************************************************
*********************************************************************/
-static WERROR rcinit_status( SERVICE_STATUS *service_status )
+static WERROR rcinit_status( const char *service, SERVICE_STATUS *status )
{
+ pstring command;
+ int ret, fd;
+
+ pstr_sprintf( command, "%s/%s/%s status", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
+
+ /* we've already performed the access check when the service was opened */
+ /* assume as return code of 0 means that the service is ok. Anything else
+ is STOPPED */
+
+ become_root();
+ ret = smbrun( command , &fd );
+ unbecome_root();
+
+ DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
+ close(fd);
+
+ ZERO_STRUCTP( status );
+ status->type = 0x0020;
+ status->state = (ret == 0 ) ? 0x0004 : 0x0001;
+ status->controls_accepted = 0x0005;
+
return WERR_OK;
}
diff --git a/source3/services/svc_spoolss.c b/source3/services/svc_spoolss.c
index 5f8fa73ced..13a1dbb1bd 100644
--- a/source3/services/svc_spoolss.c
+++ b/source3/services/svc_spoolss.c
@@ -25,7 +25,7 @@
/*********************************************************************
*********************************************************************/
-static WERROR spoolss_stop( SERVICE_STATUS *service_status )
+static WERROR spoolss_stop( const char *service, SERVICE_STATUS *service_status )
{
ZERO_STRUCTP( service_status );
@@ -43,7 +43,7 @@ static WERROR spoolss_stop( SERVICE_STATUS *service_status )
/*********************************************************************
*********************************************************************/
-static WERROR spoolss_start( void )
+static WERROR spoolss_start( const char *service )
{
/* see if the smb.conf will support this anyways */
@@ -58,8 +58,10 @@ static WERROR spoolss_start( void )
/*********************************************************************
*********************************************************************/
-static WERROR spoolss_status( SERVICE_STATUS *service_status )
+static WERROR spoolss_status( const char *service, SERVICE_STATUS *service_status )
{
+ ZERO_STRUCTP( service_status );
+
service_status->type = 0x110;
service_status->state = lp_get_spoolss_state();
service_status->controls_accepted = SVCCTL_ACCEPT_STOP;
diff --git a/source3/services/svc_winreg.c b/source3/services/svc_winreg.c
new file mode 100644
index 0000000000..1bccee246e
--- /dev/null
+++ b/source3/services/svc_winreg.c
@@ -0,0 +1,63 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Service Control API Implementation
+ * 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"
+
+/* Implementation for internal winreg service */
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_stop( const char *service, SERVICE_STATUS *service_status )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_start( const char *service )
+{
+ return WERR_ACCESS_DENIED;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static WERROR winreg_status( const char *service, SERVICE_STATUS *service_status )
+{
+ ZERO_STRUCTP( service_status );
+
+ service_status->type = 0x20;
+ service_status->state = SVCCTL_RUNNING;
+
+ return WERR_OK;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+/* struct for svcctl control to manipulate winreg service */
+
+SERVICE_CONTROL_OPS winreg_svc_ops = {
+ winreg_stop,
+ winreg_start,
+ winreg_status
+};
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 72d021d4e6..805e45f6ea 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -80,7 +80,8 @@ static BOOL in_chained_smb(void)
return (chain_size != 0);
}
-static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len);
+static void received_unlock_msg(int msg_type, struct process_id src,
+ void *buf, size_t len);
/****************************************************************************
Function to push a blocking lock request onto the lock queue.
@@ -127,7 +128,7 @@ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
/* Add a pending lock record for this. */
status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ lock_pid, procid_self(), blr->fsp->conn->cnum,
offset, count, PENDING_LOCK, &my_lock_ctx);
if (!NT_STATUS_IS_OK(status)) {
@@ -351,8 +352,8 @@ static BOOL process_lockread(blocking_lock_record *blr)
SSVAL(p,0,nread); p += 2;
set_message_end(outbuf, p+nread);
- DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
- fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
+ DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%lu nread=%ld\n",
+ fsp->fsp_name, fsp->fnum, (unsigned long)numtoread, (long)nread ) );
send_blocking_reply(outbuf,outsize);
return True;
@@ -526,7 +527,7 @@ void remove_pending_lock_requests_by_fid(files_struct *fsp)
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->lock_pid, procid_self(), blr->fsp->conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
free_blocking_lock_record(blr);
@@ -552,7 +553,7 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->lock_pid, procid_self(), blr->fsp->conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
free_blocking_lock_record(blr);
}
@@ -563,7 +564,8 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
Set a flag as an unlock request affects one of our pending locks.
*****************************************************************************/
-static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len)
+static void received_unlock_msg(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
DEBUG(10,("received_unlock_msg\n"));
process_blocking_lock_queue(time(NULL));
@@ -641,7 +643,7 @@ void process_blocking_lock_queue(time_t t)
fsp->fnum, fsp->fsp_name ));
brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->lock_pid, procid_self(), conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
@@ -658,7 +660,7 @@ void process_blocking_lock_queue(time_t t)
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->lock_pid, procid_self(), conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
free_blocking_lock_record(blr);
@@ -673,7 +675,7 @@ void process_blocking_lock_queue(time_t t)
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->lock_pid, procid_self(), conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
free_blocking_lock_record(blr);
@@ -690,7 +692,7 @@ void process_blocking_lock_queue(time_t t)
if(blocking_lock_record_process(blr)) {
brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->lock_pid, procid_self(), conn->cnum,
blr->offset, blr->count, True, NULL, NULL);
free_blocking_lock_record(blr);
diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c
index 1178400e4d..738d12151d 100644
--- a/source3/smbd/change_trust_pw.c
+++ b/source3/smbd/change_trust_pw.c
@@ -33,7 +33,8 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct in_addr pdc_ip;
fstring dc_name;
- struct cli_state *cli;
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n",
domain));
@@ -71,20 +72,18 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
* Now start the NT Domain stuff :-).
*/
- if(cli_nt_session_open(cli, PI_NETLOGON) == False) {
+ /* Shouldn't we open this with schannel ? JRA. */
+
+ netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &nt_status);
+ if (!netlogon_pipe) {
DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
- dc_name, cli_errstr(cli)));
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
+ dc_name, nt_errstr(nt_status)));
cli_shutdown(cli);
- nt_status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
- nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx, domain);
+ nt_status = trust_pw_find_change_and_store_it(netlogon_pipe, cli->mem_ctx, domain);
- cli_nt_session_close(cli);
- cli_ulogoff(cli);
cli_shutdown(cli);
failed:
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 374c57a083..c1168583ae 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -946,7 +946,7 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext)
int i;
uint32 pwHisLen, curr_pwHisLen;
- account_policy_get(AP_PASSWORD_HISTORY, &pwHisLen);
+ pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen);
if (pwHisLen == 0) {
return False;
}
@@ -1017,7 +1017,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
return NT_STATUS_ACCOUNT_RESTRICTION;
}
- if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
+ if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
DEBUG(1, ("user %s cannot change password - password too short\n",
username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index afc645ca06..becca003b6 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -110,31 +110,30 @@ static int close_filestruct(files_struct *fsp)
If any deferred opens are waiting on this close, notify them.
****************************************************************************/
-static void notify_deferred_opens(files_struct *fsp)
+static void notify_deferred_opens(struct share_mode_lock *lck)
{
- deferred_open_entry *de_array = NULL;
- int num_de_entries, i;
- pid_t mypid = sys_getpid();
-
- if (!lp_defer_sharing_violations()) {
- return;
- }
-
- num_de_entries = get_deferred_opens(fsp->conn, fsp->dev, fsp->inode, &de_array);
- for (i = 0; i < num_de_entries; i++) {
- deferred_open_entry *entry = &de_array[i];
- if (entry->pid == mypid) {
- /*
- * We need to notify ourself to retry the open.
- * Do this by finding the queued SMB record, moving it
- * to the head of the queue and changing the wait time to zero.
- */
- schedule_sharing_violation_open_smb_message(entry->mid);
- } else {
- send_deferred_open_retry_message(entry);
- }
- }
- SAFE_FREE(de_array);
+ int i;
+
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+
+ if (!is_deferred_open_entry(e)) {
+ continue;
+ }
+
+ if (procid_is_me(&e->pid)) {
+ /*
+ * We need to notify ourself to retry the open. Do
+ * this by finding the queued SMB record, moving it to
+ * the head of the queue and changing the wait time to
+ * zero.
+ */
+ schedule_deferred_open_smb_message(e->op_mid);
+ } else {
+ message_send_pid(e->pid, MSG_SMB_OPEN_RETRY,
+ e, sizeof(*e), True);
+ }
+ }
}
/****************************************************************************
@@ -148,13 +147,12 @@ static void notify_deferred_opens(files_struct *fsp)
static int close_normal_file(files_struct *fsp, BOOL normal_close)
{
- share_mode_entry *share_entry = NULL;
- size_t share_entry_count = 0;
BOOL delete_file = False;
connection_struct *conn = fsp->conn;
int saved_errno = 0;
int err = 0;
int err1 = 0;
+ struct share_mode_lock *lck;
remove_pending_lock_requests_by_fid(fsp);
@@ -194,23 +192,34 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* This prevents race conditions with the file being created. JRA.
*/
- lock_share_entry_fsp(fsp);
-
- share_entry_count = del_share_mode(fsp, &share_entry,
- &delete_file);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fsp->fsp_name);
- DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
- (unsigned long)share_entry_count, fsp->fsp_name ));
+ if (lck == NULL) {
+ DEBUG(0, ("Could not get share mode lock\n"));
+ return EINVAL;
+ }
- if (share_entry_count != 0) {
- /* We're not the last ones -- don't delete */
- delete_file = False;
+ if (!del_share_mode(lck, fsp)) {
+ DEBUG(0, ("Could not delete share entry\n"));
}
- SAFE_FREE(share_entry);
+ delete_file = lck->delete_on_close;
+
+ if (delete_file) {
+ int i;
+ /* See if others still have the file open. If this is the
+ * case, then don't delete */
+ for (i=0; i<lck->num_share_modes; i++) {
+ if (is_valid_share_mode_entry(&lck->share_modes[i])) {
+ delete_file = False;
+ break;
+ }
+ }
+ }
/* Notify any deferred opens waiting on this close. */
- notify_deferred_opens(fsp);
+ notify_deferred_opens(lck);
+ reply_to_oplock_break_requests(fsp);
/*
* NT can set delete_on_close of the last open
@@ -234,7 +243,7 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
process_pending_change_notify_queue((time_t)0);
}
- unlock_share_entry_fsp(fsp);
+ talloc_free(lck);
if(fsp->oplock_type)
release_file_oplock(fsp);
@@ -296,7 +305,7 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
*/
if (normal_close &&
- get_delete_on_close_flag(fsp->dev, fsp->inode)) {
+ get_delete_on_close_flag(fsp->dev, fsp->inode, fsp->fsp_name)) {
BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
fsp->fsp_name, ok ? "succeeded" : "failed" ));
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index b69868ecec..bb000bac30 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -287,7 +287,7 @@ the message contains just a share name and all instances of that
share are unmounted
the special sharename '*' forces unmount of all shares
****************************************************************************/
-void msg_force_tdis(int msg_type, pid_t pid, void *buf, size_t len)
+void msg_force_tdis(int msg_type, struct process_id pid, void *buf, size_t len)
{
connection_struct *conn, *next;
fstring sharename;
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 32e2f058fc..07d3181144 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -38,7 +38,7 @@ TDB_CONTEXT *conn_tdb_ctx(void)
static void make_conn_key(connection_struct *conn, const char *name, TDB_DATA *pkbuf, struct connections_key *pkey)
{
ZERO_STRUCTP(pkey);
- pkey->pid = sys_getpid();
+ pkey->pid = procid_self();
pkey->cnum = conn?conn->cnum:-1;
fstrcpy(pkey->name, name);
#ifdef DEVELOPER
@@ -107,8 +107,8 @@ static int count_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *u
/* If the pid was not found delete the entry from connections.tdb */
if (cs->Clear && !process_exists(crec.pid) && (errno == ESRCH)) {
- DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
- (unsigned int)crec.pid, crec.cnum, crec.name));
+ DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
+ procid_str_static(&crec.pid), crec.cnum, crec.name));
if (tdb_delete(the_tdb, kbuf) != 0)
DEBUG(0,("count_fn: tdb_delete failed with error %s\n", tdb_errorstr(tdb) ));
return 0;
@@ -174,7 +174,7 @@ BOOL claim_connection(connection_struct *conn, const char *name,int max_connecti
/* fill in the crec */
ZERO_STRUCT(crec);
crec.magic = 0x280267;
- crec.pid = sys_getpid();
+ crec.pid = procid_self();
crec.cnum = conn?conn->cnum:-1;
if (conn) {
crec.uid = conn->uid;
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index 090a2f6d81..3cdcae5c7f 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -41,23 +41,22 @@ void set_saved_error_triple(int eclass, int ecode, NTSTATUS status)
override_ERR_ntstatus = status;
}
+void set_saved_ntstatus(NTSTATUS status)
+{
+ uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */
+ override_ERR_ntstatus = status;
+ ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code);
+ override_ERR_class = tmp_eclass;
+
+}
+
/****************************************************************************
Return the current settings of the error triple. Return True if any are set.
****************************************************************************/
-BOOL get_saved_error_triple(int *peclass, int *pecode, NTSTATUS *pstatus)
+NTSTATUS get_saved_ntstatus(void)
{
- if (peclass) {
- *peclass = override_ERR_class;
- }
- if (pecode) {
- *pecode = override_ERR_code;
- }
- if (pstatus) {
- *pstatus = override_ERR_ntstatus;
- }
-
- return (override_ERR_class || !NT_STATUS_IS_OK(override_ERR_ntstatus));
+ return override_ERR_ntstatus;
}
/****************************************************************************
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 65986e9612..181e17b11f 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -65,7 +65,7 @@ files_struct *file_new(connection_struct *conn)
{
int i;
static int first_file;
- files_struct *fsp, *next;
+ files_struct *fsp;
/* we want to give out file handles differently on each new
connection because of a common bug in MS clients where they try to
@@ -76,32 +76,21 @@ files_struct *file_new(connection_struct *conn)
first_file = (sys_getpid() ^ (int)time(NULL)) % real_max_open_files;
}
+ /* TODO: Port the id-tree implementation from Samba4 */
+
i = bitmap_find(file_bmap, first_file);
if (i == -1) {
- /*
- * Before we give up, go through the open files
- * and see if there are any files opened with a
- * batch oplock. If so break the oplock and then
- * re-use that entry (if it becomes closed).
- * This may help as NT/95 clients tend to keep
- * files batch oplocked for quite a long time
- * after they have finished with them.
- */
- for (fsp=Files;fsp;fsp=next) {
- next=fsp->next;
- if (attempt_close_oplocked_file(fsp)) {
- return file_new(conn);
- }
- }
-
DEBUG(0,("ERROR! Out of file structures\n"));
- set_saved_error_triple(ERRSRV, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES);
+ /* TODO: We have to unconditionally return a DOS error here,
+ * W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with
+ * NTSTATUS negotiated */
+ set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES);
return NULL;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
- set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
+ set_saved_ntstatus(NT_STATUS_NO_MEMORY);
return NULL;
}
@@ -110,7 +99,7 @@ files_struct *file_new(connection_struct *conn)
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (!fsp->fh) {
SAFE_FREE(fsp);
- set_saved_error_triple(ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY);
+ set_saved_ntstatus(NT_STATUS_NO_MEMORY);
return NULL;
}
@@ -293,7 +282,9 @@ files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_i
DLIST_PROMOTE(Files, fsp);
}
/* Paranoia check. */
- if (fsp->fh->fd == -1 && fsp->oplock_type != NO_OPLOCK) {
+ if ((fsp->fh->fd == -1) &&
+ (fsp->oplock_type != NO_OPLOCK) &&
+ (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
DEBUG(0,("file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \
oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, (unsigned int)fsp->file_id,
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index 613dda9a16..335ba8e2ef 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -212,7 +212,7 @@ static BOOL is_mangled_component(const char *name, size_t len)
{
unsigned int i;
- M_DEBUG(10,("is_mangled_component %s (len %u) ?\n", name, (unsigned int)len));
+ M_DEBUG(10,("is_mangled_component %s (len %lu) ?\n", name, (unsigned long)len));
/* check the length */
if (len > 12 || len < 8)
@@ -250,7 +250,7 @@ static BOOL is_mangled_component(const char *name, size_t len)
}
}
- M_DEBUG(10,("is_mangled_component %s (len %u) -> yes\n", name, (unsigned int)len));
+ M_DEBUG(10,("is_mangled_component %s (len %lu) -> yes\n", name, (unsigned long)len));
return True;
}
diff --git a/source3/smbd/message.c b/source3/smbd/message.c
index 5af7d3e451..e975da3e15 100644
--- a/source3/smbd/message.c
+++ b/source3/smbd/message.c
@@ -43,6 +43,7 @@ static void msg_deliver(void)
int fd;
char *msg;
int len;
+ ssize_t sz;
if (! (*lp_msg_command()))
{
@@ -70,14 +71,20 @@ static void msg_deliver(void)
if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') {
i++; continue;
}
- write(fd, &msgbuf[i++], 1);
+ sz = write(fd, &msgbuf[i++], 1);
+ if ( sz != 1 ) {
+ DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno ));
+ }
}
} else {
for (i = 0; i < len;) {
if (msg[i] == '\r' && i < (len-1) && msg[i+1] == '\n') {
i++; continue;
}
- write(fd, &msg[i++],1);
+ sz = write(fd, &msg[i++],1);
+ if ( sz != 1 ) {
+ DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno ));
+ }
}
SAFE_FREE(msg);
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index f9b70de0ac..3db55bad14 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -24,7 +24,6 @@
extern int max_send;
extern enum protocol_types Protocol;
extern int smb_read_error;
-extern int global_oplock_break;
extern struct current_user current_user;
static const char *known_nt_pipes[] = {
@@ -43,6 +42,7 @@ static const char *known_nt_pipes[] = {
"\\rpcecho",
"\\svcctl",
"\\eventlog",
+ "\\unixinfo",
NULL
};
@@ -861,7 +861,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
} else {
SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
}
- } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+ } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
} else {
SCVAL(p,0,NO_OPLOCK_RETURN);
@@ -1666,11 +1666,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&info);
if (!fsp1) {
- get_saved_error_triple(NULL, NULL, &status);
+ status = get_saved_ntstatus();
if (NT_STATUS_IS_OK(status)) {
status = NT_STATUS_ACCESS_DENIED;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return status;
}
@@ -1684,11 +1684,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
&info);
if (!fsp2) {
- get_saved_error_triple(NULL, NULL, &status);
+ status = get_saved_ntstatus();
if (NT_STATUS_IS_OK(status)) {
status = NT_STATUS_ACCESS_DENIED;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
close_file(fsp1,False);
return status;
}
@@ -1989,7 +1989,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %d.\n",(int)sd_size));
+ DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
SIVAL(params,0,(uint32)sd_size);
@@ -2743,21 +2743,6 @@ int reply_nttrans(connection_struct *conn,
uint32 num_params_sofar, num_data_sofar;
START_PROFILE(SMBnttrans);
- if(global_oplock_break &&
- ((function_code == NT_TRANSACT_CREATE) ||
- (function_code == NT_TRANSACT_RENAME))) {
- /*
- * Queue this open message as we are the process of an oplock break.
- */
-
- DEBUG(2,("reply_nttrans: queueing message code 0x%x \
-due to being in oplock break state.\n", (unsigned int)function_code ));
-
- push_oplock_pending_smb_message( inbuf, length);
- END_PROFILE(SMBnttrans);
- return -1;
- }
-
if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
END_PROFILE(SMBnttrans);
return ERROR_DOS(ERRSRV,ERRaccess);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index ed847826d5..56d31c6940 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -24,11 +24,11 @@
extern struct current_user current_user;
extern userdom_struct current_user_info;
-extern uint16 global_oplock_port;
extern uint16 global_smbpid;
extern BOOL global_client_failed_oplock_break;
-struct dev_inode_bundle {
+struct deferred_open_record {
+ BOOL delayed_for_oplocks;
SMB_DEV_T dev;
SMB_INO_T inode;
};
@@ -208,7 +208,6 @@ static BOOL open_file(files_struct *fsp,
BOOL file_existed = VALID_STAT(*psbuf);
fsp->fh->fd = -1;
- fsp->oplock_type = NO_OPLOCK;
errno = EPERM;
/* Check permissions */
@@ -283,8 +282,7 @@ static BOOL open_file(files_struct *fsp,
/* Don't create files with Microsoft wildcard characters. */
if ((local_flags & O_CREAT) && !file_existed &&
ms_has_wild(fname)) {
- set_saved_error_triple(ERRDOS, ERRinvalidname,
- NT_STATUS_OBJECT_NAME_INVALID);
+ set_saved_ntstatus(NT_STATUS_OBJECT_NAME_INVALID);
return False;
}
@@ -354,7 +352,6 @@ static BOOL open_file(files_struct *fsp,
}
fsp->print_file = False;
fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
fsp->is_stat = False;
@@ -397,7 +394,7 @@ static BOOL is_executable(const char *fname)
Returns True if conflict, False if not.
****************************************************************************/
-static BOOL share_conflict(share_mode_entry *entry,
+static BOOL share_conflict(struct share_mode_entry *entry,
uint32 access_mask,
uint32 share_access)
{
@@ -445,7 +442,6 @@ static BOOL share_conflict(share_mode_entry *entry,
DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
(unsigned int)(share) )); \
- set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); \
return True; \
}
#else
@@ -454,7 +450,6 @@ sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (u
DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
(unsigned int)(share) )); \
- set_saved_error_triple(ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); \
return True; \
}
#endif
@@ -480,11 +475,23 @@ sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (u
#if defined(DEVELOPER)
static void validate_my_share_entries(int num,
- share_mode_entry *share_entry)
+ struct share_mode_entry *share_entry)
{
files_struct *fsp;
- if (share_entry->pid != sys_getpid()) {
+ if (!procid_is_me(&share_entry->pid)) {
+ return;
+ }
+
+ if (is_deferred_open_entry(share_entry) &&
+ !open_was_deferred(share_entry->op_mid)) {
+ pstring str;
+ DEBUG(0, ("Got a deferred entry without a request: "
+ "PANIC: %s\n", share_mode_str(num, share_entry)));
+ smb_panic(str);
+ }
+
+ if (!is_valid_share_mode_entry(share_entry)) {
return;
}
@@ -497,7 +504,26 @@ static void validate_my_share_entries(int num,
"share entry with an open file\n");
}
+ if (is_deferred_open_entry(share_entry) ||
+ is_unused_share_mode_entry(share_entry)) {
+ goto panic;
+ }
+
+ if ((share_entry->op_type == NO_OPLOCK) &&
+ (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK)) {
+ /* Someone has already written to it, but I haven't yet
+ * noticed */
+ return;
+ }
+
if (((uint16)fsp->oplock_type) != share_entry->op_type) {
+ goto panic;
+ }
+
+ return;
+
+ panic:
+ {
pstring str;
DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
share_mode_str(num, share_entry) ));
@@ -510,375 +536,217 @@ static void validate_my_share_entries(int num,
}
#endif
-struct share_mode_entry_list {
- struct share_mode_entry_list *next, *prev;
- share_mode_entry entry;
-};
-
-static void free_broken_entry_list(struct share_mode_entry_list *broken_entry_list)
+static BOOL is_stat_open(uint32 access_mask)
{
- while (broken_entry_list) {
- struct share_mode_entry_list *broken_entry = broken_entry_list;
- DLIST_REMOVE(broken_entry_list, broken_entry);
- SAFE_FREE(broken_entry);
- }
-}
-
-static BOOL cause_oplock_break(int request, int existing, uint32 access_mask)
-{
- if ((access_mask == DELETE_ACCESS) &&
- (request == NO_OPLOCK)) {
- /* This is a delete request */
- return (BATCH_OPLOCK_TYPE(existing) != 0);
- }
-
- if (EXCLUSIVE_OPLOCK_TYPE(existing) && (request != NO_OPLOCK)) {
- return True;
- }
-
- if ((existing != NO_OPLOCK) && (request == NO_OPLOCK)) {
- return True;
- }
-
- return False;
+ return (access_mask &&
+ ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
+ FILE_WRITE_ATTRIBUTES))==0) &&
+ ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
+ FILE_WRITE_ATTRIBUTES)) != 0));
}
/****************************************************************************
- Deal with open deny mode and oplock break processing.
+ Deal with share modes
Invarient: Share mode must be locked on entry and exit.
Returns -1 on error, or number of share modes on success (may be zero).
****************************************************************************/
-static int open_mode_check(connection_struct *conn,
- const char *fname,
- SMB_DEV_T dev,
- SMB_INO_T inode,
- uint32 access_mask,
- uint32 share_access,
- uint32 create_options,
- int *p_oplock_request,
- BOOL *p_all_current_opens_are_level_II)
+static NTSTATUS open_mode_check(connection_struct *conn,
+ const char *fname,
+ struct share_mode_lock *lck,
+ uint32 access_mask,
+ uint32 share_access,
+ uint32 create_options,
+ BOOL *file_existed)
{
int i;
- int num_share_modes;
- int oplock_contention_count = 0;
- share_mode_entry *old_shares = NULL;
- BOOL broke_oplock;
- BOOL delete_on_close;
- num_share_modes = get_share_modes(dev, inode, &old_shares, &delete_on_close);
-
- if(num_share_modes == 0) {
- SAFE_FREE(old_shares);
- return 0;
+ if(lck->num_share_modes == 0) {
+ return NT_STATUS_OK;
}
+
+ *file_existed = True;
- if (access_mask &&
- ((access_mask & ~(SYNCHRONIZE_ACCESS| FILE_READ_ATTRIBUTES|
- FILE_WRITE_ATTRIBUTES))==0) &&
- ((access_mask & (SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
- FILE_WRITE_ATTRIBUTES)) != 0)) {
+ if (is_stat_open(access_mask)) {
/* Stat open that doesn't trigger oplock breaks or share mode
* checks... ! JRA. */
- SAFE_FREE(old_shares);
- return num_share_modes;
+ return NT_STATUS_OK;
}
/* A delete on close prohibits everything */
- if (delete_on_close) {
- SAFE_FREE(old_shares);
- errno = EACCES;
- return -1;
+ if (lck->delete_on_close) {
+ return NT_STATUS_DELETE_PENDING;
}
/*
* Check if the share modes will give us access.
*/
- do {
- struct share_mode_entry_list *broken_entry_list = NULL;
- struct share_mode_entry_list *broken_entry = NULL;
-
- broke_oplock = False;
- *p_all_current_opens_are_level_II = True;
-
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &old_shares[i];
- BOOL opb_ret;
-
#if defined(DEVELOPER)
- validate_my_share_entries(i, share_entry);
+ for(i = 0; i < lck->num_share_modes; i++) {
+ validate_my_share_entries(i, &lck->share_modes[i]);
+ }
#endif
- /*
- * By observation of NetBench, oplocks are broken
- * *before* share modes are checked. This allows a
- * file to be closed by the client if the share mode
- * would deny access and the client has an oplock.
- * Check if someone has an oplock on this file. If so
- * we must break it before continuing.
- */
+ if (!lp_share_modes(SNUM(conn))) {
+ return NT_STATUS_OK;
+ }
- if (!cause_oplock_break(*p_oplock_request,
- share_entry->op_type,
- access_mask)) {
- if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- *p_all_current_opens_are_level_II = False;
- }
- continue;
- }
+ /* Now we check the share modes, after any oplock breaks. */
+ for(i = 0; i < lck->num_share_modes; i++) {
- /* This is an oplock break */
-
- DEBUG(5,("open_mode_check: oplock_request = %d, "
- "breaking oplock (%x) on file %s, "
- "dev = %x, inode = %.0f\n",
- *p_oplock_request, share_entry->op_type,
- fname, (unsigned int)dev, (double)inode));
-
- /* Ensure the reply for the open uses the correct
- * sequence number. */
- /* This isn't a real deferred packet as it's response
- * will also increment the sequence.
- */
- srv_defer_sign_response(get_current_mid());
-
- /* Oplock break - unlock to request it. */
- unlock_share_entry(conn, dev, inode);
-
- opb_ret = request_oplock_break(share_entry);
-
- /* Now relock. */
- lock_share_entry(conn, dev, inode);
-
- if (!opb_ret) {
- DEBUG(0,("open_mode_check: FAILED when breaking "
- "oplock (%x) on file %s, dev = %x, "
- "inode = %.0f\n",
- old_shares[i].op_type, fname,
- (unsigned int)dev, (double)inode));
- SAFE_FREE(old_shares);
- set_saved_error_triple(ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
- return -1;
- }
-
- broken_entry = SMB_MALLOC_P(struct share_mode_entry_list);
- if (!broken_entry) {
- smb_panic("open_mode_check: malloc fail.\n");
- }
- broken_entry->entry = *share_entry;
- DLIST_ADD(broken_entry_list, broken_entry);
- broke_oplock = True;
-
- } /* end for */
-
- if (broke_oplock) {
- /* Update the current open table. */
- SAFE_FREE(old_shares);
- num_share_modes = get_share_modes(dev, inode,
- &old_shares,
- &delete_on_close);
+ if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
+ continue;
}
- if (lp_share_modes(SNUM(conn))) {
- /* Now we check the share modes, after any oplock breaks. */
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &old_shares[i];
-
- /* someone else has a share lock on it, check to see
- * if we can too */
- if (share_conflict(share_entry, access_mask,
- share_access)) {
- SAFE_FREE(old_shares);
- free_broken_entry_list(broken_entry_list);
- errno = EACCES;
- return -1;
- }
- }
+ /* someone else has a share lock on it, check to see if we can
+ * too */
+ if (share_conflict(&lck->share_modes[i],
+ access_mask, share_access)) {
+ return NT_STATUS_SHARING_VIOLATION;
}
-
- for(broken_entry = broken_entry_list; broken_entry;
- broken_entry = broken_entry->next) {
- oplock_contention_count++;
-
- /* Paranoia check that this is no longer an exlusive entry. */
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &old_shares[i];
-
- if (!(share_modes_identical(&broken_entry->entry,
- share_entry) &&
- EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type))) {
- continue;
- }
-
- /*
- * This should not happen. The target left this oplock
- * as exlusive.... The process *must* be dead....
- */
-
- DEBUG(0,("open_mode_check: exlusive oplock left by "
- "process %d after break ! For file %s, "
- "dev = %x, inode = %.0f. Deleting it to "
- "continue...\n",
- (int)broken_entry->entry.pid, fname,
- (unsigned int)dev, (double)inode));
-
- if (process_exists(broken_entry->entry.pid)) {
- DEBUG(0,("open_mode_check: Existent process "
- "%lu left active oplock.\n",
- (unsigned long)broken_entry->entry.pid ));
- }
-
- if (del_share_entry(dev, inode, &broken_entry->entry,
- NULL, &delete_on_close) == -1) {
- free_broken_entry_list(broken_entry_list);
- errno = EACCES;
- set_saved_error_triple(ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
- return -1;
- }
-
- /*
- * We must reload the share modes after deleting the
- * other process's entry.
- */
-
- SAFE_FREE(old_shares);
- num_share_modes = get_share_modes(dev, inode,
- &old_shares,
- &delete_on_close);
- break;
- } /* end for paranoia... */
- } /* end for broken_entry */
- free_broken_entry_list(broken_entry_list);
- } while(broke_oplock);
-
- /*
- * Refuse to grant an oplock in case the contention limit is
- * reached when going through the lock list multiple times.
- */
-
- if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
- *p_oplock_request = 0;
- DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
- oplock_contention_count ));
}
- SAFE_FREE(old_shares);
- return num_share_modes;
+ return NT_STATUS_OK;
}
-/****************************************************************************
- Delete the record for a handled deferred open entry.
-****************************************************************************/
+static BOOL is_delete_request(files_struct *fsp) {
+ return ((fsp->access_mask == DELETE_ACCESS) &&
+ (fsp->oplock_type == NO_OPLOCK));
+}
-static void delete_defered_open_entry_record(connection_struct *conn,
- SMB_DEV_T dev,
- SMB_INO_T inode)
+/*
+ * 1) No files open at all: Grant whatever the client wants.
+ *
+ * 2) Exclusive (or batch) oplock around: If the requested access is a delete
+ * request, break if the oplock around is a batch oplock. If it's another
+ * requested access type, break.
+ *
+ * 3) Only level2 around: Grant level2 and do nothing else.
+ */
+
+static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp)
{
- uint16 mid = get_current_mid();
- pid_t mypid = sys_getpid();
- deferred_open_entry *de_array = NULL;
- int num_de_entries, i;
+ int i, num_level2;
+ struct share_mode_entry *exclusive = NULL;
+ BOOL delay_it = False;
+ BOOL have_level2 = False;
- if (!lp_defer_sharing_violations()) {
- return;
+ if (is_stat_open(fsp->access_mask)) {
+ fsp->oplock_type = NO_OPLOCK;
+ return False;
}
- num_de_entries = get_deferred_opens(conn, dev, inode, &de_array);
- for (i = 0; i < num_de_entries; i++) {
- deferred_open_entry *entry = &de_array[i];
- if (entry->pid == mypid && entry->mid == mid && entry->dev == dev &&
- entry->inode == inode) {
+ num_level2 = 0;
- /* Remove the deferred open entry from the array. */
- delete_deferred_open_entry(entry);
- SAFE_FREE(de_array);
- return;
+ if (lck->num_share_modes == 0) {
+ /* No files open at all: Directly grant whatever the client
+ * wants. */
+
+ if (fsp->oplock_type == NO_OPLOCK) {
+ /* Store a level2 oplock, but don't tell the client */
+ fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
+ }
+ return False;
+ }
+
+ for (i=0; i<lck->num_share_modes; i++) {
+
+ if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
+ continue;
+ }
+
+ if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
+ SMB_ASSERT(exclusive == NULL);
+ exclusive = &lck->share_modes[i];
+ }
+
+ if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
+ have_level2 = True;
}
}
- SAFE_FREE(de_array);
+
+ if (exclusive != NULL) { /* Found an exclusive oplock */
+ SMB_ASSERT(!have_level2);
+ delay_it = is_delete_request(fsp) ?
+ BATCH_OPLOCK_TYPE(exclusive->op_type) : True;
+ }
+
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ /* We can at most grant level2 */
+ fsp->oplock_type = LEVEL_II_OPLOCK;
+ }
+
+ if ((fsp->oplock_type == NO_OPLOCK) && have_level2) {
+ /* Store a level2 oplock, but don't tell the client */
+ fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
+ }
+
+ if (delay_it) {
+ DEBUG(10, ("Sending break request to PID %s\n",
+ procid_str_static(&exclusive->pid)));
+ exclusive->op_mid = get_current_mid();
+ if (!message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
+ exclusive, sizeof(*exclusive), True)) {
+ DEBUG(3, ("Could not send oplock break message\n"));
+ }
+ file_free(fsp);
+ }
+
+ return delay_it;
+}
+
+static BOOL request_timed_out(struct timeval request_time,
+ struct timeval timeout)
+{
+ struct timeval now, end_time;
+ GetTimeOfDay(&now);
+ end_time = timeval_sum(&request_time, &timeout);
+ return (timeval_compare(&end_time, &now) < 0);
}
/****************************************************************************
Handle the 1 second delay in returning a SHARING_VIOLATION error.
****************************************************************************/
-static void defer_open_sharing_error(connection_struct *conn,
- struct timeval *ptv,
- const char *fname,
- SMB_DEV_T dev,
- SMB_INO_T inode)
+static void defer_open(struct share_mode_lock *lck,
+ struct timeval request_time,
+ struct timeval timeout,
+ struct deferred_open_record *state)
{
uint16 mid = get_current_mid();
- pid_t mypid = sys_getpid();
- deferred_open_entry *de_array = NULL;
- int num_de_entries, i;
- struct dev_inode_bundle dib;
+ int i;
- if (!lp_defer_sharing_violations()) {
- return;
- }
+ /* Paranoia check */
- dib.dev = dev;
- dib.inode = inode;
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
- num_de_entries = get_deferred_opens(conn, dev, inode, &de_array);
- for (i = 0; i < num_de_entries; i++) {
- deferred_open_entry *entry = &de_array[i];
- if (entry->pid == mypid && entry->mid == mid) {
- /*
- * Check if a 1 second timeout has expired.
- */
- if (usec_time_diff(ptv, &entry->time) >
- SHARING_VIOLATION_USEC_WAIT) {
- DEBUG(10,("defer_open_sharing_error: Deleting "
- "deferred open entry for mid %u, "
- "file %s\n",
- (unsigned int)mid, fname ));
-
- /* Expired, return a real error. */
- /* Remove the deferred open entry from the array. */
-
- delete_deferred_open_entry(entry);
- SAFE_FREE(de_array);
- return;
- }
- /*
- * If the timeout hasn't expired yet and we still have
- * a sharing violation, just leave the entry in the
- * deferred open array alone. We do need to reschedule
- * this open call though (with the original created
- * time).
- */
- DEBUG(10,("defer_open_sharing_error: time [%u.%06u] "
- "updating deferred open entry for mid %u, file %s\n",
- (unsigned int)entry->time.tv_sec,
- (unsigned int)entry->time.tv_usec,
- (unsigned int)mid, fname ));
-
- push_sharing_violation_open_smb_message(&entry->time,
- (char *)&dib,
- sizeof(dib));
- SAFE_FREE(de_array);
- return;
+ if (!is_deferred_open_entry(e)) {
+ continue;
+ }
+
+ if (procid_is_me(&e->pid) && (e->op_mid == mid)) {
+ DEBUG(0, ("Trying to defer an already deferred "
+ "request: mid=%d, exiting\n", mid));
+ exit_server("exiting");
}
}
+ /* End paranoia check */
+
DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
- "open entry for mid %u, file %s\n",
- (unsigned int)ptv->tv_sec, (unsigned int)ptv->tv_usec,
- (unsigned int)mid, fname ));
+ "open entry for mid %u\n",
+ (unsigned int)request_time.tv_sec,
+ (unsigned int)request_time.tv_usec,
+ (unsigned int)mid));
- if (!push_sharing_violation_open_smb_message(ptv, (char *)&dib, sizeof(dib))) {
- SAFE_FREE(de_array);
- return;
- }
- if (!add_deferred_open(mid, ptv, dev, inode, global_oplock_port, fname)) {
- remove_sharing_violation_open_smb_message(mid);
+ if (!push_deferred_smb_message(mid, request_time, timeout,
+ (char *)state, sizeof(*state))) {
+ exit_server("push_deferred_smb_message failed\n");
}
+ add_deferred_open(lck, mid, request_time, state->dev, state->inode);
/*
* Push the MID of this packet on the signing queue.
@@ -888,8 +756,6 @@ static void defer_open_sharing_error(connection_struct *conn,
*/
srv_defer_sign_response(mid);
-
- SAFE_FREE(de_array);
}
/****************************************************************************
@@ -1196,8 +1062,6 @@ files_struct *open_file_ntcreate(connection_struct *conn,
BOOL internal_only_open = False;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
- int num_share_modes = 0;
- BOOL all_current_opens_are_level_II = False;
BOOL fsp_open = False;
files_struct *fsp = NULL;
mode_t new_unx_mode = (mode_t)0;
@@ -1205,8 +1069,11 @@ files_struct *open_file_ntcreate(connection_struct *conn,
int info;
uint32 existing_dos_attributes = 0;
struct pending_message_list *pml = NULL;
- uint16 port = 0;
uint16 mid = get_current_mid();
+ BOOL delayed_for_oplocks = False;
+ struct timeval request_time = timeval_zero();
+ struct share_mode_lock *lck = NULL;
+ NTSTATUS status;
if (conn->printer) {
/*
@@ -1241,9 +1108,11 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
if ((pml = get_open_deferred_message(mid)) != NULL) {
- struct dev_inode_bundle dib;
+ struct deferred_open_record *state =
+ (struct deferred_open_record *)pml->private_data.data;
- memcpy(&dib, pml->private_data.data, sizeof(dib));
+ request_time = pml->request_time;
+ delayed_for_oplocks = state->delayed_for_oplocks;
/* There could be a race condition where the dev/inode pair
has changed since we deferred the message. If so, just
@@ -1255,24 +1124,18 @@ files_struct *open_file_ntcreate(connection_struct *conn,
notified of a close and we don't want to trigger another
spurious oplock break. */
- if (!file_existed || dib.dev != psbuf->st_dev ||
- dib.inode != psbuf->st_ino || pml->msg_time.tv_sec ||
- pml->msg_time.tv_usec) {
- /* Ensure we don't reprocess this message. */
- remove_sharing_violation_open_smb_message(mid);
-
- /* Now remove the deferred open entry under lock. */
- lock_share_entry(conn, dib.dev, dib.inode);
- delete_defered_open_entry_record(conn, dib.dev,
- dib.inode);
- unlock_share_entry(conn, dib.dev, dib.inode);
-
- set_saved_error_triple(ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
- return NULL;
+ /* Now remove the deferred open entry under lock. */
+ lck = get_share_mode_lock(NULL, state->dev, state->inode,
+ fname);
+ if (lck == NULL) {
+ DEBUG(0, ("could not get share mode lock\n"));
+ } else {
+ del_deferred_open_entry(lck, mid);
+ talloc_destroy(lck);
}
+
/* Ensure we don't reprocess this message. */
- remove_sharing_violation_open_smb_message(mid);
+ remove_deferred_open_smb_message(mid);
}
if (!check_name(fname,conn)) {
@@ -1285,7 +1148,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
/* ignore any oplock requests if oplocks are disabled */
- if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
+ if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
+ IS_VETO_OPLOCK_PATH(conn, fname)) {
oplock_request = 0;
}
@@ -1325,7 +1189,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_OPEN "
"requested for file %s and file "
"doesn't exist.\n", fname ));
- set_saved_error_triple(ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
errno = ENOENT;
return NULL;
}
@@ -1338,7 +1202,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
"requested for file %s and file "
"doesn't exist.\n", fname ));
- set_saved_error_triple(ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
errno = ENOENT;
return NULL;
}
@@ -1369,8 +1233,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
break;
default:
- set_saved_error_triple(ERRDOS, ERRinvalidparam,
- NT_STATUS_INVALID_PARAMETER);
+ set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);
return NULL;
}
@@ -1447,8 +1310,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: write access requested for "
"file %s on read only %s\n",
fname, !CAN_WRITE(conn) ? "share" : "file" ));
- set_saved_error_triple(ERRDOS, ERRnoaccess,
- NT_STATUS_ACCESS_DENIED);
+ set_saved_ntstatus(NT_STATUS_ACCESS_DENIED);
errno = EACCES;
return NULL;
}
@@ -1458,45 +1320,96 @@ files_struct *open_file_ntcreate(connection_struct *conn,
return NULL;
}
+ fsp->dev = psbuf->st_dev;
+ fsp->inode = psbuf->st_ino;
+ fsp->share_access = share_access;
+ fsp->fh->private_options = create_options;
+ fsp->access_mask = access_mask;
+ fsp->oplock_type = oplock_request;
+
+ if (timeval_is_zero(&request_time)) {
+ request_time = fsp->open_time;
+ }
+
if (file_existed) {
dev = psbuf->st_dev;
inode = psbuf->st_ino;
- lock_share_entry(conn, dev, inode);
-
- num_share_modes = open_mode_check(conn, fname, dev, inode,
- access_mask, share_access,
- create_options,
- &oplock_request,
- &all_current_opens_are_level_II);
- if(num_share_modes == -1) {
-
- if (!internal_only_open) {
- NTSTATUS status;
- get_saved_error_triple(NULL, NULL, &status);
- if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
- /* Check if this can be done with the
- * deny_dos and fcb calls. */
- if (create_options &
- (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
- NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
- files_struct *fsp_dup;
- fsp_dup = fcb_or_dos_open(conn, fname, dev,
- inode, access_mask,
- share_access,
- create_options);
-
- if (fsp_dup) {
- unlock_share_entry(conn, dev, inode);
- file_free(fsp);
- if (pinfo) {
- *pinfo = FILE_WAS_OPENED;
- }
- conn->num_files_open++;
- return fsp_dup;
- }
+ lck = get_share_mode_lock(NULL, dev, inode, fname);
+
+ if (lck == NULL) {
+ DEBUG(0, ("Could not get share mode lock\n"));
+ set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
+ return NULL;
+ }
+
+ if (delay_for_oplocks(lck, fsp)) {
+ struct deferred_open_record state;
+ struct timeval timeout;
+
+ if (delayed_for_oplocks) {
+ DEBUG(0, ("Trying to delay for oplocks "
+ "twice\n"));
+ exit_server("exiting");
+ }
+
+ timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
+
+ /* Normally the smbd we asked should respond within
+ * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
+ * the client did, give twice the timeout as a safety
+ * measure here in case the other smbd is stuck
+ * somewhere else. */
+
+ state.delayed_for_oplocks = True;
+ state.dev = dev;
+ state.inode = inode;
+
+ if (!request_timed_out(request_time, timeout)) {
+ defer_open(lck, request_time, timeout,
+ &state);
+ }
+
+ talloc_free(lck);
+ return NULL;
+ }
+
+ status = open_mode_check(conn, fname, lck,
+ access_mask, share_access,
+ create_options, &file_existed);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
+ /* DELETE_PENDING is not deferred for a second */
+ set_saved_ntstatus(status);
+ talloc_free(lck);
+ file_free(fsp);
+ return NULL;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+
+ SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
+
+ /* Check if this can be done with the deny_dos and fcb
+ * calls. */
+ if (create_options &
+ (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
+ NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
+ files_struct *fsp_dup;
+ fsp_dup = fcb_or_dos_open(conn, fname, dev,
+ inode, access_mask,
+ share_access,
+ create_options);
+
+ if (fsp_dup) {
+ talloc_free(lck);
+ file_free(fsp);
+ if (pinfo) {
+ *pinfo = FILE_WAS_OPENED;
}
+ conn->num_files_open++;
+ return fsp_dup;
}
}
@@ -1527,8 +1440,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if (!fsp_open && errno) {
/* Default error. */
- set_saved_error_triple(ERRDOS, ERRnoaccess,
- NT_STATUS_ACCESS_DENIED);
+ set_saved_ntstatus(NT_STATUS_ACCESS_DENIED);
}
/*
@@ -1536,27 +1448,32 @@ files_struct *open_file_ntcreate(connection_struct *conn,
* cope with the braindead 1 second delay.
*/
- if (!internal_only_open) {
- NTSTATUS status;
- get_saved_error_triple(NULL, NULL, &status);
- if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
- /* The fsp->open_time here represents
- * the current time of day. */
- defer_open_sharing_error(conn,
- &fsp->open_time,
- fname, dev, inode);
+ if (!internal_only_open &&
+ lp_defer_sharing_violations()) {
+ struct timeval timeout;
+ struct deferred_open_record state;
+
+ timeout = timeval_set(0, SHARING_VIOLATION_USEC_WAIT);
+
+ state.delayed_for_oplocks = False;
+ state.dev = dev;
+ state.inode = inode;
+
+ if (!request_timed_out(request_time,
+ timeout)) {
+ defer_open(lck, request_time, timeout,
+ &state);
}
}
- unlock_share_entry(conn, dev, inode);
+ talloc_free(lck);
if (fsp_open) {
fd_close(conn, fsp);
/*
* We have detected a sharing violation here
* so return the correct error code
*/
- set_saved_error_triple(ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
+ set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
}
file_free(fsp);
return NULL;
@@ -1567,23 +1484,28 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*/
}
+ SMB_ASSERT(!file_existed || (lck != NULL));
+
/*
* Ensure we pay attention to default ACLs on directories if required.
*/
if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
- (def_acl = directory_has_default_acl(conn, parent_dirname(fname)))) {
+ (def_acl = directory_has_default_acl(conn,
+ parent_dirname(fname)))) {
unx_mode = 0777;
}
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
- (unsigned int)flags,(unsigned int)flags2,(unsigned int)unx_mode));
+ (unsigned int)flags, (unsigned int)flags2,
+ (unsigned int)unx_mode));
/*
* open_file strips any O_TRUNC flags itself.
*/
- fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,access_mask);
+ fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,
+ access_mask);
if (!fsp_open && (flags2 & O_EXCL) && (errno == EEXIST)) {
/*
@@ -1602,23 +1524,24 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
if (!fsp_open) {
- if(file_existed) {
- unlock_share_entry(conn, dev, inode);
+ if (lck != NULL) {
+ talloc_free(lck);
}
file_free(fsp);
return NULL;
}
- /*
- * Deal with the race condition where two smbd's detect the file
- * doesn't exist and do the create at the same time. One of them will
- * win and set a share mode, the other (ie. this one) should check if
- * the requested share mode for this create is allowed.
- */
-
if (!file_existed) {
/*
+ * Deal with the race condition where two smbd's detect the
+ * file doesn't exist and do the create at the same time. One
+ * of them will win and set a share mode, the other (ie. this
+ * one) should check if the requested share mode for this
+ * create is allowed.
+ */
+
+ /*
* Now the file exists and fsp is successfully opened,
* fsp->dev and fsp->inode are valid and should replace the
* dev=0,inode=0 from a non existent file. Spotted by
@@ -1628,70 +1551,41 @@ files_struct *open_file_ntcreate(connection_struct *conn,
dev = fsp->dev;
inode = fsp->inode;
- lock_share_entry_fsp(fsp);
-
- num_share_modes = open_mode_check(conn, fname, dev, inode,
- access_mask, share_access,
- create_options,
- &oplock_request,
- &all_current_opens_are_level_II);
-
- if(num_share_modes == -1) {
- NTSTATUS status;
- get_saved_error_triple(NULL, NULL, &status);
- if (NT_STATUS_EQUAL(status,NT_STATUS_SHARING_VIOLATION)) {
- /* Check if this can be done with the deny_dos
- * and fcb calls. */
- if (create_options &
- (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
- NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
- files_struct *fsp_dup;
- fsp_dup = fcb_or_dos_open(conn, fname, dev, inode,
- access_mask, share_access,
- create_options);
- if (fsp_dup) {
- unlock_share_entry(conn, dev, inode);
- fd_close(conn, fsp);
- file_free(fsp);
- if (pinfo) {
- *pinfo = FILE_WAS_OPENED;
- }
- conn->num_files_open++;
- return fsp_dup;
- }
- }
-
- /*
- * If we're returning a share violation,
- * ensure we cope with the braindead 1 second
- * delay.
- */
-
- /* The fsp->open_time here represents the
- * current time of day. */
- defer_open_sharing_error(conn, &fsp->open_time,
- fname, dev, inode);
- }
+ lck = get_share_mode_lock(NULL, dev, inode, fname);
- unlock_share_entry_fsp(fsp);
- fd_close(conn,fsp);
+ if (lck == NULL) {
+ DEBUG(0, ("Coult not get share mode lock\n"));
+ fd_close(conn, fsp);
file_free(fsp);
- /*
- * We have detected a sharing violation here, so
- * return the correct code.
- */
- set_saved_error_triple(ERRDOS, ERRbadshare,
- NT_STATUS_SHARING_VIOLATION);
+ set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
return NULL;
}
- /*
- * If there are any share modes set then the file *did*
- * exist. Ensure we return the correct value for action.
- */
+ status = open_mode_check(conn, fname, lck,
+ access_mask, share_access,
+ create_options, &file_existed);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ struct deferred_open_record state;
- if (num_share_modes > 0) {
- file_existed = True;
+ fd_close(conn, fsp);
+ file_free(fsp);
+
+ state.delayed_for_oplocks = False;
+ state.dev = dev;
+ state.inode = inode;
+
+ /* Do it all over again immediately. In the second
+ * round we will find that the file existed and handle
+ * the DELETE_PENDING and FCB cases correctly. No need
+ * to duplicate the code here. Essentially this is a
+ * "goto top of this function", but don't tell
+ * anybody... */
+
+ defer_open(lck, request_time, timeval_zero(),
+ &state);
+ talloc_free(lck);
+ return NULL;
}
/*
@@ -1699,6 +1593,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*/
}
+ SMB_ASSERT(lck != NULL);
+
/* note that we ignore failure for the following. It is
basically a hack for NFS, and NFS will never set one of
these only read them. Nobody but Samba can ever set a deny
@@ -1725,7 +1621,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*/
if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) ||
(SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) {
- unlock_share_entry_fsp(fsp);
+ talloc_free(lck);
fd_close(conn,fsp);
file_free(fsp);
return NULL;
@@ -1761,20 +1657,14 @@ files_struct *open_file_ntcreate(connection_struct *conn,
* file structs.
*/
- if(oplock_request && (num_share_modes == 0) &&
- !IS_VETO_OPLOCK_PATH(conn,fname) &&
- set_file_oplock(fsp, oplock_request) ) {
- port = global_oplock_port;
- } else if (oplock_request && all_current_opens_are_level_II) {
- port = global_oplock_port;
- oplock_request = LEVEL_II_OPLOCK;
- set_file_oplock(fsp, oplock_request);
- } else {
- port = 0;
- oplock_request = 0;
+ if ((fsp->oplock_type != NO_OPLOCK) &&
+ (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
+ if (!set_file_oplock(fsp, fsp->oplock_type)) {
+ /* Could not get the kernel oplock */
+ fsp->oplock_type = NO_OPLOCK;
+ }
}
-
- set_share_mode(fsp, port, oplock_request);
+ set_share_mode(lck, fsp, 0, fsp->oplock_type);
if (create_options & FILE_DELETE_ON_CLOSE) {
uint32 dosattr= existing_dos_attributes;
@@ -1788,19 +1678,16 @@ files_struct *open_file_ntcreate(connection_struct *conn,
result = can_set_delete_on_close(fsp, True, dosattr);
if (!NT_STATUS_IS_OK(result)) {
- uint8 u_e_c;
- uint32 u_e_code;
- BOOL dummy_del_on_close;
/* Remember to delete the mode we just added. */
- del_share_mode(fsp, NULL, &dummy_del_on_close);
- unlock_share_entry_fsp(fsp);
+ del_share_mode(lck, fsp);
+ talloc_free(lck);
fd_close(conn,fsp);
file_free(fsp);
- ntstatus_to_dos(result, &u_e_c, &u_e_code);
- set_saved_error_triple(u_e_c, u_e_code, result);
+ set_saved_ntstatus(result);
return NULL;
}
- set_delete_on_close(fsp, True);
+ lck->delete_on_close = True;
+ lck->modified = True;
}
if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
@@ -1860,8 +1747,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
/* If this is a successful open, we must remove any deferred open
* records. */
- delete_defered_open_entry_record(conn, fsp->dev, fsp->inode);
- unlock_share_entry_fsp(fsp);
+ del_deferred_open_entry(lck, mid);
+ talloc_free(lck);
conn->num_files_open++;
@@ -1945,17 +1832,13 @@ files_struct *open_directory(connection_struct *conn,
if (is_ntfs_stream_name(fname)) {
DEBUG(0,("open_directory: %s is a stream name!\n", fname ));
- /* NB. Is the DOS error ERRbadpath or ERRbaddirectory ? */
- set_saved_error_triple(ERRDOS, ERRbadpath,
- NT_STATUS_NOT_A_DIRECTORY);
+ set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY);
return NULL;
}
if (dir_existed && !S_ISDIR(psbuf->st_mode)) {
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
- /* NB. Is the DOS error ERRbadpath or ERRbaddirectory ? */
- set_saved_error_triple(ERRDOS, ERRbadpath,
- NT_STATUS_NOT_A_DIRECTORY);
+ set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY);
return NULL;
}
@@ -1967,8 +1850,7 @@ files_struct *open_directory(connection_struct *conn,
DEBUG(5,("open_directory: FILE_OPEN requested "
"for directory %s and it doesn't "
"exist.\n", fname ));
- set_saved_error_triple(ERRDOS, ERRbadfile,
- NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
return NULL;
}
info = FILE_WAS_OPENED;
@@ -2008,8 +1890,7 @@ files_struct *open_directory(connection_struct *conn,
"0x%x for directory %s\n",
(unsigned int)create_disposition, fname));
file_free(fsp);
- set_saved_error_triple(ERRDOS, ERRinvalidparam,
- NT_STATUS_INVALID_PARAMETER);
+ set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);
return NULL;
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index c0c9e989a9..385f998b1c 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -3,6 +3,7 @@
oplock processing
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998 - 2001
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,25 +22,17 @@
#include "includes.h"
-/* Oplock ipc UDP socket. */
-static int oplock_sock = -1;
-uint16 global_oplock_port = 0;
-
/* Current number of oplocks we have outstanding. */
static int32 exclusive_oplocks_open = 0;
static int32 level_II_oplocks_open = 0;
BOOL global_client_failed_oplock_break = False;
-BOOL global_oplock_break = False;
extern struct timeval smb_last_time;
extern uint32 global_client_caps;
-extern struct current_user current_user;
extern int smb_read_error;
static struct kernel_oplocks *koplocks;
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local);
-
/****************************************************************************
Get the number of current exclusive oplocks.
****************************************************************************/
@@ -58,9 +51,6 @@ BOOL oplock_message_waiting(fd_set *fds)
if (koplocks && koplocks->msg_waiting(fds))
return True;
- if (FD_ISSET(oplock_sock, fds))
- return True;
-
return False;
}
@@ -75,13 +65,9 @@ BOOL oplock_message_waiting(fd_set *fds)
****************************************************************************/
-BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
+void process_kernel_oplocks(void)
{
- struct sockaddr_in from;
- socklen_t fromlen = sizeof(from);
- int32 msg_len = 0;
fd_set fds;
- int selrtn = -1;
FD_ZERO(&fds);
smb_read_error = 0;
@@ -92,110 +78,29 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout)
* already been eaten. JRA.
*/
- if (koplocks && koplocks->msg_waiting(&fds)) {
- return koplocks->receive_message(&fds, buffer, buffer_len);
+ if (!koplocks) {
+ return;
}
- while (timeout > 0 && selrtn == -1) {
- struct timeval to;
- int maxfd = oplock_sock;
- time_t starttime = time(NULL);
-
- FD_ZERO(&fds);
- maxfd = setup_oplock_select_set(&fds);
+ while (koplocks->msg_waiting(&fds)) {
+ files_struct *fsp;
+ struct kernel_oplock_message msg;
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- DEBUG(5,("receive_local_message: doing select with timeout of %d ms\n", timeout));
-
- selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
-
- if (selrtn == -1 && errno == EINTR) {
-
- /* could be a kernel oplock interrupt */
- if (koplocks && koplocks->msg_waiting(&fds)) {
- return koplocks->receive_message(&fds, buffer, buffer_len);
- }
+ fsp = koplocks->receive_message(&fds);
- /*
- * Linux 2.0.x seems to have a bug in that
- * it can return -1, EINTR with a timeout of zero.
- * Make sure we bail out here with a read timeout
- * if we got EINTR on a timeout of 1 or less.
- */
-
- if (timeout <= 1) {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
-
- /* Not a kernel interrupt - could be a SIGUSR1 message. We must restart. */
- /* We need to decrement the timeout here. */
- timeout -= ((time(NULL) - starttime)*1000);
- if (timeout < 0)
- timeout = 1;
-
- DEBUG(5,("receive_local_message: EINTR : new timeout %d ms\n", timeout));
- continue;
+ if (fsp == NULL) {
+ DEBUG(3, ("Kernel oplock message announced, but none "
+ "received\n"));
+ return;
}
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
- }
-
- if (koplocks && koplocks->msg_waiting(&fds)) {
- return koplocks->receive_message(&fds, buffer, buffer_len);
+ msg.dev = fsp->dev;
+ msg.inode = fsp->inode;
+ msg.file_id = fsp->file_id;
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_SMB_KERNEL_BREAK,
+ &msg, sizeof(msg), True);
}
-
- if (!FD_ISSET(oplock_sock, &fds))
- return False;
-
- /*
- * From here down we deal with the smbd <--> smbd
- * oplock break protocol only.
- */
-
- /*
- * Read a loopback udp message.
- */
- msg_len = sys_recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
- buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen);
-
- if(msg_len < 0) {
- DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
- return False;
- }
-
- /* Validate message length. */
- if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
- DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n", msg_len,
- buffer_len - OPBRK_CMD_HEADER_LEN));
- return False;
- }
-
- /* Validate message from address (must be localhost). */
- if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
- DEBUG(0,("receive_local_message: invalid 'from' address \
-(was %lx should be 127.0.0.1)\n", (long)from.sin_addr.s_addr));
- return False;
- }
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
-
- return True;
}
/****************************************************************************
@@ -229,13 +134,19 @@ tv_sec = %x, tv_usec = %x\n",
void release_file_oplock(files_struct *fsp)
{
- if ((fsp->oplock_type != NO_OPLOCK) && koplocks)
+ if ((fsp->oplock_type != NO_OPLOCK) &&
+ (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
+ koplocks) {
koplocks->release_oplock(fsp);
+ }
if (fsp->oplock_type == LEVEL_II_OPLOCK)
level_II_oplocks_open--;
- else if (fsp->oplock_type)
+ else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
exclusive_oplocks_open--;
+
+ SMB_ASSERT(exclusive_oplocks_open>=0);
+ SMB_ASSERT(level_II_oplocks_open>=0);
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
@@ -263,45 +174,58 @@ static void downgrade_file_oplock(files_struct *fsp)
to none even if a "break-to-level II" was sent.
****************************************************************************/
-BOOL remove_oplock(files_struct *fsp, BOOL break_to_none)
+BOOL remove_oplock(files_struct *fsp)
{
SMB_DEV_T dev = fsp->dev;
SMB_INO_T inode = fsp->inode;
- BOOL ret = True;
+ BOOL ret;
+ struct share_mode_lock *lck;
/* Remove the oplock flag from the sharemode. */
- if (lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
- fsp->fsp_name ));
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+ if (lck == NULL) {
+ DEBUG(0,("remove_oplock: failed to lock share entry for "
+ "file %s\n", fsp->fsp_name ));
return False;
}
+ ret = remove_share_oplock(lck, fsp);
+ if (!ret) {
+ DEBUG(0,("remove_oplock: failed to remove share oplock for "
+ "file %s fnum %d, dev = %x, inode = %.0f\n",
+ fsp->fsp_name, fsp->fnum, (unsigned int)dev,
+ (double)inode));
+ }
+ release_file_oplock(fsp);
+ talloc_free(lck);
+ return ret;
+}
- if (fsp->sent_oplock_break == BREAK_TO_NONE_SENT || break_to_none) {
- /*
- * Deal with a reply when a break-to-none was sent.
- */
-
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
-dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
+/*
+ * Deal with a reply when a break-to-level II was sent.
+ */
+BOOL downgrade_oplock(files_struct *fsp)
+{
+ SMB_DEV_T dev = fsp->dev;
+ SMB_INO_T inode = fsp->inode;
+ BOOL ret;
+ struct share_mode_lock *lck;
- release_file_oplock(fsp);
- } else {
- /*
- * Deal with a reply when a break-to-level II was sent.
- */
- if(downgrade_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
-dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
-
- downgrade_file_oplock(fsp);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+ if (lck == NULL) {
+ DEBUG(0,("downgrade_oplock: failed to lock share entry for "
+ "file %s\n", fsp->fsp_name ));
+ return False;
}
-
- unlock_share_entry_fsp(fsp);
+ ret = downgrade_share_oplock(lck, fsp);
+ if (!ret) {
+ DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
+ "for file %s fnum %d, dev = %x, inode = %.0f\n",
+ fsp->fsp_name, fsp->fnum, (unsigned int)dev,
+ (double)inode));
+ }
+
+ downgrade_file_oplock(fsp);
+ talloc_free(lck);
return ret;
}
@@ -313,12 +237,7 @@ dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)
int setup_oplock_select_set( fd_set *fds)
{
- int maxfd = oplock_sock;
-
- if(oplock_sock == -1)
- return 0;
-
- FD_SET(oplock_sock,fds);
+ int maxfd = 0;
if (koplocks && koplocks->notification_fd != -1) {
FD_SET(koplocks->notification_fd, fds);
@@ -329,197 +248,31 @@ int setup_oplock_select_set( fd_set *fds)
}
/****************************************************************************
- Process an oplock break message - whether it came from the UDP socket
- or from the kernel.
+ Set up an oplock break message.
****************************************************************************/
-BOOL process_local_message(char *buffer, int buf_size)
+static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
+ files_struct *fsp, uint8_t cmd)
{
- int32 msg_len;
- uint16 from_port;
- char *msg_start;
- pid_t remotepid;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- unsigned long file_id;
- uint16 break_cmd_type;
- struct sockaddr_in toaddr;
-
- msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
- from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
-
- msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
-
- DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
- msg_len, from_port));
-
- /*
- * Pull the info out of the requesting packet.
- */
-
- break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
-
- switch(break_cmd_type) {
- case KERNEL_OPLOCK_BREAK_CMD:
- if (!koplocks) {
- DEBUG(0,("unexpected kernel oplock break!\n"));
- break;
- }
- if (!koplocks->parse_message(msg_start, msg_len, &inode, &dev, &file_id)) {
- DEBUG(0,("kernel oplock break parse failure!\n"));
- return False;
- }
- break;
-
- case OPLOCK_BREAK_CMD:
- case LEVEL_II_OPLOCK_BREAK_CMD:
- case ASYNC_LEVEL_II_OPLOCK_BREAK_CMD:
-
- /* Ensure that the msg length is correct. */
- if(msg_len != OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
- (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
- memcpy((char *)&file_id, msg_start+OPLOCK_BREAK_FILEID_OFFSET,sizeof(file_id));
-
- DEBUG(5,("process_local_message: (%s) oplock break request from \
-pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
- (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
- break;
-
- case RETRY_DEFERRED_OPEN_CMD:
-
- /* Request to retry and open that would return SHARING_VIOLATION. */
- if (msg_len != DEFERRED_OPEN_MSG_LEN) {
- DEBUG(0,("process_local_message: incorrect length for RETRY_DEFERRED_OPEN_CMD (was %d, should be %d).\n",
- (int)msg_len, (int)DEFERRED_OPEN_MSG_LEN));
- return False;
- }
- {
- uint16 mid;
-
- memcpy((char *)&remotepid, msg_start+DEFERRED_OPEN_PID_OFFSET,sizeof(remotepid));
- memcpy((char *)&inode, msg_start+DEFERRED_OPEN_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&dev, msg_start+DEFERRED_OPEN_DEV_OFFSET,sizeof(dev));
- memcpy((char *)&mid, msg_start+DEFERRED_OPEN_MID_OFFSET,sizeof(mid));
-
- DEBUG(5,("process_local_message: RETRY_DEFERRED_OPEN from \
-pid %d, port %d, dev = %x, inode = %.0f, mid = %u\n",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode, (unsigned int)mid));
-
- schedule_sharing_violation_open_smb_message(mid);
- }
- return True;
-
- /*
- * Keep this as a debug case - eventually we can remove it.
- */
- case 0x8001:
- DEBUG(0,("process_local_message: Received unsolicited break \
-reply - dumping info.\n"));
-
- if(msg_len != OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("process_local_message: ubr: incorrect length for reply \
-(was %d, should be %d).\n", (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
- memcpy((char *)&file_id, msg_start+OPLOCK_BREAK_FILEID_OFFSET,sizeof(file_id));
+ char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
- DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id));
-
- return False;
-
- default:
- DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
- (unsigned int)SVAL(msg_start,0)));
- return False;
- }
-
- /*
- * Now actually process the break request.
- */
-
- if ((exclusive_oplocks_open == 0) &&
- (level_II_oplocks_open == 0)) {
- /*
- * If we have no record of any currently open oplocks,
- * it's not an error, as a close command may have
- * just been issued on the file that was oplocked.
- * Just log a message and return success in this case.
- */
- DEBUG(3,("process_local_message: oplock break requested with "
- "no outstanding oplocks. Returning success.\n"));
-
- } else {
- if (!oplock_break(dev, inode, file_id, False)) {
- DEBUG(0,("process_local_message: oplock break failed.\n"));
- return False;
- }
- }
-
- /*
- * Do the appropriate reply - none in the kernel or async level II
- * case.
- */
-
- if (!((break_cmd_type == OPLOCK_BREAK_CMD) ||
- (break_cmd_type == LEVEL_II_OPLOCK_BREAK_CMD))) {
- return True;
- }
-
- /* Send the message back after OR'ing in the 'REPLY' bit. */
- SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type | CMD_REPLY);
-
- memset((char *)&toaddr,'\0',sizeof(toaddr));
- toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- toaddr.sin_port = htons(from_port);
- toaddr.sin_family = AF_INET;
-
- if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
- (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) {
- DEBUG(0,("process_local_message: sendto process %d failed. "
- "Errno was %s\n", (int)remotepid, strerror(errno)));
- return False;
+ if (result == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
}
- DEBUG(5,("process_local_message: oplock break reply sent to pid %d, "
- "port %d, for file dev = %x, inode = %.0f, file_id = %lu\n",
- (int)remotepid, from_port, (unsigned int)dev,
- (double)inode, file_id));
-
- return True;
-}
-
-/****************************************************************************
- Set up an oplock break message.
-****************************************************************************/
-
-static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
-{
- memset(outbuf,'\0',smb_size);
- set_message(outbuf,8,0,True);
-
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->conn->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fsp->fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
+ memset(result,'\0',smb_size);
+ set_message(result,8,0,True);
+ SCVAL(result,smb_com,SMBlockingX);
+ SSVAL(result,smb_tid,fsp->conn->cnum);
+ SSVAL(result,smb_pid,0xFFFF);
+ SSVAL(result,smb_uid,0);
+ SSVAL(result,smb_mid,0xFFFF);
+ SCVAL(result,smb_vwv0,0xFF);
+ SSVAL(result,smb_vwv2,fsp->fnum);
+ SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
+ SCVAL(result,smb_vwv3+1,cmd);
+ return result;
}
/****************************************************************************
@@ -602,639 +355,266 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un
return fsp;
}
-/****************************************************************************
- Process a level II oplock break directly.
- We must call this function with the share mode entry locked.
-****************************************************************************/
-
-static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request)
+static void oplock_timeout_handler(struct timed_event *te,
+ const struct timeval *now,
+ void *private_data)
{
- char outbuf[128];
- SMB_DEV_T dev = fsp->dev;
- SMB_INO_T inode = fsp->inode;
-
- /*
- * We can have a level II oplock even if the client is not
- * level II oplock aware. In this case just remove the
- * flags and don't send the break-to-none message to
- * the client.
- */
-
- if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
- BOOL sign_state;
-
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- if (local_request) {
- wait_before_sending_break();
- }
-
- /* Prepare the SMBlockingX message. */
- prepare_break_message( outbuf, fsp, False);
-
- /* Save the server smb signing state. */
- sign_state = srv_oplock_set_signing(False);
-
- show_msg(outbuf);
- if (!send_smb(smbd_server_fd(), outbuf))
- exit_server("oplock_break_level2: send_smb failed.");
+ files_struct *fsp = private_data;
- /* Restore the sign state to what it was. */
- srv_oplock_set_signing(sign_state);
- }
-
- /*
- * Now we must update the shared memory structure to tell
- * everyone else we no longer have a level II oplock on
- * this open file. We must call this function with the share mode
- * entry locked so we can change the entry directly.
- */
-
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
- }
-
- release_file_oplock(fsp);
-
- if(level_II_oplocks_open < 0) {
- DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
- level_II_oplocks_open));
- abort();
- }
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "oplock_break_level2: returning success for " );
- dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, fsp->file_id );
- dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
- }
-
- return True;
+ DEBUG(0, ("Oplock break failed -- replying anyway\n"));
+ global_client_failed_oplock_break = True;
+ remove_oplock(fsp);
+ reply_to_oplock_break_requests(fsp);
}
-/****************************************************************************
- Process an oplock break directly.
- This is always called with the share mode lock *NOT* held.
-****************************************************************************/
-
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local_request)
+static void process_oplock_break_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
- char *inbuf = NULL;
- char *saved_inbuf = NULL;
- char *outbuf = NULL;
- char *saved_outbuf = NULL;
- files_struct *fsp = NULL;
- time_t start_time;
- BOOL shutdown_server = False;
- BOOL oplock_timeout = False;
+ struct share_mode_entry *msg = buf;
+ files_struct *fsp;
+ char *break_msg;
+ BOOL break_to_level2 = False;
BOOL sign_state;
- connection_struct *saved_user_conn;
- connection_struct *saved_fsp_conn;
- int saved_vuid;
- pstring saved_dir;
- int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
- pstring file_name;
- BOOL using_levelII;
-
- if((fsp = initial_break_processing(dev, inode, file_id)) == NULL)
- return True;
- /*
- * Deal with a level II oplock going break to none separately.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
- BOOL ret;
- /* We must always call oplock_break_level2() with
- the share mode entry locked. */
- if (lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("oplock_break: unable to lock share entry for file %s\n", fsp->fsp_name ));
- return False;
- }
- ret = oplock_break_level2(fsp, local_request);
- unlock_share_entry_fsp(fsp);
- return ret;
+ if (buf == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
+ return;
}
- /* Mark the oplock break as sent - we don't want to send twice! */
- if (fsp->sent_oplock_break) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
- dbgtext( "file %s ", fsp->fsp_name);
- dbgtext( "(dev = %x, inode = %.0f, file_id = %lu)\n", (unsigned int)dev, (double)inode, fsp->file_id );
- }
-
- /*
- * We have to fail the open here as we cannot send another oplock break on
- * this file whilst we are awaiting a response from the client - neither
- * can we allow another open to succeed while we are waiting for the client.
- */
- return False;
+ if (len != sizeof(*msg)) {
+ DEBUG(0, ("Got invalid msg len %d\n", (int)len));
+ return;
}
- if(global_oplock_break) {
- DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
- abort();
- }
+ DEBUG(10, ("Got oplock break message from pid %d: %d/%d/%d\n",
+ (int)procid_to_pid(&src), (int)msg->dev, (int)msg->inode,
+ (int)msg->share_file_id));
- /*
- * Now comes the horrid part. We must send an oplock break to the client,
- * and then process incoming messages until we get a close or oplock release.
- * At this point we know we need a new inbuf/outbuf buffer pair.
- * We cannot use these staticaly as we may recurse into here due to
- * messages crossing on the wire.
- */
+ fsp = initial_break_processing(msg->dev, msg->inode,
+ msg->share_file_id);
- if((inbuf = NewInBuffer(&saved_inbuf))==NULL) {
- DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
- return False;
+ if (fsp == NULL) {
+ /* We hit race here. Break messages are sent, and before we
+ * get to process this message, we have closed the file. Reply
+ * with 'ok, oplock broken' */
+ DEBUG(3, ("Did not find fsp\n"));
+ message_send_pid(src, MSG_SMB_BREAK_RESPONSE,
+ msg, sizeof(*msg), True);
+ return;
}
- if((outbuf = NewOutBuffer(&saved_outbuf))==NULL) {
- DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
- /* Free must be done before set.. */
- free_InBuffer(inbuf);
- set_InBuffer(saved_inbuf);
- return False;
+ if (fsp->sent_oplock_break != NO_BREAK_SENT) {
+ /* Remember we have to inform the requesting PID when the
+ * client replies */
+ msg->pid = src;
+ ADD_TO_ARRAY(NULL, struct share_mode_entry, *msg,
+ &fsp->pending_break_messages,
+ &fsp->num_pending_break_messages);
+ return;
}
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- if (local_request) {
- wait_before_sending_break();
+ if (EXCLUSIVE_OPLOCK_TYPE(msg->op_type) &&
+ !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ DEBUG(3, ("Already downgraded oplock on %.0f/%.0f: %s\n",
+ (double)fsp->dev, (double)fsp->inode,
+ fsp->fsp_name));
+ message_send_pid(src, MSG_SMB_BREAK_RESPONSE,
+ msg, sizeof(*msg), True);
+ return;
}
- /* Prepare the SMBlockingX message. */
+ if ((msg_type == MSG_SMB_BREAK_REQUEST) &&
+ (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
+ !koplocks && /* NOTE: we force levelII off for kernel oplocks -
+ * this will change when it is supported */
+ lp_level2_oplocks(SNUM(fsp->conn))) {
+ break_to_level2 = True;
+ }
- if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
- !koplocks && /* NOTE: we force levelII off for kernel oplocks - this will change when it is supported */
- lp_level2_oplocks(SNUM(fsp->conn))) {
- using_levelII = True;
- } else {
- using_levelII = False;
+ break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ?
+ OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
+ if (break_msg == NULL) {
+ exit_server("Could not talloc break_msg\n");
}
- prepare_break_message( outbuf, fsp, using_levelII);
- /* Remember if we just sent a break to level II on this file. */
- fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
+ /* Need to wait before sending a break message to a file of our own */
+ if (procid_to_pid(&src) == sys_getpid()) {
+ wait_before_sending_break();
+ }
/* Save the server smb signing state. */
sign_state = srv_oplock_set_signing(False);
- show_msg(outbuf);
- if (!send_smb(smbd_server_fd(), outbuf)) {
- srv_oplock_set_signing(sign_state);
+ show_msg(break_msg);
+ if (!send_smb(smbd_server_fd(), break_msg)) {
exit_server("oplock_break: send_smb failed.");
}
/* Restore the sign state to what it was. */
srv_oplock_set_signing(sign_state);
- /* We need this in case a readraw crosses on the wire. */
- global_oplock_break = True;
-
- /* Process incoming messages. */
-
- /*
- * JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
- * seconds we should just die....
- */
-
- start_time = time(NULL);
+ talloc_free(break_msg);
- /*
- * Save the information we need to re-become the
- * user, then unbecome the user whilst we're doing this.
- */
- saved_user_conn = current_user.conn;
- saved_vuid = current_user.vuid;
- saved_fsp_conn = fsp->conn;
- /*
- * Initialize saved_dir to something sensible: vfs_GetWd may not work well
- * for root: the directory may be NFS-mounted and exported with root_squash
- * (so has no root access).
- */
- pstrcpy(saved_dir,saved_fsp_conn->connectpath);
- vfs_GetWd(saved_fsp_conn,saved_dir);
- /* Save the chain fnum. */
- file_chain_save();
-
- pstrcpy(file_name, fsp->fsp_name);
-
- change_to_root_user();
-
- /*
- * From Charles Hoch <hoch@exemplary.com>. If the break processing
- * code closes the file (as it often does), then the fsp pointer here
- * points to free()'d memory. We *must* revalidate fsp each time
- * around the loop. With async I/O, write calls may steal the global InBuffer,
- * so ensure we're using the correct one each time around the loop.
- */
-
- while((fsp = initial_break_processing(dev, inode, file_id)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
-
- inbuf = get_InBuffer();
- outbuf = get_OutBuffer();
-
- if(receive_smb(smbd_server_fd(),inbuf, timeout) == False) {
- /*
- * Die if we got an error.
- */
-
- if (smb_read_error == READ_EOF) {
- DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
- shutdown_server = True;
- } else if (smb_read_error == READ_ERROR) {
- DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
- shutdown_server = True;
- } else if (smb_read_error == READ_BAD_SIG) {
- DEBUG( 0, ("oplock_break: bad signature from client\n" ));
- shutdown_server = True;
- } else if (smb_read_error == READ_TIMEOUT) {
- DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n", OPLOCK_BREAK_TIMEOUT ) );
- oplock_timeout = True;
- }
-
- DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
- DEBUGADD( 0, ( "(dev = %x, inode = %.0f, file_id = %lu).\n",
- (unsigned int)dev, (double)inode, file_id));
+ if (msg_type == MSG_SMB_BREAK_REQUEST) {
+ fsp->sent_oplock_break = break_to_level2 ?
+ LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
+ } else {
+ /* Async level2 request, don't send a reply */
+ fsp->sent_oplock_break = ASYNC_LEVEL_II_BREAK_SENT;
+ }
+ msg->pid = src;
+ ADD_TO_ARRAY(NULL, struct share_mode_entry, *msg,
+ &fsp->pending_break_messages,
+ &fsp->num_pending_break_messages);
- break;
- }
+ if (fsp->oplock_timeout != NULL) {
+ DEBUG(0, ("Logic problem -- have an oplock event hanging "
+ "around\n"));
+ }
- /*
- * There are certain SMB requests that we shouldn't allow
- * to recurse. opens, renames and deletes are the obvious
- * ones. This is handled in the switch_message() function.
- * If global_oplock_break is set they will push the packet onto
- * the pending smb queue and return -1 (no reply).
- * JRA.
- */
+ fsp->oplock_timeout =
+ add_timed_event(NULL,
+ timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
+ "oplock_timeout_handler",
+ oplock_timeout_handler, fsp);
- process_smb(inbuf, outbuf);
+ if (fsp->oplock_timeout == NULL) {
+ DEBUG(0, ("Could not add oplock timeout handler\n"));
+ }
+}
- /*
- * Die if we go over the time limit.
- */
+static void process_kernel_oplock_break(int msg_type, struct process_id src,
+ void *buf, size_t len)
+{
+ struct kernel_oplock_message *msg = buf;
+ files_struct *fsp;
+ char *break_msg;
+ BOOL sign_state;
- if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "oplock_break: no break received from client " );
- dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
- dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
- dbgtext( "(dev = %x, inode = %.0f, file_id = %lu).\n",
- (unsigned int)dev, (double)inode, file_id );
- }
- oplock_timeout = True;
- break;
- }
+ if (buf == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
+ return;
}
- /*
- * Go back to being the user who requested the oplock
- * break.
- */
- if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !change_to_user(saved_user_conn, saved_vuid)) {
- DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
- DEBUGADD( 0, ( "Shutting down server\n" ) );
- close(oplock_sock);
- exit_server("unable to re-become user");
+ if (len != sizeof(*msg)) {
+ DEBUG(0, ("Got invalid msg len %d\n", (int)len));
+ return;
}
- /* Including the directory. */
- vfs_ChDir(saved_fsp_conn,saved_dir);
-
- /* Restore the chain fnum. */
- file_chain_restore();
+ DEBUG(10, ("Got kernel oplock break message from pid %d: %d/%d/%d\n",
+ (int)procid_to_pid(&src), (int)msg->dev, (int)msg->inode,
+ (int)msg->file_id));
- /* Free the buffers we've been using to recurse. */
- /* Free must be done before set.. */
- free_InBuffer(inbuf);
- free_OutBuffer(outbuf);
+ fsp = initial_break_processing(msg->dev, msg->inode, msg->file_id);
- /* Restore the global In/Out buffers. */
- set_InBuffer(saved_inbuf);
- set_OutBuffer(saved_outbuf);
-
- /* We need this in case a readraw crossed on the wire. */
- if(global_oplock_break)
- global_oplock_break = False;
-
- /*
- * If the client timed out then clear the oplock (or go to level II)
- * and continue. This seems to be what NT does and is better than dropping
- * the connection.
- */
-
- if(oplock_timeout && (fsp = initial_break_processing(dev, inode, file_id)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
- DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
- remove_oplock(fsp,True);
-#if FASCIST_OPLOCK_BACKOFF
- global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
-#endif
+ if (fsp == NULL) {
+ DEBUG(3, ("Got a kernel oplock break message for a file "
+ "I don't know about\n"));
+ return;
}
- /*
- * If the client had an error we must die.
- */
-
- if(shutdown_server) {
- DEBUG( 0, ( "oplock_break: client failure in break - " ) );
- DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
- close(oplock_sock);
- exit_server("oplock break failure");
+ if (fsp->sent_oplock_break != NO_BREAK_SENT) {
+ /* This is ok, kernel oplocks come in completely async */
+ DEBUG(3, ("Got a kernel oplock request while waiting for a "
+ "break reply\n"));
+ return;
}
- /* Santity check - remove this later. JRA */
- if(exclusive_oplocks_open < 0) {
- DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n", exclusive_oplocks_open));
- abort();
+ break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
+ if (break_msg == NULL) {
+ exit_server("Could not talloc break_msg\n");
}
- /* We know we have no saved errors here. */
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ /* Save the server smb signing state. */
+ sign_state = srv_oplock_set_signing(False);
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "oplock_break: returning success for " );
- dbgtext( "dev = %x, inode = %.0f, file_id = %lu\n", (unsigned int)dev, (double)inode, file_id );
- dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
+ show_msg(break_msg);
+ if (!send_smb(smbd_server_fd(), break_msg)) {
+ exit_server("oplock_break: send_smb failed.");
}
- return True;
-}
-
-/****************************************************************************
- Send an oplock break message to another smbd process. If the oplock is held
- by the local smbd then call the oplock break function directly.
- This function is called with no share locks held.
-****************************************************************************/
+ /* Restore the sign state to what it was. */
+ srv_oplock_set_signing(sign_state);
-BOOL request_oplock_break(share_mode_entry *share_entry)
-{
- char op_break_msg[OPLOCK_BREAK_MSG_LEN];
- struct sockaddr_in addr_out;
- pid_t pid = sys_getpid();
- time_t start_time;
- int time_left;
- SMB_DEV_T dev = share_entry->dev;
- SMB_INO_T inode = share_entry->inode;
- unsigned long file_id = share_entry->share_file_id;
- uint16 break_cmd_type;
-
- if(pid == share_entry->pid) {
- /* We are breaking our own oplock, make sure it's us. */
- if(share_entry->op_port != global_oplock_port) {
- DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
- return False;
- }
+ talloc_free(break_msg);
- DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
+ fsp->sent_oplock_break = BREAK_TO_NONE_SENT;
+}
-#if 1 /* JRA PARANOIA TEST.... */
- {
- files_struct *fsp = file_find_dif(dev, inode, file_id);
- if (!fsp) {
- DEBUG(0,("request_oplock_break: PANIC : breaking our own oplock requested for \
-dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
- (unsigned int)dev, (double)inode, file_id ));
- smb_panic("request_oplock_break: no fsp found for our own oplock\n");
- }
- }
-#endif /* END JRA PARANOIA TEST... */
+void reply_to_oplock_break_requests(files_struct *fsp)
+{
+ int i;
- /* Call oplock break direct. */
- return oplock_break(dev, inode, file_id, True);
+ for (i=0; i<fsp->num_pending_break_messages; i++) {
+ struct share_mode_entry *msg = &fsp->pending_break_messages[i];
+ message_send_pid(msg->pid, MSG_SMB_BREAK_RESPONSE,
+ msg, sizeof(*msg), True);
}
- /* We need to send a OPLOCK_BREAK_CMD message to the port in the share mode entry. */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- break_cmd_type = LEVEL_II_OPLOCK_BREAK_CMD;
- } else {
- break_cmd_type = OPLOCK_BREAK_CMD;
+ SAFE_FREE(fsp->pending_break_messages);
+ fsp->num_pending_break_messages = 0;
+ if (fsp->oplock_timeout != NULL) {
+ talloc_free(fsp->oplock_timeout);
+ fsp->oplock_timeout = NULL;
}
+ return;
+}
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,break_cmd_type);
- memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
- memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
- memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
- memcpy(op_break_msg+OPLOCK_BREAK_FILEID_OFFSET,(char *)&file_id,sizeof(file_id));
-
- /* Set the address and port. */
- memset((char *)&addr_out,'\0',sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( share_entry->op_port );
- addr_out.sin_family = AF_INET;
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "request_oplock_break: sending a synchronous oplock break message to " );
- dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
- }
+static void process_oplock_break_response(int msg_type, struct process_id src,
+ void *buf, size_t len)
+{
+ struct share_mode_entry *msg = buf;
- if(sys_sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "request_oplock_break: failed when sending a oplock " );
- dbgtext( "break message to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
- dbgtext( "Error was %s\n", strerror(errno) );
- }
- return False;
+ if (buf == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
+ return;
}
- /*
- * Now we must await the oplock broken message coming back
- * from the target smbd process. Timeout if it fails to
- * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
- * While we get messages that aren't ours, loop.
- */
-
- start_time = time(NULL);
- time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
-
- while(time_left >= 0) {
- char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
- uint16 reply_from_port;
- char *reply_msg_start;
-
- if(receive_local_message(op_break_reply, sizeof(op_break_reply),
- time_left ? time_left * 1000 : 1) == False) {
- if(smb_read_error == READ_TIMEOUT) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "request_oplock_break: no response received to oplock " );
- dbgtext( "break request to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
- }
-
- /*
- * This is a hack to make handling of failing clients more robust.
- * If a oplock break response message is not received in the timeout
- * period we may assume that the smbd servicing that client holding
- * the oplock has died and the client changes were lost anyway, so
- * we should continue to try and open the file.
- */
- break;
- } else {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "request_oplock_break: error in response received " );
- dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
- dbgtext( "Error was (%s).\n", strerror(errno) );
- }
- }
- return False;
- }
-
- reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
- reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
-
- /*
- * Test to see if this is the reply we are awaiting (ie. the one we sent with the CMD_REPLY flag OR'ed in).
- */
- if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
- ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == break_cmd_type) &&
- (reply_from_port == share_entry->op_port) &&
- (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
- OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0)) {
-
- /*
- * This is the reply we've been waiting for.
- */
- break;
- } else {
- /*
- * This is another message - a break request.
- * Note that both kernel oplock break requests
- * and UDP inter-smbd oplock break requests will
- * be processed here.
- *
- * Process it to prevent potential deadlock.
- * Note that the code in switch_message() prevents
- * us from recursing into here as any SMB requests
- * we might process that would cause another oplock
- * break request to be made will be queued.
- * JRA.
- */
-
- process_local_message(op_break_reply, sizeof(op_break_reply));
- }
-
- time_left -= (time(NULL) - start_time);
+ if (len != sizeof(*msg)) {
+ DEBUG(0, ("Got invalid msg len %d\n", (int)len));
+ return;
}
- DEBUG(3,("request_oplock_break: broke oplock.\n"));
+ DEBUG(10, ("Got oplock break response from pid %d: %d/%d/%d mid %d\n",
+ (int)procid_to_pid(&src), (int)msg->dev, (int)msg->inode,
+ (int)msg->share_file_id, (int)msg->op_mid));
- return True;
+ /* Here's the hack from open.c, store the mid in the 'port' field */
+ schedule_deferred_open_smb_message(msg->op_mid);
}
-/****************************************************************************
- Attempt to break an oplock on a file (if oplocked).
- Returns True if the file was closed as a result of
- the oplock break, False otherwise.
- Used as a last ditch attempt to free a space in the
- file table when we have run out.
-****************************************************************************/
-
-BOOL attempt_close_oplocked_file(files_struct *fsp)
+static void process_open_retry_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
- DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
-
- if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fh->fd != -1)) {
- /* Try and break the oplock. */
- if (oplock_break(fsp->dev, fsp->inode, fsp->file_id, True)) {
- if(file_find_fsp(fsp) == NULL) /* Did the oplock break close the file ? */
- return True;
- }
+ struct share_mode_entry *msg = buf;
+
+ if (buf == NULL) {
+ DEBUG(0, ("Got NULL buffer\n"));
+ return;
}
- return False;
-}
-
-/****************************************************************************
- Send an asynchronous oplock break message to another smbd process.
-****************************************************************************/
-
-static BOOL request_remote_level2_async_oplock_break(share_mode_entry *share_entry)
-{
- char op_break_msg[OPLOCK_BREAK_MSG_LEN];
- struct sockaddr_in addr_out;
- pid_t pid = sys_getpid();
- SMB_DEV_T dev = share_entry->dev;
- SMB_INO_T inode = share_entry->inode;
- unsigned long file_id = share_entry->share_file_id;
-
- /* We need to send a ASYNC_LEVEL_II_OPLOCK_BREAK_CMD message to the port in the share mode entry. */
-
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,ASYNC_LEVEL_II_OPLOCK_BREAK_CMD);
- memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
- memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
- memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
- memcpy(op_break_msg+OPLOCK_BREAK_FILEID_OFFSET,(char *)&file_id,sizeof(file_id));
-
- /* Set the address and port. */
- memset((char *)&addr_out,'\0',sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( share_entry->op_port );
- addr_out.sin_family = AF_INET;
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "request_remote_level2_async_oplock_break: sending an asynchronous oplock break message to ");
- dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
+ if (len != sizeof(*msg)) {
+ DEBUG(0, ("Got invalid msg len %d\n", (int)len));
+ return;
}
- if(sys_sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "request_remote_level2_async_oplock_break: failed when sending a oplock " );
- dbgtext( "break message to pid %d ", (int)share_entry->pid );
- dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)dev, (double)inode, file_id );
- dbgtext( "Error was %s\n", strerror(errno) );
- }
- return False;
- }
+ DEBUG(10, ("Got open retry msg from pid %d: %d/%d mid %d\n",
+ (int)procid_to_pid(&src), (int)msg->dev, (int)msg->inode,
+ (int)msg->op_mid));
- DEBUG(3,("request_remote_level2_async_oplock_break: sent async break message to level II entry.\n"));
- return True;
+ schedule_deferred_open_smb_message(msg->op_mid);
}
/****************************************************************************
This function is called on any file modification or lock request. If a file
- is level 2 oplocked then it must tell all other level 2 holders to break to none.
+ is level 2 oplocked then it must tell all other level 2 holders to break to
+ none.
****************************************************************************/
void release_level_2_oplocks_on_change(files_struct *fsp)
{
- share_mode_entry *share_list = NULL;
- pid_t pid = sys_getpid();
- int num_share_modes = 0;
int i;
- BOOL dummy;
+ struct share_mode_lock *lck;
/*
* If this file is level II oplocked then we need
@@ -1247,125 +627,71 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
return;
- if (lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("release_level_2_oplocks_on_change: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
+ if (lck == NULL) {
+ DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
+ "share mode entry for file %s.\n", fsp->fsp_name ));
}
- num_share_modes = get_share_modes(fsp->dev, fsp->inode, &share_list,
- &dummy);
-
DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
- num_share_modes ));
+ lck->num_share_modes ));
+
+ if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
+ /* See if someone else has already downgraded us, then we
+ don't have to do anything */
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if ((e->op_type == NO_OPLOCK) &&
+ (e->share_file_id == fsp->file_id) &&
+ (e->dev == fsp->dev) &&
+ (e->inode == fsp->inode) &&
+ (procid_is_me(&e->pid))) {
+ /* We're done */
+ fsp->oplock_type = NO_OPLOCK;
+ talloc_free(lck);
+ return;
+ }
+ }
+ }
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &share_list[i];
+ for(i = 0; i < lck->num_share_modes; i++) {
+ struct share_mode_entry *share_entry = &lck->share_modes[i];
/*
- * As there could have been multiple writes waiting at the lock_share_entry
- * gate we may not be the first to enter. Hence the state of the op_types
- * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II
- * oplock. It will do no harm to re-send break messages to those smbd's
- * that are still waiting their turn to remove their LEVEL_II state, and
- * also no harm to ignore existing NO_OPLOCK states. JRA.
+ * As there could have been multiple writes waiting at the
+ * lock_share_entry gate we may not be the first to
+ * enter. Hence the state of the op_types in the share mode
+ * entries may be partly NO_OPLOCK and partly LEVEL_II
+ * oplock. It will do no harm to re-send break messages to
+ * those smbd's that are still waiting their turn to remove
+ * their LEVEL_II state, and also no harm to ignore existing
+ * NO_OPLOCK states. JRA.
*/
- DEBUG(10,("release_level_2_oplocks_on_change: share_entry[%i]->op_type == %d\n",
- i, share_entry->op_type ));
+ DEBUG(10,("release_level_2_oplocks_on_change: "
+ "share_entry[%i]->op_type == %d\n",
+ i, share_entry->op_type ));
- if (share_entry->op_type == NO_OPLOCK)
+ if ((share_entry->op_type == NO_OPLOCK) ||
+ (share_entry->op_type == FAKE_LEVEL_II_OPLOCK)) {
continue;
+ }
/* Paranoia .... */
if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
- DEBUG(0,("release_level_2_oplocks_on_change: PANIC. share mode entry %d is an exlusive oplock !\n", i ));
- unlock_share_entry(fsp->conn, fsp->dev, fsp->inode);
+ DEBUG(0,("release_level_2_oplocks_on_change: PANIC. "
+ "share mode entry %d is an exlusive "
+ "oplock !\n", i ));
+ talloc_free(lck);
abort();
}
- /*
- * Check if this is a file we have open (including the
- * file we've been called to do write_file on. If so
- * then break it directly without releasing the lock.
- */
-
- if (pid == share_entry->pid) {
- files_struct *new_fsp = file_find_dif(share_entry->dev, share_entry->inode, share_entry->share_file_id);
-
- /* Paranoia check... */
- if(new_fsp == NULL) {
- DEBUG(0,("release_level_2_oplocks_on_change: PANIC. share mode entry %d is not a local file !\n", i ));
- unlock_share_entry(fsp->conn, fsp->dev, fsp->inode);
- abort();
- }
-
- DEBUG(10,("release_level_2_oplocks_on_change: breaking our own oplock.\n"));
-
- oplock_break_level2(new_fsp, True);
-
- } else {
-
- /*
- * This is a remote file and so we send an asynchronous
- * message.
- */
-
- DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock (async).\n"));
- request_remote_level2_async_oplock_break(share_entry);
- }
- }
-
- SAFE_FREE(share_list);
- unlock_share_entry_fsp(fsp);
-
- /* Paranoia check... */
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
- DEBUG(0,("release_level_2_oplocks_on_change: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
- smb_panic("release_level_2_oplocks_on_change");
- }
-}
-
-/****************************************************************************
- Send a 'retry your open' message to a process with a deferred open entry.
-****************************************************************************/
-
-BOOL send_deferred_open_retry_message(deferred_open_entry *entry)
-{
- char de_msg[DEFERRED_OPEN_MSG_LEN];
- struct sockaddr_in addr_out;
- pid_t pid = sys_getpid();
-
- memset(de_msg, '\0', DEFERRED_OPEN_MSG_LEN);
- SSVAL(de_msg,DEFERRED_OPEN_CMD_OFFSET,RETRY_DEFERRED_OPEN_CMD);
- memcpy(de_msg+DEFERRED_OPEN_PID_OFFSET,(char *)&pid,sizeof(pid));
- memcpy(de_msg+DEFERRED_OPEN_DEV_OFFSET,(char *)&entry->dev,sizeof(entry->dev));
- memcpy(de_msg+DEFERRED_OPEN_INODE_OFFSET,(char *)&entry->inode,sizeof(entry->inode));
- memcpy(de_msg+DEFERRED_OPEN_MID_OFFSET,(char *)&entry->mid,sizeof(entry->mid));
-
- /* Set the address and port. */
- memset((char *)&addr_out,'\0',sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( entry->port );
- addr_out.sin_family = AF_INET;
-
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "send_deferred_open_retry_message: sending a message to ");
- dbgtext( "pid %d on port %d ", (int)entry->pid, entry->port );
- dbgtext( "for dev = %x, inode = %.0f, mid = %u\n",
- (unsigned int)entry->dev, (double)entry->inode, (unsigned int)entry->mid );
+ message_send_pid(share_entry->pid, MSG_SMB_ASYNC_LEVEL2_BREAK,
+ share_entry, sizeof(*share_entry), True);
}
- if(sys_sendto(oplock_sock,de_msg,DEFERRED_OPEN_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "send_deferred_open_retry_message: failed sending a message to ");
- dbgtext( "pid %d on port %d ", (int)entry->pid, entry->port );
- dbgtext( "for dev = %x, inode = %.0f, mid = %u\n",
- (unsigned int)entry->dev, (double)entry->inode, (unsigned int)entry->mid );
- dbgtext( "Error was %s\n", strerror(errno) );
- }
- return False;
- }
- return True;
+ remove_all_share_oplocks(lck, fsp);
+ talloc_free(lck);
}
/****************************************************************************
@@ -1374,30 +700,18 @@ BOOL send_deferred_open_retry_message(deferred_open_entry *entry)
BOOL init_oplocks(void)
{
- struct sockaddr_in sock_name;
- socklen_t len = sizeof(sock_name);
-
DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
- /* Open a lookback UDP socket on a random port. */
- oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK),False);
- if (oplock_sock == -1) {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
- global_oplock_port = 0;
- return(False);
- }
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0) {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(oplock_sock);
- oplock_sock = -1;
- global_oplock_port = 0;
- return False;
- }
- global_oplock_port = ntohs(sock_name.sin_port);
+ message_register(MSG_SMB_BREAK_REQUEST,
+ process_oplock_break_message);
+ message_register(MSG_SMB_ASYNC_LEVEL2_BREAK,
+ process_oplock_break_message);
+ message_register(MSG_SMB_BREAK_RESPONSE,
+ process_oplock_break_response);
+ message_register(MSG_SMB_KERNEL_BREAK,
+ process_kernel_oplock_break);
+ message_register(MSG_SMB_OPEN_RETRY,
+ process_open_retry_message);
if (lp_kernel_oplocks()) {
#if HAVE_KERNEL_OPLOCKS_IRIX
@@ -1407,8 +721,5 @@ address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
#endif
}
- DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
- (int)sys_getpid(), global_oplock_port));
-
return True;
}
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index f4405a021e..f49aa297e4 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -86,7 +86,7 @@ Disabling kernel oplock support.\n", strerror(errno) ));
* oplock break protocol.
****************************************************************************/
-static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
+static files_struct *irix_oplock_receive_message(fd_set *fds)
{
extern int smb_read_error;
oplock_stat_t os;
@@ -102,7 +102,7 @@ static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_le
DEBUG(0,("irix_oplock_receive_message: read of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR;
- return False;
+ return NULL;
}
/*
@@ -122,7 +122,7 @@ Error was %s.\n", strerror(errno) ));
return True;
}
smb_read_error = READ_ERROR;
- return False;
+ return NULL;
}
/*
@@ -138,24 +138,8 @@ Error was %s.\n", strerror(errno) ));
DEBUG(5,("irix_oplock_receive_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
-
- /*
- * Create a kernel oplock break message.
- */
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
-
- buffer += OPBRK_CMD_HEADER_LEN;
-
- SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
-
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
-
- return True;
+
+ return fsp;
}
/****************************************************************************
@@ -215,30 +199,6 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
}
/****************************************************************************
- Parse a kernel oplock message.
-****************************************************************************/
-
-static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len,
- SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id)
-{
- /* Ensure that the msg length is correct. */
- if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %d).\n",
- msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
- memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
- memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
-
- DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n",
- (unsigned int)*dev, (double)*inode, *file_id));
-
- return True;
-}
-
-/****************************************************************************
Set *maxfd to include oplock read pipe.
****************************************************************************/
@@ -274,7 +234,6 @@ struct kernel_oplocks *irix_init_kernel_oplocks(void)
koplocks.receive_message = irix_oplock_receive_message;
koplocks.set_oplock = irix_set_kernel_oplock;
koplocks.release_oplock = irix_release_kernel_oplock;
- koplocks.parse_message = irix_kernel_oplock_parse;
koplocks.msg_waiting = irix_oplock_msg_waiting;
koplocks.notification_fd = oplock_pipe_read;
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 477832c6e8..ab0c08f7fc 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -128,10 +128,10 @@ static int linux_setlease(int fd, int leasetype)
* oplock break protocol.
****************************************************************************/
-static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
+static files_struct *linux_oplock_receive_message(fd_set *fds)
{
int fd;
- struct files_struct *fsp;
+ files_struct *fsp;
BlockSignals(True, RT_SIGNAL_LEASE);
fd = fd_pending_array[0];
@@ -145,32 +145,7 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l
/* now we can receive more signals */
BlockSignals(False, RT_SIGNAL_LEASE);
- if (fsp == NULL) {
- DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd));
- return False;
- }
-
- DEBUG(3,("linux_oplock_receive_message: kernel oplock break request received for \
-dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (double)fsp->inode,
- fd, fsp->file_id));
-
- /*
- * Create a kernel oplock break message.
- */
-
- /* Setup the message header */
- SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
- SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
-
- buffer += OPBRK_CMD_HEADER_LEN;
-
- SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
-
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
-
- return True;
+ return fsp;
}
/****************************************************************************
@@ -224,30 +199,6 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
}
/****************************************************************************
- Parse a kernel oplock message.
-****************************************************************************/
-
-static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *inode,
- SMB_DEV_T *dev, unsigned long *file_id)
-{
- /* Ensure that the msg length is correct. */
- if (msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
- DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %lu).\n",
- msg_len, (unsigned long)KERNEL_OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
- memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
- memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
-
- DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %lu\n",
- (unsigned int)*dev, (double)*inode, *file_id));
-
- return True;
-}
-
-/****************************************************************************
See if a oplock message is waiting.
****************************************************************************/
@@ -299,7 +250,6 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void)
koplocks.receive_message = linux_oplock_receive_message;
koplocks.set_oplock = linux_set_kernel_oplock;
koplocks.release_oplock = linux_release_kernel_oplock;
- koplocks.parse_message = linux_kernel_oplock_parse;
koplocks.msg_waiting = linux_oplock_msg_waiting;
koplocks.notification_fd = -1;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 8f9cc52882..0b7b94cce2 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
process incoming packets - main loop
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,12 +45,11 @@ int max_send = BUFFER_SIZE;
int max_recv = BUFFER_SIZE;
extern int last_message;
-extern int global_oplock_break;
extern userdom_struct current_user_info;
extern int smb_read_error;
SIG_ATOMIC_T reload_after_sighup = 0;
SIG_ATOMIC_T got_sig_term = 0;
-BOOL global_machine_password_needs_changing = False;
+extern BOOL global_machine_password_needs_changing;
extern int max_send;
/****************************************************************************
@@ -66,106 +66,72 @@ uint16 get_current_mid(void)
for processing.
****************************************************************************/
-static struct pending_message_list *smb_oplock_queue;
-static struct pending_message_list *smb_sharing_violation_queue;
-
-enum q_type { OPLOCK_QUEUE, SHARE_VIOLATION_QUEUE };
-
-/****************************************************************************
- Free up a message.
-****************************************************************************/
-
-static void free_queued_message(struct pending_message_list *msg)
-{
- data_blob_free(&msg->buf);
- data_blob_free(&msg->private_data);
- SAFE_FREE(msg);
-}
+static struct pending_message_list *deferred_open_queue;
/****************************************************************************
Function to push a message onto the tail of a linked list of smb messages ready
for processing.
****************************************************************************/
-static BOOL push_queued_message(enum q_type qt, char *buf, int msg_len, struct timeval *ptv, char *private_data, size_t private_len)
+static BOOL push_queued_message(char *buf, int msg_len,
+ struct timeval request_time,
+ struct timeval end_time,
+ char *private_data, size_t private_len)
{
struct pending_message_list *tmp_msg;
- struct pending_message_list *msg = SMB_MALLOC_P(struct pending_message_list);
+ struct pending_message_list *msg;
+
+ msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
if(msg == NULL) {
DEBUG(0,("push_message: malloc fail (1)\n"));
return False;
}
- memset(msg,'\0',sizeof(*msg));
-
- msg->buf = data_blob(buf, msg_len);
+ msg->buf = data_blob_talloc(msg, buf, msg_len);
if(msg->buf.data == NULL) {
DEBUG(0,("push_message: malloc fail (2)\n"));
- SAFE_FREE(msg);
+ talloc_free(msg);
return False;
}
- if (ptv) {
- msg->msg_time = *ptv;
- }
+ msg->request_time = request_time;
+ msg->end_time = end_time;
if (private_data) {
- msg->private_data = data_blob(private_data, private_len);
+ msg->private_data = data_blob_talloc(msg, private_data,
+ private_len);
if (msg->private_data.data == NULL) {
DEBUG(0,("push_message: malloc fail (3)\n"));
- data_blob_free(&msg->buf);
- SAFE_FREE(msg);
+ talloc_free(msg);
return False;
}
}
- if (qt == OPLOCK_QUEUE) {
- DLIST_ADD_END(smb_oplock_queue, msg, tmp_msg);
- } else {
- DLIST_ADD_END(smb_sharing_violation_queue, msg, tmp_msg);
- }
+ DLIST_ADD_END(deferred_open_queue, msg, tmp_msg);
- DEBUG(10,("push_message: pushed message length %u on queue %s\n",
- (unsigned int)msg_len,
- qt == OPLOCK_QUEUE ? "smb_oplock_queue" : "smb_sharing_violation_queue" ));
+ DEBUG(10,("push_message: pushed message length %u on "
+ "deferred_open_queue\n", (unsigned int)msg_len));
return True;
}
/****************************************************************************
- Function to push an oplock smb message onto a linked list of local smb messages ready
- for processing.
-****************************************************************************/
-
-BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
-{
- BOOL ret = push_queued_message(OPLOCK_QUEUE, buf, msg_len, NULL, NULL, 0);
- if (ret) {
- /* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(buf,smb_mid));
- }
- return ret;
-}
-
-/****************************************************************************
Function to delete a sharing violation open message by mid.
****************************************************************************/
-void remove_sharing_violation_open_smb_message(uint16 mid)
+void remove_deferred_open_smb_message(uint16 mid)
{
struct pending_message_list *pml;
- if (!lp_defer_sharing_violations()) {
- return;
- }
-
- for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
+ for (pml = deferred_open_queue; pml; pml = pml->next) {
if (mid == SVAL(pml->buf.data,smb_mid)) {
- DEBUG(10,("remove_sharing_violation_open_smb_message: deleting mid %u len %u\n",
- (unsigned int)mid, (unsigned int)pml->buf.length ));
- DLIST_REMOVE(smb_sharing_violation_queue, pml);
- free_queued_message(pml);
+ DEBUG(10,("remove_sharing_violation_open_smb_message: "
+ "deleting mid %u len %u\n",
+ (unsigned int)mid,
+ (unsigned int)pml->buf.length ));
+ DLIST_REMOVE(deferred_open_queue, pml);
+ talloc_free(pml);
return;
}
}
@@ -176,30 +142,26 @@ void remove_sharing_violation_open_smb_message(uint16 mid)
schedule it for immediate processing.
****************************************************************************/
-void schedule_sharing_violation_open_smb_message(uint16 mid)
+void schedule_deferred_open_smb_message(uint16 mid)
{
struct pending_message_list *pml;
int i = 0;
- if (!lp_defer_sharing_violations()) {
- return;
- }
-
- for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
+ for (pml = deferred_open_queue; pml; pml = pml->next) {
uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
- DEBUG(10,("schedule_sharing_violation_open_smb_message: [%d] msg_mid = %u\n", i++,
+ DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
(unsigned int)msg_mid ));
if (mid == msg_mid) {
- DEBUG(10,("schedule_sharing_violation_open_smb_message: scheduling mid %u\n",
+ DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
mid ));
- pml->msg_time.tv_sec = 0;
- pml->msg_time.tv_usec = 0;
- DLIST_PROMOTE(smb_sharing_violation_queue, pml);
+ pml->end_time.tv_sec = 0;
+ pml->end_time.tv_usec = 0;
+ DLIST_PROMOTE(deferred_open_queue, pml);
return;
}
}
- DEBUG(10,("schedule_sharing_violation_open_smb_message: failed to find message mid %u\n",
+ DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
mid ));
}
@@ -211,13 +173,9 @@ BOOL open_was_deferred(uint16 mid)
{
struct pending_message_list *pml;
- if (!lp_defer_sharing_violations()) {
- return False;
- }
-
- for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
+ for (pml = deferred_open_queue; pml; pml = pml->next) {
if (SVAL(pml->buf.data,smb_mid) == mid) {
- set_saved_error_triple(SMB_SUCCESS, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return True;
}
}
@@ -232,11 +190,7 @@ struct pending_message_list *get_open_deferred_message(uint16 mid)
{
struct pending_message_list *pml;
- if (!lp_defer_sharing_violations()) {
- return NULL;
- }
-
- for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
+ for (pml = deferred_open_queue; pml; pml = pml->next) {
if (SVAL(pml->buf.data,smb_mid) == mid) {
return pml;
}
@@ -245,57 +199,216 @@ struct pending_message_list *get_open_deferred_message(uint16 mid)
}
/****************************************************************************
- Function to push a sharing violation open smb message onto a linked list of local smb messages ready
- for processing. We must use current_inbuf here not Inbuf in case we're in a chained message set.
+ Function to push a deferred open smb message onto a linked list of local smb
+ messages ready for processing.
+****************************************************************************/
+
+BOOL push_deferred_smb_message(uint16 mid,
+ struct timeval request_time,
+ struct timeval timeout,
+ char *private_data, size_t priv_len)
+{
+ struct timeval end_time;
+
+ end_time = timeval_sum(&request_time, &timeout);
+
+ DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
+ "timeout time [%u.%06u]\n",
+ (unsigned int) smb_len(current_inbuf)+4, (unsigned int)mid,
+ (unsigned int)end_time.tv_sec,
+ (unsigned int)end_time.tv_usec));
+
+ return push_queued_message(current_inbuf, smb_len(current_inbuf)+4,
+ request_time, end_time,
+ private_data, priv_len);
+}
+
+static struct timed_event *timed_events;
+
+struct timed_event {
+ struct timed_event *next, *prev;
+ struct timeval when;
+ const char *event_name;
+ void (*handler)(struct timed_event *te,
+ const struct timeval *now,
+ void *private_data);
+ void *private_data;
+};
+
+static int timed_event_destructor(void *p)
+{
+ struct timed_event *te = talloc_get_type_abort(p, struct timed_event);
+ DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
+ te->event_name));
+ DLIST_REMOVE(timed_events, te);
+ return 0;
+}
+
+/****************************************************************************
+ Schedule a function for future calling, cancel with talloc_free().
+ It's the responsibility of the handler to call talloc_free() on the event
+ handed to it.
****************************************************************************/
-BOOL push_sharing_violation_open_smb_message(struct timeval *ptv, char *private_data, size_t priv_len)
+struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
+ struct timeval when,
+ const char *event_name,
+ void (*handler)(struct timed_event *te,
+ const struct timeval *now,
+ void *private_data),
+ void *private_data)
{
- uint16 mid = SVAL(current_inbuf,smb_mid);
- struct timeval tv;
- SMB_BIG_INT tdif;
+ struct timed_event *te, *last_te, *cur_te;
- if (!lp_defer_sharing_violations()) {
- return True;
+ te = TALLOC_P(mem_ctx, struct timed_event);
+ if (te == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
}
- tv = *ptv;
- tdif = tv.tv_sec;
- tdif *= 1000000;
- tdif += tv.tv_usec;
+ te->when = when;
+ te->event_name = event_name;
+ te->handler = handler;
+ te->private_data = private_data;
+
+ /* keep the list ordered */
+ last_te = NULL;
+ for (cur_te = timed_events; cur_te; cur_te = cur_te->next) {
+ /* if the new event comes before the current one break */
+ if (!timeval_is_zero(&cur_te->when) &&
+ timeval_compare(&te->when, &cur_te->when) < 0) {
+ break;
+ }
+ last_te = cur_te;
+ }
- /* Add on the timeout. */
- tdif += SHARING_VIOLATION_USEC_WAIT;
-
- tv.tv_sec = tdif / 1000000;
- tv.tv_usec = tdif % 1000000;
-
- DEBUG(10,("push_sharing_violation_open_smb_message: pushing message len %u mid %u\
- timeout time [%u.%06u]\n", (unsigned int) smb_len(current_inbuf)+4, (unsigned int)mid,
- (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec));
+ DLIST_ADD_AFTER(timed_events, te, last_te);
+ talloc_set_destructor(te, timed_event_destructor);
- return push_queued_message(SHARE_VIOLATION_QUEUE, current_inbuf,
- smb_len(current_inbuf)+4, &tv, private_data, priv_len);
+ DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
+ (unsigned long)te));
+ return te;
}
+static void run_events(void)
+{
+ struct timeval now;
+
+ if (timed_events == NULL) {
+ /* No syscall if there are no events */
+ DEBUG(10, ("run_events: No events\n"));
+ return;
+ }
+
+ GetTimeOfDay(&now);
+
+ if (timeval_compare(&now, &timed_events->when) < 0) {
+ /* Nothing to do yet */
+ DEBUG(10, ("run_events: Nothing to do\n"));
+ return;
+ }
+
+ DEBUG(10, ("Running event \"%s\" %lx\n", timed_events->event_name,
+ (unsigned long)timed_events));
+
+ timed_events->handler(timed_events, &now, timed_events->private_data);
+ return;
+}
+
+struct timeval timed_events_timeout(void)
+{
+ struct timeval now, timeout;
+
+ if (timed_events == NULL) {
+ return timeval_set(SMBD_SELECT_TIMEOUT, 0);
+ }
+
+ now = timeval_current();
+ timeout = timeval_until(&now, &timed_events->when);
+
+ DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)timeout.tv_sec,
+ (int)timeout.tv_usec));
+
+ return timeout;
+}
+
+struct idle_event {
+ struct timed_event *te;
+ struct timeval interval;
+ BOOL (*handler)(const struct timeval *now, void *private_data);
+ void *private_data;
+};
+
+static void idle_event_handler(struct timed_event *te,
+ const struct timeval *now,
+ void *private_data)
+{
+ struct idle_event *event =
+ talloc_get_type_abort(private_data, struct idle_event);
+
+ talloc_free(event->te);
+
+ if (!event->handler(now, event->private_data)) {
+ /* Don't repeat, delete ourselves */
+ talloc_free(event);
+ return;
+ }
+
+ event->te = add_timed_event(event, timeval_sum(now, &event->interval),
+ "idle_event_handler",
+ idle_event_handler, event);
+
+ /* We can't do much but fail here. */
+ SMB_ASSERT(event->te != NULL);
+}
+
+struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
+ struct timeval interval,
+ BOOL (*handler)(const struct timeval *now,
+ void *private_data),
+ void *private_data)
+{
+ struct idle_event *result;
+ struct timeval now = timeval_current();
+
+ result = TALLOC_P(mem_ctx, struct idle_event);
+ if (result == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->interval = interval;
+ result->handler = handler;
+ result->private_data = private_data;
+
+ result->te = add_timed_event(result, timeval_sum(&now, &interval),
+ "idle_event_handler",
+ idle_event_handler, result);
+ if (result->te == NULL) {
+ DEBUG(0, ("add_timed_event failed\n"));
+ talloc_free(result);
+ return NULL;
+ }
+
+ return result;
+}
+
/****************************************************************************
- Do all async processing in here. This includes UDB oplock messages, kernel
- oplock messages, change notify events etc.
+ Do all async processing in here. This includes kernel oplock messages, change
+ notify events etc.
****************************************************************************/
-static void async_processing(char *buffer, int buffer_len)
+static void async_processing(void)
{
DEBUG(10,("async_processing: Doing async processing.\n"));
process_aio_queue();
- /* check for oplock messages (both UDP and kernel) */
- if (receive_local_message(buffer, buffer_len, 1)) {
- process_local_message(buffer, buffer_len);
- }
+ process_kernel_oplocks();
- /* Do the aio check again after receive_local_message as it does a select
- and may have eaten our signal. */
+ /* Do the aio check again after receive_local_message as it does a
+ select and may have eaten our signal. */
+ /* Is this till true? -- vl */
process_aio_queue();
if (got_sig_term) {
@@ -339,17 +452,17 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
{
fd_set fds;
int selrtn;
- struct timeval to;
- struct timeval *pto;
+ struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0);
int maxfd;
smb_read_error = 0;
again:
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
- pto = timeout > 0 ? &to : NULL;
+ if (timeout >= 0) {
+ to.tv_sec = timeout / 1000;
+ to.tv_usec = (timeout % 1000) * 1000;
+ }
/*
* Note that this call must be before processing any SMB
@@ -359,37 +472,21 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
message_dispatch();
/*
- * Check to see if we already have a message on the smb queue.
- * If so - copy and return it.
- */
- if(smb_oplock_queue != NULL) {
- struct pending_message_list *msg = smb_oplock_queue;
- memcpy(buffer, msg->buf.data, MIN(buffer_len, msg->buf.length));
-
- /* Free the message we just copied. */
- DLIST_REMOVE(smb_oplock_queue, msg);
- free_queued_message(msg);
-
- DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
- return True;
- }
-
- /*
* Check to see if we already have a message on the deferred open queue
* and it's time to schedule.
*/
- if(smb_sharing_violation_queue != NULL) {
+ if(deferred_open_queue != NULL) {
BOOL pop_message = False;
- struct pending_message_list *msg = smb_sharing_violation_queue;
+ struct pending_message_list *msg = deferred_open_queue;
- if (msg->msg_time.tv_sec == 0 && msg->msg_time.tv_usec == 0) {
+ if (timeval_is_zero(&msg->end_time)) {
pop_message = True;
} else {
struct timeval tv;
SMB_BIG_INT tdif;
GetTimeOfDay(&tv);
- tdif = usec_time_diff(&msg->msg_time, &tv);
+ tdif = usec_time_diff(&msg->end_time, &tv);
if (tdif <= 0) {
/* Timed out. Schedule...*/
pop_message = True;
@@ -398,9 +495,8 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
/* Make a more accurate select timeout. */
to.tv_sec = tdif / 1000000;
to.tv_usec = tdif % 1000000;
- pto = &to;
DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
- (unsigned int)pto->tv_sec, (unsigned int)pto->tv_usec ));
+ (unsigned int)to.tv_sec, (unsigned int)to.tv_usec ));
}
}
@@ -431,7 +527,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
if (oplock_message_waiting(&fds)) {
DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
- async_processing(buffer, buffer_len);
+ async_processing();
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -439,18 +535,26 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
*/
goto again;
}
+
+ {
+ struct timeval tmp = timed_events_timeout();
+ to = timeval_min(&to, &tmp);
+ if (timeval_is_zero(&to)) {
+ return True;
+ }
+ }
FD_SET(smbd_server_fd(),&fds);
maxfd = setup_oplock_select_set(&fds);
- selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,pto);
+ selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,&to);
/* if we get EINTR then maybe we have received an oplock
signal - treat this as select returning 1. This is ugly, but
is the best we can do until the oplock code knows more about
signals */
if (selrtn == -1 && errno == EINTR) {
- async_processing(buffer, buffer_len);
+ async_processing();
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -479,7 +583,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
*/
if (oplock_message_waiting(&fds)) {
- async_processing(buffer, buffer_len);
+ async_processing();
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -518,8 +622,6 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
void respond_to_all_remaining_local_messages(void)
{
- char buffer[1024];
-
/*
* Assert we have no exclusive open oplocks.
*/
@@ -530,15 +632,7 @@ void respond_to_all_remaining_local_messages(void)
return;
}
- /*
- * Keep doing receive_local_message with a 1 ms timeout until
- * we have no more messages.
- */
-
- while(receive_local_message(buffer, sizeof(buffer), 1)) {
- /* Deal with oplock break requests from other smbd's. */
- process_local_message(buffer, sizeof(buffer));
- }
+ process_kernel_oplocks();
return;
}
@@ -556,8 +650,7 @@ force write permissions on print services.
#define TIME_INIT (1<<2)
#define CAN_IPC (1<<3)
#define AS_GUEST (1<<5)
-#define QUEUE_IN_OPLOCK (1<<6)
-#define DO_CHDIR (1<<7)
+#define DO_CHDIR (1<<6)
/*
define a list of possible SMB messages and their corresponding
@@ -572,19 +665,19 @@ static const struct smb_message_struct {
/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
-/* 0x02 */ { "SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
+/* 0x02 */ { "SMBopen",reply_open,AS_USER },
/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
-/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
-/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
+/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
+/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
/* 0x0a */ { "SMBread",reply_read,AS_USER},
/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
-/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
+/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
/* 0x10 */ { "SMBchkpth",reply_chkpth,AS_USER},
/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
@@ -611,11 +704,11 @@ static const struct smb_message_struct {
/* 0x26 */ { "SMBtranss",NULL,AS_USER | CAN_IPC},
/* 0x27 */ { "SMBioctl",reply_ioctl,0},
/* 0x28 */ { "SMBioctls",NULL,AS_USER},
-/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
-/* 0x2a */ { "SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
+/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
+/* 0x2a */ { "SMBmove",NULL,AS_USER | NEED_WRITE },
/* 0x2b */ { "SMBecho",reply_echo,0},
/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
-/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
+/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
/* 0x30 */ { NULL, NULL, 0 },
@@ -730,12 +823,12 @@ static const struct smb_message_struct {
/* 0x9d */ { NULL, NULL, 0 },
/* 0x9e */ { NULL, NULL, 0 },
/* 0x9f */ { NULL, NULL, 0 },
-/* 0xa0 */ { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
+/* 0xa0 */ { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
/* 0xa1 */ { "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
-/* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
+/* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC },
/* 0xa3 */ { NULL, NULL, 0 },
/* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0 },
-/* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
+/* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE },
/* 0xa6 */ { NULL, NULL, 0 },
/* 0xa7 */ { NULL, NULL, 0 },
/* 0xa8 */ { NULL, NULL, 0 },
@@ -762,7 +855,7 @@ static const struct smb_message_struct {
/* 0xbd */ { NULL, NULL, 0 },
/* 0xbe */ { NULL, NULL, 0 },
/* 0xbf */ { NULL, NULL, 0 },
-/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
+/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
@@ -871,7 +964,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
pid = sys_getpid();
errno = 0;
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
last_message = type;
@@ -900,19 +993,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n",smb_fn_name(type),(int)pid,(unsigned long)conn));
smb_dump(smb_fn_name(type), 1, inbuf, size);
- if(global_oplock_break) {
- if(flags & QUEUE_IN_OPLOCK) {
- /*
- * Queue this message as we are the process of an oplock break.
- */
-
- DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
- DEBUGADD( 2, ( "oplock break state.\n" ) );
-
- push_oplock_pending_smb_message( inbuf, size );
- return -1;
- }
- }
/* Ensure this value is replaced in the incoming packet. */
SSVAL(inbuf,smb_uid,session_tag);
@@ -1289,6 +1369,7 @@ static int setup_select_timeout(void)
select_timeout *= 1000;
t = change_notify_timeout();
+ DEBUG(10, ("change_notify_timeout: %d\n", t));
if (t != -1)
select_timeout = MIN(select_timeout, t*1000);
@@ -1302,7 +1383,7 @@ static int setup_select_timeout(void)
Check if services need reloading.
****************************************************************************/
-void check_reload(int t)
+void check_reload(time_t t)
{
static pid_t mypid = 0;
static time_t last_smb_conf_reload_time = 0;
@@ -1644,6 +1725,8 @@ void smbd_process(void)
num_smbs = 0; /* Reset smb counter. */
}
+ run_events();
+
#if defined(DEVELOPER)
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
#endif
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 5572f47e42..ba22a56cfb 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -30,7 +30,6 @@
extern enum protocol_types Protocol;
extern int max_send;
extern int max_recv;
-extern int global_oplock_break;
unsigned int smb_echo_count = 0;
extern uint32 global_client_caps;
@@ -1779,7 +1778,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
}
/* We need a better way to return NT status codes from open... */
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
fsp = open_file_ntcreate(conn, fname, pst,
DELETE_ACCESS,
@@ -1791,12 +1790,12 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
NULL);
if (!fsp) {
- NTSTATUS ret;
- if (get_saved_error_triple(NULL, NULL, &ret)) {
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ NTSTATUS ret = get_saved_ntstatus();
+ if (!NT_STATUS_IS_OK(ret)) {
+ set_saved_ntstatus(NT_STATUS_OK);
return ret;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
@@ -1860,7 +1859,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
don't do it here as we'll get it wrong. */
/* We need a better way to return NT status codes from open... */
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
fsp = open_file_ntcreate(conn, fname, &sbuf,
DELETE_ACCESS,
@@ -1872,12 +1871,12 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
NULL);
if (!fsp) {
- NTSTATUS ret;
- if (get_saved_error_triple(NULL, NULL, &ret)) {
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ NTSTATUS ret = get_saved_ntstatus();
+ if (!NT_STATUS_IS_OK(ret)) {
+ set_saved_ntstatus(NT_STATUS_OK);
return ret;
}
- set_saved_error_triple(0, 0, NT_STATUS_OK);
+ set_saved_ntstatus(NT_STATUS_OK);
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,False);
@@ -2209,15 +2208,6 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
* return a zero length response here.
*/
- if(global_oplock_break) {
- _smb_setlen(header,0);
- if (write_data(smbd_server_fd(),header,4) != 4)
- fail_readraw();
- DEBUG(5,("readbraw - oplock break finished\n"));
- END_PROFILE(SMBreadbraw);
- return -1;
- }
-
fsp = file_fsp(inbuf,smb_vwv0);
if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
@@ -2298,8 +2288,8 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
nread = 0;
#endif
- DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
- (int)maxcount, (int)mincount, (int)nread ) );
+ DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
+ (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
@@ -3744,7 +3734,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if( is_ntfs_stream_name(directory)) {
DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
END_PROFILE(SMBmkdir);
- return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
+ return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
}
status = mkdir_internal(conn, directory,bad_path);
@@ -5084,7 +5074,8 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma
Reply to a lockingX request.
****************************************************************************/
-int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
+ int length, int bufsize)
{
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
unsigned char locktype = CVAL(inbuf,smb_vwv3);
@@ -5096,7 +5087,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
int32 lock_timeout = IVAL(inbuf,smb_vwv4);
int i;
char *data;
- BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+ BOOL large_file_format =
+ (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
BOOL err;
BOOL my_lock_ctx = False;
NTSTATUS status;
@@ -5125,19 +5117,25 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE)) {
/* Client can insist on breaking to none. */
BOOL break_to_none = (oplocklevel == 0);
-
- DEBUG(5,("reply_lockingX: oplock break reply (%u) from client for fnum = %d\n",
- (unsigned int)oplocklevel, fsp->fnum ));
+ BOOL result;
+
+ DEBUG(5,("reply_lockingX: oplock break reply (%u) from client "
+ "for fnum = %d\n", (unsigned int)oplocklevel,
+ fsp->fnum ));
/*
- * Make sure we have granted an exclusive or batch oplock on this file.
+ * Make sure we have granted an exclusive or batch oplock on
+ * this file.
*/
- if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
- DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
-
- /* if this is a pure oplock break request then don't send a reply */
+ if (fsp->oplock_type == 0) {
+ DEBUG(0,("reply_lockingX: Error : oplock break from "
+ "client for fnum = %d (oplock=%d) and no "
+ "oplock granted on this file (%s).\n",
+ fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+
+ /* if this is a pure oplock break request then don't
+ * send a reply */
if (num_locks == 0 && num_ulocks == 0) {
END_PROFILE(SMBlockingX);
return -1;
@@ -5147,17 +5145,30 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
}
}
- if (remove_oplock(fsp, break_to_none) == False) {
- DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
- fsp->fsp_name ));
+ if ((fsp->sent_oplock_break == BREAK_TO_NONE_SENT) ||
+ (break_to_none)) {
+ result = remove_oplock(fsp);
+ } else {
+ result = downgrade_oplock(fsp);
}
- /* if this is a pure oplock break request then don't send a reply */
+ if (!result) {
+ DEBUG(0, ("reply_lockingX: error in removing "
+ "oplock on file %s\n", fsp->fsp_name));
+ /* Hmmm. Is this panic justified? */
+ smb_panic("internal tdb error");
+ }
+
+ reply_to_oplock_break_requests(fsp);
+
+ /* if this is a pure oplock break request then don't send a
+ * reply */
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
if(CVAL(inbuf,smb_vwv0) != 0xff)
- DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ DEBUG(0,("reply_lockingX: Error : pure oplock "
+ "break is a chained %d request !\n",
(unsigned int)CVAL(inbuf,smb_vwv0) ));
END_PROFILE(SMBlockingX);
return -1;
@@ -5186,8 +5197,9 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for pid %u, file %s\n",
- (double)offset, (double)count, (unsigned int)lock_pid, fsp->fsp_name ));
+ DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
+ "pid %u, file %s\n", (double)offset, (double)count,
+ (unsigned int)lock_pid, fsp->fsp_name ));
status = do_unlock(fsp,conn,lock_pid,count,offset);
if (NT_STATUS_V(status)) {
@@ -5219,27 +5231,34 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid %u, file %s timeout = %d\n",
- (double)offset, (double)count, (unsigned int)lock_pid,
- fsp->fsp_name, (int)lock_timeout ));
+ DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
+ "%u, file %s timeout = %d\n", (double)offset,
+ (double)count, (unsigned int)lock_pid,
+ fsp->fsp_name, (int)lock_timeout ));
status = do_lock_spin(fsp,conn,lock_pid, count,offset,
- ((locktype & 1) ? READ_LOCK : WRITE_LOCK), &my_lock_ctx);
+ ((locktype & 1) ? READ_LOCK:WRITE_LOCK),
+ &my_lock_ctx);
if (NT_STATUS_V(status)) {
/*
- * Interesting fact found by IFSTEST /t LockOverlappedTest...
- * Even if it's our own lock context, we need to wait here as
- * there may be an unlock on the way.
- * So I removed a "&& !my_lock_ctx" from the following
- * if statement. JRA.
+ * Interesting fact found by IFSTEST /t
+ * LockOverlappedTest... Even if it's our own lock
+ * context, we need to wait here as there may be an
+ * unlock on the way. So I removed a "&&
+ * !my_lock_ctx" from the following if statement. JRA.
*/
- if ((lock_timeout != 0) && lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ if ((lock_timeout != 0) &&
+ lp_blocking_locks(SNUM(conn)) &&
+ ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
* onto the blocking lock queue.
*/
- if(push_blocking_lock_request(inbuf, length, lock_timeout, i, lock_pid, offset, count)) {
+ if(push_blocking_lock_request(inbuf, length,
+ lock_timeout, i,
+ lock_pid, offset,
+ count)) {
END_PROFILE(SMBlockingX);
return -1;
}
@@ -5259,10 +5278,12 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
for(i--; i >= 0; i--) {
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ offset = get_lock_offset( data, i, large_file_format,
+ &err);
/*
- * There is no error code marked "stupid client bug".... :-).
+ * There is no error code marked "stupid client
+ * bug".... :-).
*/
if(err) {
END_PROFILE(SMBlockingX);
@@ -5277,8 +5298,8 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
set_message(outbuf,2,0,True);
- DEBUG( 3, ( "lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks ) );
+ DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+ fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
END_PROFILE(SMBlockingX);
return chain_reply(inbuf,outbuf,length,bufsize);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 1ff03174fe..8310b408d0 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -96,7 +96,7 @@ static void killkids(void)
somewhere else.
****************************************************************************/
-static void msg_sam_sync(int UNUSED(msg_type), pid_t UNUSED(pid),
+static void msg_sam_sync(int UNUSED(msg_type), struct process_id UNUSED(pid),
void *UNUSED(buf), size_t UNUSED(len))
{
DEBUG(10, ("** sam sync message received, ignoring\n"));
@@ -107,7 +107,8 @@ static void msg_sam_sync(int UNUSED(msg_type), pid_t UNUSED(pid),
somewhere else.
****************************************************************************/
-static void msg_sam_repl(int msg_type, pid_t pid, void *buf, size_t len)
+static void msg_sam_repl(int msg_type, struct process_id pid,
+ void *buf, size_t len)
{
uint32 low_serial;
@@ -140,7 +141,8 @@ static BOOL open_sockets_inetd(void)
return True;
}
-static void msg_exit_server(int msg_type, pid_t src, void *buf, size_t len)
+static void msg_exit_server(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
exit_server("Got a SHUTDOWN message");
}
@@ -621,9 +623,6 @@ void exit_server(const char *reason)
print_notify_send_messages(3); /* 3 second timeout. */
- /* run all registered exit events */
- smb_run_exit_events();
-
/* delete our entry in the connections database. */
yield_connection(NULL,"");
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index bf7287aab9..fc2d8b4abb 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -139,6 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
int length, int bufsize,
DATA_BLOB *secblob)
{
+ TALLOC_CTX *mem_ctx;
DATA_BLOB ticket;
char *client, *p, *domain;
fstring netbios_domain_name;
@@ -146,7 +147,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
fstring user;
int sess_vuid;
NTSTATUS ret;
- DATA_BLOB auth_data;
+ PAC_DATA *pac_data;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
DATA_BLOB session_key = data_blob(NULL, 0);
@@ -154,18 +155,24 @@ static int reply_spnego_kerberos(connection_struct *conn,
DATA_BLOB nullblob = data_blob(NULL, 0);
fstring real_username;
BOOL map_domainuser_to_guest = False;
+ PAC_LOGON_INFO *logon_info = NULL;
+ int i;
ZERO_STRUCT(ticket);
- ZERO_STRUCT(auth_data);
+ ZERO_STRUCT(pac_data);
ZERO_STRUCT(ap_rep);
ZERO_STRUCT(ap_rep_wrapped);
ZERO_STRUCT(response);
+ mem_ctx = talloc_init("reply_spnego_kerberos");
+ if (mem_ctx == NULL)
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+
if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key);
+ ret = ads_verify_ticket(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key);
data_blob_free(&ticket);
@@ -174,7 +181,18 @@ static int reply_spnego_kerberos(connection_struct *conn,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- data_blob_free(&auth_data);
+ if (pac_data) {
+
+ /* get the logon_info */
+ for (i=0; i < pac_data->num_buffers; i++) {
+
+ if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO)
+ continue;
+
+ logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info;
+ break;
+ }
+ }
DEBUG(3,("Ticket name is [%s]\n", client));
@@ -203,7 +221,14 @@ static int reply_spnego_kerberos(connection_struct *conn,
domain = p+1;
- {
+ if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) {
+
+ unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1);
+ domain = netbios_domain_name;
+ DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
+
+ } else {
+
/* If we have winbind running, we can (and must) shorten the
username by using the short netbios name. Otherwise we will
have inconsistent user names. With Kerberos, we get the
@@ -231,7 +256,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
wb_response.data.domain_info.name);
domain = netbios_domain_name;
- DEBUG(10, ("Mapped to [%s]\n", domain));
+ DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
} else {
DEBUG(3, ("Could not find short name -- winbind "
"not running?\n"));
@@ -274,8 +299,21 @@ static int reply_spnego_kerberos(connection_struct *conn,
reload_services(True);
if ( map_domainuser_to_guest ) {
make_server_info_guest(&server_info);
+ } else if (logon_info) {
+ ret = make_server_info_pac(&server_info, real_username, pw, logon_info);
+
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(1,("make_server_info_pac failed!\n"));
+ SAFE_FREE(client);
+ data_blob_free(&ap_rep);
+ data_blob_free(&session_key);
+ passwd_free(&pw);
+ return ERROR_NT(ret);
+ }
+
} else {
ret = make_server_info_pw(&server_info, real_username, pw);
+
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("make_server_info_from_pw failed!\n"));
SAFE_FREE(client);
@@ -284,15 +322,17 @@ static int reply_spnego_kerberos(connection_struct *conn,
passwd_free(&pw);
return ERROR_NT(ret);
}
+
+ /* make_server_info_pw does not set the domain. Without this we end up
+ * with the local netbios name in substitutions for %D. */
+
+ if (server_info->sam_account != NULL) {
+ pdb_set_domain(server_info->sam_account, domain, PDB_SET);
+ }
}
- passwd_free(&pw);
- /* make_server_info_pw does not set the domain. Without this we end up
- * with the local netbios name in substitutions for %D. */
- if (server_info->sam_account != NULL) {
- pdb_set_domain(server_info->sam_account, domain, PDB_SET);
- }
+ passwd_free(&pw);
/* register_vuid keeps the server info */
/* register_vuid takes ownership of session_key, no need to free after this.
@@ -339,6 +379,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
data_blob_free(&ap_rep);
data_blob_free(&ap_rep_wrapped);
data_blob_free(&response);
+ talloc_destroy(mem_ctx);
return -1; /* already replied */
}
@@ -348,6 +389,8 @@ static int reply_spnego_kerberos(connection_struct *conn,
Send a session setup reply, wrapped in SPNEGO.
Get vuid and check first.
End the NTLMSSP exchange context if we are OK/complete fail
+ This should be split into two functions, one to handle each
+ leg of the NTLM auth steps.
***************************************************************************/
static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
@@ -422,6 +465,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out
and the other end, that we are not finished yet. */
if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ /* NB. This is *NOT* an error case. JRA */
auth_ntlmssp_end(auth_ntlmssp_state);
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
@@ -660,7 +704,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
return ret;
}
- if (strncmp(blob1.data, "NTLMSSP", 7) == 0) {
+ if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
DATA_BLOB chal;
NTSTATUS nt_status;
if (!vuser->auth_ntlmssp_state) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 38363bf66a..f0b7812a1e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -27,7 +27,6 @@
extern int max_send;
extern enum protocol_types Protocol;
extern int smb_read_error;
-extern int global_oplock_break;
extern uint32 global_client_caps;
extern struct current_user current_user;
@@ -2789,7 +2788,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
delete_pending =
get_delete_on_close_flag(sbuf.st_dev,
- sbuf.st_ino);
+ sbuf.st_ino,
+ fname);
} else {
/*
* Original code - this is an open file.
@@ -2804,7 +2804,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
pos = fsp->fh->position_information;
delete_pending =
get_delete_on_close_flag(sbuf.st_dev,
- sbuf.st_ino);
+ sbuf.st_ino,
+ fname);
access_mask = fsp->access_mask;
}
} else {
@@ -2847,7 +2848,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
}
delete_pending = get_delete_on_close_flag(sbuf.st_dev,
- sbuf.st_ino);
+ sbuf.st_ino,
+ fname);
if (delete_pending) {
return ERROR_NT(NT_STATUS_DELETE_PENDING);
}
@@ -3455,91 +3457,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
/****************************************************************************
- Deal with the internal needs of setting the delete on close flag. Note that
- as the tdb locking is recursive, it is safe to call this from within
- open_file_shared. JRA.
-****************************************************************************/
-
-NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
- uint32 dosmode)
-{
- if (!delete_on_close) {
- return NT_STATUS_OK;
- }
-
- /*
- * Only allow delete on close for writable files.
- */
-
- if ((dosmode & aRONLY) &&
- !lp_delete_readonly(SNUM(fsp->conn))) {
- DEBUG(10,("can_set_delete_on_close: file %s delete on close "
- "flag set but file attribute is readonly.\n",
- fsp->fsp_name ));
- return NT_STATUS_CANNOT_DELETE;
- }
-
- /*
- * Only allow delete on close for writable shares.
- */
-
- if (!CAN_WRITE(fsp->conn)) {
- DEBUG(10,("can_set_delete_on_close: file %s delete on "
- "close flag set but write access denied on share.\n",
- fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- /*
- * Only allow delete on close for files/directories opened with delete
- * intent.
- */
-
- if (!(fsp->access_mask & DELETE_ACCESS)) {
- DEBUG(10,("can_set_delete_on_close: file %s delete on "
- "close flag set but delete access denied.\n",
- fsp->fsp_name ));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Sets the delete on close flag over all share modes on this file.
- Modify the share mode entry for all files open
- on this device and inode to tell other smbds we have
- changed the delete on close flag. This will be noticed
- in the close code, the last closer will delete the file
- if flag is set.
-****************************************************************************/
-
-NTSTATUS set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
-{
- DEBUG(10,("set_delete_on_close: %s delete on close flag for "
- "fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum,
- fsp->fsp_name ));
-
- if (fsp->is_directory || fsp->is_stat)
- return NT_STATUS_OK;
-
- if (lock_share_entry_fsp(fsp) == False)
- return NT_STATUS_ACCESS_DENIED;
-
- if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
- DEBUG(0,("set_delete_on_close: failed to change delete "
- "on close flag for file %s\n",
- fsp->fsp_name ));
- unlock_share_entry_fsp(fsp);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- unlock_share_entry_fsp(fsp);
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
Set a hard link (called by UNIX extensions and by NT rename with HARD link
code.
****************************************************************************/
@@ -3912,16 +3829,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
if (fd == -1) {
files_struct *new_fsp = NULL;
- if(global_oplock_break) {
- /* Queue this file modify as we are the process of an oplock break. */
-
- DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
- DEBUGADD(2,( "in oplock break state.\n"));
-
- push_oplock_pending_smb_message(inbuf, length);
- return -1;
- }
-
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE,
@@ -4003,9 +3910,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
/* The set is across all open files on this dev/inode pair. */
- status =set_delete_on_close(fsp, delete_on_close);
- if (!NT_STATUS_IS_OK(status)) {
- return ERROR_NT(status);
+ if (!set_delete_on_close(fsp, delete_on_close)) {
+ return ERROR_NT(NT_STATUS_ACCESS_DENIED);
}
SSVAL(params,0,0);
@@ -4456,16 +4362,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (fd == -1) {
files_struct *new_fsp = NULL;
- if(global_oplock_break) {
- /* Queue this file modify as we are the process of an oplock break. */
-
- DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
- DEBUGADD(2,( "in oplock break state.\n"));
-
- push_oplock_pending_smb_message(inbuf, length);
- return -1;
- }
-
new_fsp = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE,
@@ -4859,18 +4755,6 @@ int reply_trans2(connection_struct *conn,
unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
START_PROFILE(SMBtrans2);
- if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
- /* Queue this open message as we are the process of an
- * oplock break. */
-
- DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
- DEBUGADD(2,( "in oplock break state.\n"));
-
- push_oplock_pending_smb_message(inbuf, length);
- END_PROFILE(SMBtrans2);
- return -1;
- }
-
if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
&& (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
END_PROFILE(SMBtrans2);
diff --git a/source3/tdb/tdbdump.c b/source3/tdb/tdbdump.c
index 17ae536bc4..3efb29e44c 100644
--- a/source3/tdb/tdbdump.c
+++ b/source3/tdb/tdbdump.c
@@ -49,10 +49,10 @@ static void print_data(TDB_DATA d)
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
printf("{\n");
- printf("key(%d) = \"",key.dsize);
+ printf("key(%d) = \"", (int)key.dsize);
print_data(key);
printf("\"\n");
- printf("data(%d) = \"",dbuf.dsize);
+ printf("data(%d) = \"", (int)dbuf.dsize);
print_data(dbuf);
printf("\"\n");
printf("}\n");
diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c
index d9e7b9315a..8aa57af7ab 100644
--- a/source3/tdb/tdbtool.c
+++ b/source3/tdb/tdbtool.c
@@ -331,7 +331,7 @@ static void move_rec(char *keyname, size_t keylen, char* tdbname)
static int print_conn_key(TDB_DATA key)
{
- printf( "\nkey %d bytes\n", key.dsize);
+ printf( "\nkey %d bytes\n", (int)key.dsize);
printf( "pid =%5d ", ((connections_key*)key.dptr)->pid);
printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum);
printf( "name =[%s]\n", ((connections_key*)key.dptr)->name);
@@ -340,7 +340,7 @@ static int print_conn_key(TDB_DATA key)
static int print_conn_data(TDB_DATA dbuf)
{
- printf( "\ndata %d bytes\n", dbuf.dsize);
+ printf( "\ndata %d bytes\n", (int)dbuf.dsize);
printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid);
printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum);
printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name);
@@ -373,16 +373,16 @@ static int print_crec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *s
static int print_arec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
- printf("\nkey %d bytes\n", key.dsize);
+ printf("\nkey %d bytes\n", (int)key.dsize);
print_asc(key.dptr, key.dsize);
- printf("\ndata %d bytes\n", dbuf.dsize);
+ printf("\ndata %d bytes\n", (int)dbuf.dsize);
print_data(dbuf.dptr, dbuf.dsize);
return 0;
}
static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
- printf("key %d bytes: ", key.dsize);
+ printf("key %d bytes: ", (int)key.dsize);
print_asc(key.dptr, key.dsize);
printf("\n");
return 0;
@@ -390,7 +390,7 @@ static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *st
static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
- printf("key %d bytes\n", key.dsize);
+ printf("key %d bytes\n", (int)key.dsize);
print_data(key.dptr, key.dsize);
printf("\n");
return 0;
diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c
index 47f1bb2dc2..e27880e5ea 100644
--- a/source3/tdb/tdbutil.c
+++ b/source3/tdb/tdbutil.c
@@ -566,7 +566,12 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...)
p = va_arg(ap, void **);
if (bufsize < len)
goto no_space;
- *p = (void *)IVAL(buf, 0);
+ /*
+ * This isn't a real pointer - only a token (1 or 0)
+ * to mark the fact a pointer is present.
+ */
+
+ *p = (void *)(IVAL(buf, 0) ? (void *)1 : NULL);
break;
case 'P':
s = va_arg(ap,char *);
diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c
index d0b502c74e..fc180bfafe 100644
--- a/source3/torture/locktest2.c
+++ b/source3/torture/locktest2.c
@@ -133,12 +133,12 @@ static BOOL try_unlock(struct cli_state *c, int fstype,
return False;
}
-static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid,
enum brl_type lock_type,
br_off start, br_off size)
{
printf("%6d %05x:%05x %s %.0f:%.0f(%.0f)\n",
- (int)pid, (int)dev, (int)ino,
+ (int)procid_to_pid(&pid), (int)dev, (int)ino,
lock_type==READ_LOCK?"R":"W",
(double)start, (double)start+size-1,(double)size);
diff --git a/source3/torture/mangle_test.c b/source3/torture/mangle_test.c
index df0855d93d..9ce6afa038 100644
--- a/source3/torture/mangle_test.c
+++ b/source3/torture/mangle_test.c
@@ -98,7 +98,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
} else {
TDB_DATA namedata;
/* store it for later */
- namedata.dptr = name;
+ namedata.dptr = CONST_DISCARD(char *, name);
namedata.dsize = strlen(name)+1;
tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
}
diff --git a/source3/torture/msgtest.c b/source3/torture/msgtest.c
index ac55d70327..d691ab32f1 100644
--- a/source3/torture/msgtest.c
+++ b/source3/torture/msgtest.c
@@ -28,7 +28,7 @@ static int pong_count;
/****************************************************************************
a useful function for testing the message system
****************************************************************************/
-void pong_message(int msg_type, pid_t src, void *buf, size_t len)
+void pong_message(int msg_type, struct process_id src, void *buf, size_t len)
{
pong_count++;
}
@@ -56,7 +56,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len)
message_register(MSG_PONG, pong_message);
for (i=0;i<n;i++) {
- message_send_pid(pid, MSG_PING, NULL, 0, True);
+ message_send_pid(pid_to_procid(pid), MSG_PING, NULL, 0, True);
}
while (pong_count < i) {
@@ -70,8 +70,10 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len)
safe_strcpy(buf, "1234567890", sizeof(buf)-1);
for (i=0;i<n;i++) {
- message_send_pid(getpid(), MSG_PING, NULL, 0, False);
- message_send_pid(getpid(), MSG_PING, buf, 11, False);
+ message_send_pid(pid_to_procid(getpid()), MSG_PING,
+ NULL, 0, False);
+ message_send_pid(pid_to_procid(getpid()), MSG_PING,
+ buf, 11, False);
}
for (i=0;i<n;i++) {
diff --git a/source3/torture/t_asn1.c b/source3/torture/t_asn1.c
new file mode 100644
index 0000000000..98ee7baf92
--- /dev/null
+++ b/source3/torture/t_asn1.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004 by Volker Lendecke
+ *
+ * Test harness for asn1_write_*, inspired by Love Hornquist Astrand
+ */
+
+#include "includes.h"
+
+static DATA_BLOB tests[] = {
+ {"\x02\x01\x00", 3, NULL},
+ {"\x02\x01\x7f", 3, NULL},
+ {"\x02\x02\x00\x80", 4, NULL},
+ {"\x02\x02\x01\x00", 4, NULL},
+ {"\x02\x01\x80", 3, NULL},
+ {"\x02\x02\xff\x7f", 4, NULL},
+ {"\x02\x01\xff", 3, NULL},
+ {"\x02\x02\xff\x01", 4, NULL},
+ {"\x02\x02\x00\xff", 4, NULL},
+ {"\x02\x04\x80\x00\x00\x00", 6, NULL},
+ {"\x02\x04\x7f\xff\xff\xff", 6, NULL},
+ {NULL, 0, NULL}
+};
+
+static int values[] = {0, 127, 128, 256, -128, -129, -1, -255, 255,
+ 0x80000000, 0x7fffffff};
+
+int main(void)
+{
+ int i = 0;
+ int val;
+ BOOL ok = True;
+
+ for (i=0; tests[i].data != NULL; i++) {
+ ASN1_DATA data;
+ DATA_BLOB blob;
+
+ ZERO_STRUCT(data);
+ asn1_write_Integer(&data, values[i]);
+
+ if ((data.length != tests[i].length) ||
+ (memcmp(data.data, tests[i].data, data.length) != 0)) {
+ printf("Test for %d failed\n", values[i]);
+ ok = False;
+ }
+
+ blob.data = data.data;
+ blob.length = data.length;
+ asn1_load(&data, blob);
+ if (!asn1_read_Integer(&data, &val)) {
+ printf("Could not read our own Integer for %d\n",
+ values[i]);
+ ok = False;
+ }
+ if (val != values[i]) {
+ printf("%d -> ASN -> Int %d\n", values[i], val);
+ ok = False;
+ }
+ }
+
+ return ok ? 0 : 1;
+}
diff --git a/source3/torture/t_strappend.c b/source3/torture/t_strappend.c
new file mode 100644
index 0000000000..becc691c7f
--- /dev/null
+++ b/source3/torture/t_strappend.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 by Volker Lendecke
+ *
+ * Test harness for sprintf_append
+ */
+
+#include "includes.h"
+#include <assert.h>
+
+int main(int argc, char *argv[])
+{
+ TALLOC_CTX *mem_ctx;
+ char *string = NULL;
+ int len = 0;
+ int bufsize = 4;
+ int i;
+
+ mem_ctx = talloc_init("t_strappend");
+ if (mem_ctx == NULL) {
+ fprintf(stderr, "talloc_init failed\n");
+ return 1;
+ }
+
+ sprintf_append(mem_ctx, &string, &len, &bufsize, "");
+ assert(strlen(string) == len);
+ sprintf_append(mem_ctx, &string, &len, &bufsize, "");
+ assert(strlen(string) == len);
+ sprintf_append(mem_ctx, &string, &len, &bufsize,
+ "01234567890123456789012345678901234567890123456789\n");
+ assert(strlen(string) == len);
+
+
+ for (i=0; i<(100000); i++) {
+ if (i%1000 == 0) {
+ printf("%d %d\r", i, bufsize);
+ fflush(stdout);
+ }
+ sprintf_append(mem_ctx, &string, &len, &bufsize, "%d\n", i);
+ assert(strlen(string) == len);
+ }
+
+ talloc_destroy(mem_ctx);
+
+ return 0;
+}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 11cea53188..8ad567f177 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -698,7 +698,6 @@ static BOOL run_netbench(int client)
{
struct cli_state *cli;
int i;
- fstring fname;
pstring line;
char cname[20];
FILE *f;
diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c
index 69acd01c1a..b5ccf930bc 100644
--- a/source3/torture/vfstest.c
+++ b/source3/torture/vfstest.c
@@ -38,7 +38,7 @@ extern pstring user_socket_options;
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
+static char **completion_fn(const char *text, int start, int end)
{
#define MAX_COMPLETIONS 100
char **matches;
diff --git a/source3/utils/log2pcaphex.c b/source3/utils/log2pcaphex.c
index d07dc2a211..24412cbe85 100644
--- a/source3/utils/log2pcaphex.c
+++ b/source3/utils/log2pcaphex.c
@@ -200,7 +200,7 @@ void read_log_msg(FILE *in, unsigned char **_buffer, long *buffersize, long *dat
long read_log_data(FILE *in, unsigned char *buffer, long data_length)
{
long i, addr; char real[2][16]; int ret;
- unsigned char tmp;
+ unsigned int tmp;
for(i = 0; i < data_length; i++) {
if(i % 16 == 0){
if(i != 0) { /* Read data after each line */
@@ -213,7 +213,7 @@ long read_log_data(FILE *in, unsigned char *buffer, long data_length)
}
assert(addr == i);
}
- if(!fscanf(in, "%02lX", &tmp)) {
+ if(!fscanf(in, "%02X", &tmp)) {
if(!quiet)fprintf(stderr, "Only first %ld bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i-1);
return i-1;
}
@@ -230,7 +230,7 @@ int main (int argc, char **argv)
poptContext pc;
char buffer[4096];
long data_offset, data_length;
- long data_bytes_read;
+ long data_bytes_read = 0;
int in_packet = 0;
struct poptOption long_options[] = {
POPT_AUTOHELP
diff --git a/source3/utils/net.c b/source3/utils/net.c
index e9332f58f7..4d9dec4b85 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -219,36 +219,39 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS connect_dst_pipe(struct cli_state **cli_dst, int pipe_num, BOOL *got_pipe)
+NTSTATUS connect_dst_pipe(struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, int pipe_num)
{
NTSTATUS nt_status;
char *server_name = SMB_STRDUP("127.0.0.1");
struct cli_state *cli_tmp = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
if (opt_destination)
server_name = SMB_STRDUP(opt_destination);
/* make a connection to a named pipe */
nt_status = connect_to_ipc(&cli_tmp, NULL, server_name);
- if (!NT_STATUS_IS_OK(nt_status))
+ if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
+ }
- if (!cli_nt_session_open(cli_tmp, pipe_num)) {
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli_tmp, pipe_num, &nt_status);
+ if (!pipe_hnd) {
DEBUG(0, ("couldn't not initialize pipe\n"));
cli_shutdown(cli_tmp);
- return NT_STATUS_UNSUCCESSFUL;
+ return nt_status;
}
*cli_dst = cli_tmp;
- *got_pipe = True;
+ *pp_pipe_hnd = pipe_hnd;
return nt_status;
}
-
/****************************************************************************
- Use the local machine's password for this session
+ Use the local machine's password for this session.
****************************************************************************/
+
int net_use_machine_password(void)
{
char *user_name = NULL;
diff --git a/source3/utils/net.h b/source3/utils/net.h
index a2df6596b4..2df13cfb8f 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -23,16 +23,21 @@
* include
*/
-typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *,
- struct cli_state *, TALLOC_CTX *, int, const char **);
-
+typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *,
+ const char *,
+ struct cli_state *cli,
+ struct rpc_pipe_client *,
+ TALLOC_CTX *,
+ int,
+ const char **);
+
typedef struct copy_clistate {
TALLOC_CTX *mem_ctx;
struct cli_state *cli_share_src;
struct cli_state *cli_share_dst;
char *cwd;
uint16 attribute;
-}copy_clistate;
+}copy_clistate;
/* INCLUDE FILES */
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 6a58fa9fac..49a7f1cc2d 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -969,7 +969,8 @@ static int net_ads_printer_info(int argc, const char **argv)
return 0;
}
-void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
+void do_drv_upgrade_printer(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
return;
}
@@ -980,6 +981,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
ADS_STATUS rc;
const char *servername, *printername;
struct cli_state *cli;
+ struct rpc_pipe_client *pipe_hnd;
struct in_addr server_ip;
NTSTATUS nt_status;
TALLOC_CTX *mem_ctx = talloc_init("net_ads_printer_publish");
@@ -1038,8 +1040,9 @@ static int net_ads_printer_publish(int argc, const char **argv)
asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0], printername, srv_dn);
- cli_nt_session_open(cli, PI_SPOOLSS);
- get_remote_printer_publishing_data(cli, mem_ctx, &mods, printername);
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SPOOLSS, &nt_status);
+ get_remote_printer_publishing_data(pipe_hnd, mem_ctx, &mods,
+ printername);
rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
if (!ADS_ERR_OK(rc)) {
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index e80e8e6f5c..f1522ef158 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -4,6 +4,7 @@
Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com)
Copyright (C) 2004 Guenther Deschner (gd@samba.org)
+ Copyright (C) 2005 Jeremy Allison (jra@samba.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,24 +51,26 @@ static int net_mode_share;
static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **domain_name)
{
+ struct rpc_pipe_client *lsa_pipe;
DOM_SID *domain_sid;
POLICY_HND pol;
NTSTATUS result = NT_STATUS_OK;
uint32 info_class = 5;
- if (!cli_nt_session_open (cli, PI_LSARPC)) {
+ lsa_pipe = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
+ if (!lsa_pipe) {
fprintf(stderr, "could not initialise lsa pipe\n");
goto error;
}
- result = cli_lsa_open_policy(cli, mem_ctx, False,
+ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, False,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
if (!NT_STATUS_IS_OK(result)) {
goto error;
}
- result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
+ result = rpccli_lsa_query_info_policy(lsa_pipe, mem_ctx, &pol, info_class,
domain_name, &domain_sid);
if (!NT_STATUS_IS_OK(result)) {
error:
@@ -80,8 +83,10 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem
exit(1);
}
- cli_lsa_close(cli, mem_ctx, &pol);
- cli_nt_session_close(cli);
+ if (lsa_pipe) {
+ rpccli_lsa_close(lsa_pipe, mem_ctx, &pol);
+ cli_rpc_pipe_close(lsa_pipe);
+ }
return domain_sid;
}
@@ -98,21 +103,26 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem
* @return A shell status integer (0 for success)
*/
-int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
- rpc_command_fn fn,
- int argc, const char **argv)
+int run_rpc_command(struct cli_state *cli_arg,
+ const int pipe_idx,
+ int conn_flags,
+ rpc_command_fn fn,
+ int argc,
+ const char **argv)
{
struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid;
char *domain_name;
/* make use of cli_state handed over as an argument, if possible */
- if (!cli_arg)
+ if (!cli_arg) {
cli = net_make_ipc_connection(conn_flags);
- else
+ } else {
cli = cli_arg;
+ }
if (!cli) {
return -1;
@@ -129,14 +139,31 @@ int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flag
domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name);
if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
- if (!cli_nt_session_open(cli, pipe_idx)) {
- DEBUG(0, ("Could not initialise pipe\n"));
- cli_shutdown(cli);
- return -1;
+ if (lp_client_schannel() && (pipe_idx == PI_NETLOGON)) {
+ /* Always try and create an schannel netlogon pipe. */
+ pipe_hnd = cli_rpc_pipe_open_schannel(cli, pipe_idx,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain_name,
+ &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
+ nt_errstr(nt_status) ));
+ cli_shutdown(cli);
+ return -1;
+ }
+ } else {
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
+ cli_get_pipe_name(pipe_idx),
+ nt_errstr(nt_status) ));
+ cli_shutdown(cli);
+ return -1;
+ }
}
}
- nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv);
+ nt_status = fn(domain_sid, domain_name, cli, pipe_hnd, mem_ctx, argc, argv);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
@@ -145,23 +172,20 @@ int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flag
}
if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
- if (cli->pipes[cli->pipe_idx].fnum)
- cli_nt_session_close(cli);
+ if (pipe_hnd) {
+ cli_rpc_pipe_close(pipe_hnd);
+ }
}
/* close the connection only if it was opened here */
- if (!cli_arg)
+ if (!cli_arg) {
cli_shutdown(cli);
+ }
talloc_destroy(mem_ctx);
-
return (!NT_STATUS_IS_OK(nt_status));
}
-
-/****************************************************************************/
-
-
/**
* Force a change of the trust acccount password.
*
@@ -178,11 +202,16 @@ int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flag
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
+static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
- return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
+ return trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup);
}
/**
@@ -202,10 +231,6 @@ int net_rpc_changetrustpw(int argc, const char **argv)
argc, argv);
}
-
-/****************************************************************************/
-
-
/**
* Join a domain, the old way.
*
@@ -226,16 +251,29 @@ int net_rpc_changetrustpw(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
+static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
fstring trust_passwd;
unsigned char orig_trust_passwd_hash[16];
NTSTATUS result;
uint32 sec_channel_type;
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
+ if (!pipe_hnd) {
+ DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. "
+ "error was %s\n",
+ cli->desthost,
+ nt_errstr(result) ));
+ return result;
+ }
+
/*
check what type of join - if the user want's to join as
a BDC, the server must agree that we are a BDC.
@@ -258,7 +296,7 @@ static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *dom
E_md4hash(trust_passwd, orig_trust_passwd_hash);
- result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
+ result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, opt_target_workgroup,
orig_trust_passwd_hash,
sec_channel_type);
@@ -287,7 +325,7 @@ static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *dom
static int net_rpc_perform_oldjoin(int argc, const char **argv)
{
return run_rpc_command(NULL, PI_NETLOGON,
- NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
+ NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
rpc_oldjoin_internals,
argc, argv);
}
@@ -356,8 +394,6 @@ int net_rpc_join(int argc, const char **argv)
return net_rpc_join_newstyle(argc, argv);
}
-
-
/**
* display info about a rpc domain
*
@@ -374,10 +410,13 @@ int net_rpc_join(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_info_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -387,14 +426,14 @@ rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
sid_to_string(sid_str, domain_sid);
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -402,7 +441,7 @@ rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
}
ZERO_STRUCT(ctr);
- result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_dom_info(pipe_hnd, mem_ctx, &domain_pol,
2, &ctr);
if (NT_STATUS_IS_OK(result)) {
TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
@@ -419,13 +458,13 @@ rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
return result;
}
-
/**
* 'net rpc info' entrypoint.
* @param argc Standard main() style argc
* @param argc Standard main() style argv. Initial components are already
* stripped
**/
+
int net_rpc_info(int argc, const char **argv)
{
return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
@@ -433,7 +472,6 @@ int net_rpc_info(int argc, const char **argv)
argc, argv);
}
-
/**
* Fetch domain SID into the local secrets.tdb
*
@@ -450,10 +488,13 @@ int net_rpc_info(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_getsid_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
fstring sid_str;
@@ -469,13 +510,13 @@ rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name,
return NT_STATUS_OK;
}
-
/**
* 'net rpc getsid' entrypoint.
* @param argc Standard main() style argc
* @param argc Standard main() style argv. Initial components are already
* stripped
**/
+
int net_rpc_getsid(int argc, const char **argv)
{
return run_rpc_command(NULL, PI_SAMR, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
@@ -483,7 +524,6 @@ int net_rpc_getsid(int argc, const char **argv)
argc, argv);
}
-
/****************************************************************************/
/**
@@ -514,9 +554,13 @@ static int rpc_user_usage(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
+static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -534,7 +578,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *do
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -542,7 +586,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *do
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -554,7 +598,7 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *do
acb_info = ACB_NORMAL;
unknown = 0xe005000b; /* No idea what this is - a permission mask? */
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
acct_name, acb_info, unknown,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result)) {
@@ -604,10 +648,12 @@ static int rpc_user_add(int argc, const char **argv)
**/
static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol, user_pol;
@@ -619,14 +665,14 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
}
/* Get sam policy and domain handles */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
@@ -640,7 +686,7 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
uint32 *user_rids, num_rids, *name_types;
uint32 flags = 0x000003e8; /* Unknown */
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
flags, 1, &argv[0],
&num_rids, &user_rids,
&name_types);
@@ -649,7 +695,7 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rids[0], &user_pol);
@@ -660,23 +706,22 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
/* Delete user */
- result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
+ result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Display results */
- if (!NT_STATUS_IS_OK(result)) {
+ if (!NT_STATUS_IS_OK(result)) {
d_printf("Failed to delete user account - %s\n", nt_errstr(result));
- } else {
- d_printf("Deleted user account\n");
- }
+ } else {
+ d_printf("Deleted user account\n");
+ }
done:
return result;
-
-}
+}
/**
* Rename a user on a remote RPC server
@@ -694,10 +739,14 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
+static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 info_level = 7;
@@ -725,7 +774,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -733,7 +782,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -742,7 +791,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
names[0] = old_name;
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
flags, num_names, names,
&num_rids, &user_rid, &name_types);
if (!NT_STATUS_IS_OK(result)) {
@@ -750,7 +799,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
}
/* Open domain user */
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -758,7 +807,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
}
/* Query user info */
- result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
info_level, &user_ctr);
if (!NT_STATUS_IS_OK(result)) {
@@ -771,7 +820,7 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
init_sam_user_info7(&info7, new_name);
/* Set new name */
- result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
info_level, &cli->user_session_key, &ctr);
if (!NT_STATUS_IS_OK(result)) {
@@ -788,7 +837,6 @@ static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char
return result;
}
-
/**
* Rename a user on a remote RPC server
*
@@ -838,10 +886,12 @@ static int rpc_user_delete(int argc, const char **argv)
**/
static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND connect_pol, domain_pol, user_pol;
@@ -870,14 +920,14 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
/* Get sam policy and domain handles */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
@@ -891,7 +941,7 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
uint32 *user_rids, num_rids, *name_types;
uint32 flags = 0x000003e8; /* Unknown */
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
flags, 1, &user,
&num_rids, &user_rids,
&name_types);
@@ -900,7 +950,7 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rids[0], &user_pol);
@@ -921,7 +971,7 @@ static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid,
ctr.switch_value = 24;
ctr.info.id24 = &p24;
- result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
+ result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
&cli->user_session_key, &ctr);
if (!NT_STATUS_IS_OK(result)) {
@@ -967,10 +1017,13 @@ static int rpc_user_password(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name,
+static NTSTATUS rpc_user_info_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -987,31 +1040,31 @@ rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name,
}
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Get handle on user */
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
flags, 1, &argv[0],
&num_rids, &rids, &name_types);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
rids[0], &user_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
- result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, &user_pol,
&num_rids, &user_gids);
if (!NT_STATUS_IS_OK(result)) goto done;
@@ -1024,7 +1077,7 @@ rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name,
for (i = 0; i < num_rids; i++)
rids[i] = user_gids[i].g_rid;
- result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, &domain_pol,
num_rids, rids,
&num_names, &names, &name_types);
@@ -1073,10 +1126,13 @@ static int rpc_user_info(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_user_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1086,7 +1142,7 @@ rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -1094,7 +1150,7 @@ rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -1115,7 +1171,7 @@ rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name,
get_query_dispinfo_params(
loop_count, &max_entries, &max_size);
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
&start_idx, 1, &num_entries,
max_entries, max_size, &ctr);
loop_count++;
@@ -1163,7 +1219,6 @@ int net_rpc_user(int argc, const char **argv)
return net_run_function(argc, argv, func, rpc_user_usage);
}
-
/****************************************************************************/
/**
@@ -1195,10 +1250,12 @@ static int rpc_group_usage(int argc, const char **argv)
**/
static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol, user_pol;
BOOL group_is_primary = False;
@@ -1219,7 +1276,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
return NT_STATUS_OK; /* ok? */
}
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -1227,7 +1284,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
@@ -1236,7 +1293,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol,
flags, 1, &argv[0],
&num_rids, &group_rids,
&name_types);
@@ -1249,7 +1306,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
switch (name_types[0])
{
case SID_NAME_DOM_GRP:
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rids[0], &group_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -1259,7 +1316,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
group_rid = group_rids[0];
- result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
+ result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs);
@@ -1276,7 +1333,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
/* Check if group is anyone's primary group */
for (i = 0; i < num_members; i++)
{
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rids[i], &user_pol);
@@ -1287,7 +1344,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
ZERO_STRUCT(user_ctr);
- result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx, &user_pol,
21, &user_ctr);
if (!NT_STATUS_IS_OK(result)) {
@@ -1303,7 +1360,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
group_is_primary = True;
}
- cli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
}
if (group_is_primary) {
@@ -1318,7 +1375,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
{
if (opt_verbose)
d_printf("Remove group member %d...",group_rids[i]);
- result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, group_rids[i]);
+ result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, group_rids[i]);
if (NT_STATUS_IS_OK(result)) {
if (opt_verbose)
@@ -1330,12 +1387,12 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
}
}
- result = cli_samr_delete_dom_group(cli, mem_ctx, &group_pol);
+ result = rpccli_samr_delete_dom_group(pipe_hnd, mem_ctx, &group_pol);
break;
/* removing a local group is easier... */
case SID_NAME_ALIAS:
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rids[0], &group_pol);
@@ -1344,7 +1401,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_delete_dom_alias(cli, mem_ctx, &group_pol);
+ result = rpccli_samr_delete_dom_alias(pipe_hnd, mem_ctx, &group_pol);
break;
default:
d_printf("%s is of type %s. This command is only for deleting local or global groups\n",
@@ -1373,10 +1430,13 @@ static int rpc_group_delete(int argc, const char **argv)
argc,argv);
}
-static NTSTATUS
-rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_add_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol, group_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1390,20 +1450,20 @@ rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Create the group */
- result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_group(pipe_hnd, mem_ctx, &domain_pol,
argv[0], MAXIMUM_ALLOWED_ACCESS,
&group_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
@@ -1415,7 +1475,7 @@ rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
group_info.switch_value1 = 4;
init_samr_group_info4(&group_info.group.info4, opt_comment);
- result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &group_info);
+ result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &group_info);
if (!NT_STATUS_IS_OK(result)) goto done;
done:
@@ -1427,10 +1487,13 @@ rpc_group_add_internals(const DOM_SID *domain_sid, const char *domain_name,
return result;
}
-static NTSTATUS
-rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_alias_add_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol, alias_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1444,20 +1507,20 @@ rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
/* Create the group */
- result = cli_samr_create_dom_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_alias(pipe_hnd, mem_ctx, &domain_pol,
argv[0], &alias_pol);
if (!NT_STATUS_IS_OK(result)) goto done;
@@ -1468,7 +1531,7 @@ rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
alias_info.level = 3;
init_samr_alias_info3(&alias_info.alias.info3, opt_comment);
- result = cli_samr_set_aliasinfo(cli, mem_ctx, &alias_pol, &alias_info);
+ result = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, &alias_pol, &alias_info);
if (!NT_STATUS_IS_OK(result)) goto done;
done:
@@ -1492,33 +1555,31 @@ static int rpc_group_add(int argc, const char **argv)
argc, argv);
}
-static NTSTATUS
-get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name,
- DOM_SID *sid, enum SID_NAME_USE *type)
+static NTSTATUS get_sid_from_name(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *name,
+ DOM_SID *sid,
+ enum SID_NAME_USE *type)
{
- int current_pipe = cli->pipe_idx;
-
DOM_SID *sids = NULL;
uint32 *types = NULL;
+ struct rpc_pipe_client *pipe_hnd;
POLICY_HND lsa_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- if (current_pipe != PI_LSARPC) {
-
- if (current_pipe != -1)
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, PI_LSARPC))
- goto done;
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
+ if (!pipe_hnd) {
+ goto done;
}
- result = cli_lsa_open_policy(cli, mem_ctx, False,
+ result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, False,
SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
- result = cli_lsa_lookup_names(cli, mem_ctx, &lsa_pol, 1,
+ result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &lsa_pol, 1,
&name, &sids, &types);
if (NT_STATUS_IS_OK(result)) {
@@ -1526,13 +1587,11 @@ get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name,
*type = types[0];
}
- cli_lsa_close(cli, mem_ctx, &lsa_pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
done:
- if (current_pipe != PI_LSARPC) {
- cli_nt_session_close(cli);
- if (current_pipe != -1)
- cli_nt_session_open(cli, current_pipe);
+ if (pipe_hnd) {
+ cli_rpc_pipe_close(pipe_hnd);
}
if (!NT_STATUS_IS_OK(result) && (StrnCaseCmp(name, "S-", 2) == 0)) {
@@ -1551,9 +1610,10 @@ get_sid_from_name(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *name,
return result;
}
-static NTSTATUS
-rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, const char *member)
+static NTSTATUS rpc_add_groupmem(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *group_sid,
+ const char *member)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result;
@@ -1568,23 +1628,26 @@ rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
sid_copy(&sid, group_sid);
- if (!sid_split_rid(&sid, &group_rid))
+ if (!sid_split_rid(&sid, &group_rid)) {
return NT_STATUS_UNSUCCESSFUL;
+ }
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&sid, &domain_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
1, &member,
&num_rids, &rids, &rid_types);
@@ -1593,23 +1656,25 @@ rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rid, &group_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
+ }
- result = cli_samr_add_groupmem(cli, mem_ctx, &group_pol, rids[0]);
+ result = rpccli_samr_add_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
return result;
}
-static NTSTATUS
-rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *alias_sid, const char *member)
+static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *alias_sid,
+ const char *member)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result;
@@ -1623,10 +1688,11 @@ rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
sid_copy(&sid, alias_sid);
- if (!sid_split_rid(&sid, &alias_rid))
+ if (!sid_split_rid(&sid, &alias_rid)) {
return NT_STATUS_UNSUCCESSFUL;
+ }
- result = get_sid_from_name(cli, mem_ctx, member,
+ result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
&member_sid, &member_type);
if (!NT_STATUS_IS_OK(result)) {
@@ -1635,41 +1701,46 @@ rpc_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
alias_rid, &alias_pol);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
- result = cli_samr_add_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
+ result = rpccli_samr_add_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
return result;
}
-static NTSTATUS
-rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_addmem_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
DOM_SID group_sid;
enum SID_NAME_USE group_type;
@@ -1686,7 +1757,7 @@ rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name,
}
if (group_type == SID_NAME_DOM_GRP) {
- NTSTATUS result = rpc_add_groupmem(cli, mem_ctx,
+ NTSTATUS result = rpc_add_groupmem(pipe_hnd, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
@@ -1697,7 +1768,7 @@ rpc_group_addmem_internals(const DOM_SID *domain_sid, const char *domain_name,
}
if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_add_aliasmem(cli, mem_ctx,
+ NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
@@ -1720,9 +1791,10 @@ static int rpc_group_addmem(int argc, const char **argv)
argc, argv);
}
-static NTSTATUS
-rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, const char *member)
+static NTSTATUS rpc_del_groupmem(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *group_sid,
+ const char *member)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result;
@@ -1741,19 +1813,19 @@ rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_UNSUCCESSFUL;
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result))
return result;
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
1, &member,
&num_rids, &rids, &rid_types);
@@ -1762,23 +1834,24 @@ rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rid, &group_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_del_groupmem(cli, mem_ctx, &group_pol, rids[0]);
+ result = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, &group_pol, rids[0]);
done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
return result;
}
-static NTSTATUS
-rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const DOM_SID *alias_sid, const char *member)
+static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *alias_sid,
+ const char *member)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result;
@@ -1795,7 +1868,7 @@ rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (!sid_split_rid(&sid, &alias_rid))
return NT_STATUS_UNSUCCESSFUL;
- result = get_sid_from_name(cli, mem_ctx, member,
+ result = get_sid_from_name(pipe_hnd->cli, mem_ctx, member,
&member_sid, &member_type);
if (!NT_STATUS_IS_OK(result)) {
@@ -1804,41 +1877,44 @@ rpc_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
alias_rid, &alias_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_del_aliasmem(cli, mem_ctx, &alias_pol, &member_sid);
+ result = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, &alias_pol, &member_sid);
if (!NT_STATUS_IS_OK(result))
return result;
done:
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
return result;
}
-static NTSTATUS
-rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_delmem_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
DOM_SID group_sid;
enum SID_NAME_USE group_type;
@@ -1855,7 +1931,7 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name,
}
if (group_type == SID_NAME_DOM_GRP) {
- NTSTATUS result = rpc_del_groupmem(cli, mem_ctx,
+ NTSTATUS result = rpc_del_groupmem(pipe_hnd, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
@@ -1866,7 +1942,7 @@ rpc_group_delmem_internals(const DOM_SID *domain_sid, const char *domain_name,
}
if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_del_aliasmem(cli, mem_ctx,
+ NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
@@ -1905,10 +1981,13 @@ static int rpc_group_delmem(int argc, const char **argv)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1937,7 +2016,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -1945,7 +2024,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -1970,7 +2049,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
get_query_dispinfo_params(
loop_count, &max_entries, &max_size);
- result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_query_dispinfo(pipe_hnd, mem_ctx, &domain_pol,
&start_idx, 3, &num_entries,
max_entries, max_size, &ctr);
@@ -2003,7 +2082,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
* everything. I'm too lazy (sorry) to get this through to
* rpc_parse/ etc. Volker */
- result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
&start_idx, 0xffff,
&groups, &num_entries);
@@ -2020,15 +2099,15 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
POLICY_HND alias_pol;
ALIAS_INFO_CTR ctr;
- if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
+ if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
&domain_pol,
0x8,
groups[i].rid,
&alias_pol))) &&
- (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
+ (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
&alias_pol, 3,
&ctr))) &&
- (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
+ (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
&alias_pol)))) {
description = unistr2_tdup(mem_ctx,
ctr.alias.info3.description.string);
@@ -2044,10 +2123,10 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
}
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
/* Get builtin policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&global_sid_Builtin, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -2058,7 +2137,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
do {
if (!builtin) break;
- result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
&start_idx, max_entries,
&groups, &num_entries);
@@ -2075,15 +2154,15 @@ rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name,
POLICY_HND alias_pol;
ALIAS_INFO_CTR ctr;
- if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
+ if ((NT_STATUS_IS_OK(rpccli_samr_open_alias(pipe_hnd, mem_ctx,
&domain_pol,
0x8,
groups[i].rid,
&alias_pol))) &&
- (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
+ (NT_STATUS_IS_OK(rpccli_samr_query_alias_info(pipe_hnd, mem_ctx,
&alias_pol, 3,
&ctr))) &&
- (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
+ (NT_STATUS_IS_OK(rpccli_samr_close(pipe_hnd, mem_ctx,
&alias_pol)))) {
description = unistr2_tdup(mem_ctx,
ctr.alias.info3.description.string);
@@ -2111,10 +2190,12 @@ static int rpc_group_list(int argc, const char **argv)
argc, argv);
}
-static NTSTATUS
-rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *domain_name, const DOM_SID *domain_sid,
- POLICY_HND *domain_pol, uint32 rid)
+static NTSTATUS rpc_list_group_members(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const char *domain_name,
+ const DOM_SID *domain_sid,
+ POLICY_HND *domain_pol,
+ uint32 rid)
{
NTSTATUS result;
POLICY_HND group_pol;
@@ -2127,14 +2208,14 @@ rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
fstring sid_str;
sid_to_string(sid_str, domain_sid);
- result = cli_samr_open_group(cli, mem_ctx, domain_pol,
+ result = rpccli_samr_open_group(pipe_hnd, mem_ctx, domain_pol,
MAXIMUM_ALLOWED_ACCESS,
rid, &group_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
+ result = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs);
@@ -2147,7 +2228,7 @@ rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (num_members < this_time)
this_time = num_members;
- result = cli_samr_lookup_rids(cli, mem_ctx, domain_pol,
+ result = rpccli_samr_lookup_rids(pipe_hnd, mem_ctx, domain_pol,
this_time, group_rids,
&num_names, &names, &name_types);
@@ -2175,11 +2256,13 @@ rpc_list_group_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS
-rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *domain_pol, uint32 rid)
+static NTSTATUS rpc_list_alias_members(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol,
+ uint32 rid)
{
NTSTATUS result;
+ struct rpc_pipe_client *lsa_pipe;
POLICY_HND alias_pol, lsa_pol;
uint32 num_members;
DOM_SID *alias_sids;
@@ -2188,13 +2271,13 @@ rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 *types;
int i;
- result = cli_samr_open_alias(cli, mem_ctx, domain_pol,
+ result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, domain_pol,
MAXIMUM_ALLOWED_ACCESS, rid, &alias_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
+ result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, &alias_pol,
&num_members, &alias_sids);
if (!NT_STATUS_IS_OK(result)) {
@@ -2206,28 +2289,30 @@ rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- cli_nt_session_close(cli);
-
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- d_printf("Couldn't open LSA pipe\n");
+ lsa_pipe = cli_rpc_pipe_open_noauth(pipe_hnd->cli, PI_LSARPC, &result);
+ if (!lsa_pipe) {
+ d_printf("Couldn't open LSA pipe. Error was %s\n",
+ nt_errstr(result) );
return result;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
if (!NT_STATUS_IS_OK(result)) {
d_printf("Couldn't open LSA policy handle\n");
+ cli_rpc_pipe_close(lsa_pipe);
return result;
}
- result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, num_members,
+ result = rpccli_lsa_lookup_sids(lsa_pipe, mem_ctx, &lsa_pol, num_members,
alias_sids,
&domains, &names, &types);
if (!NT_STATUS_IS_OK(result) &&
!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
d_printf("Couldn't lookup SIDs\n");
+ cli_rpc_pipe_close(lsa_pipe);
return result;
}
@@ -2247,14 +2332,17 @@ rpc_list_alias_members(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
}
+ cli_rpc_pipe_close(lsa_pipe);
return NT_STATUS_OK;
}
-static NTSTATUS
-rpc_group_members_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_members_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result;
POLICY_HND connect_pol, domain_pol;
@@ -2262,7 +2350,7 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result))
@@ -2270,14 +2358,14 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
1, argv, &num_rids, &rids, &rid_types);
if (!NT_STATUS_IS_OK(result)) {
@@ -2286,11 +2374,11 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
DOM_SID sid_Builtin;
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
string_to_sid(&sid_Builtin, "S-1-5-32");
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&sid_Builtin, &domain_pol);
@@ -2299,7 +2387,7 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
return result;
}
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
1, argv, &num_rids,
&rids, &rid_types);
@@ -2315,13 +2403,13 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
}
if (rid_types[0] == SID_NAME_DOM_GRP) {
- return rpc_list_group_members(cli, mem_ctx, domain_name,
+ return rpc_list_group_members(pipe_hnd, mem_ctx, domain_name,
domain_sid, &domain_pol,
rids[0]);
}
if (rid_types[0] == SID_NAME_ALIAS) {
- return rpc_list_alias_members(cli, mem_ctx, &domain_pol,
+ return rpc_list_alias_members(pipe_hnd, mem_ctx, &domain_pol,
rids[0]);
}
@@ -2339,11 +2427,13 @@ static int rpc_group_members(int argc, const char **argv)
argc, argv);
}
-static NTSTATUS
-rpc_group_rename_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_group_rename_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result;
POLICY_HND connect_pol, domain_pol, group_pol;
@@ -2357,7 +2447,7 @@ rpc_group_rename_internals(const DOM_SID *domain_sid,
/* Get sam policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result))
@@ -2365,14 +2455,14 @@ rpc_group_rename_internals(const DOM_SID *domain_sid,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, 1000,
1, argv, &num_rids, &rids, &rid_types);
if (num_rids != 1) {
@@ -2385,7 +2475,7 @@ rpc_group_rename_internals(const DOM_SID *domain_sid,
return NT_STATUS_UNSUCCESSFUL;
}
- result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_group(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
rids[0], &group_pol);
@@ -2397,7 +2487,7 @@ rpc_group_rename_internals(const DOM_SID *domain_sid,
ctr.switch_value1 = 2;
init_samr_group_info2(&ctr.group.info2, argv[1]);
- result = cli_samr_set_groupinfo(cli, mem_ctx, &group_pol, &ctr);
+ result = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, &group_pol, &ctr);
if (!NT_STATUS_IS_OK(result))
return result;
@@ -2467,10 +2557,12 @@ static int rpc_share_usage(int argc, const char **argv)
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,int argc, const char **argv)
+static NTSTATUS rpc_share_add_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,int argc,
+ const char **argv)
{
WERROR result;
char *sharename=talloc_strdup(mem_ctx, argv[0]);
@@ -2485,7 +2577,7 @@ rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name,
return NT_STATUS_UNSUCCESSFUL;
*path++ = '\0';
- result = cli_srvsvc_net_share_add(cli, mem_ctx, sharename, type,
+ result = rpccli_srvsvc_net_share_add(pipe_hnd, mem_ctx, sharename, type,
opt_comment, perms, opt_maxusers,
num_users, path, password,
level, NULL);
@@ -2518,14 +2610,17 @@ static int rpc_share_add(int argc, const char **argv)
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,int argc, const char **argv)
+static NTSTATUS rpc_share_del_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
- result = cli_srvsvc_net_share_del(cli, mem_ctx, argv[0]);
+ result = rpccli_srvsvc_net_share_del(pipe_hnd, mem_ctx, argv[0]);
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -2572,10 +2667,12 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
}
-
-static WERROR get_share_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 level, int argc, const char **argv,
- SRV_SHARE_INFO_CTR *ctr)
+static WERROR get_share_info(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ uint32 level,
+ int argc,
+ const char **argv,
+ SRV_SHARE_INFO_CTR *ctr)
{
WERROR result;
SRV_SHARE_INFO info;
@@ -2588,12 +2685,12 @@ static WERROR get_share_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_enum_hnd(&hnd, 0);
- return cli_srvsvc_net_share_enum(cli, mem_ctx, level, ctr,
+ return rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, level, ctr,
preferred_len, &hnd);
}
/* request just one share */
- result = cli_srvsvc_net_share_get_info(cli, mem_ctx, argv[0], level, &info);
+ result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, argv[0], level, &info);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2720,16 +2817,19 @@ done:
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_share_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
SRV_SHARE_INFO_CTR ctr;
WERROR result;
uint32 i, level = 1;
- result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -2808,10 +2908,14 @@ static BOOL check_share_sanity(struct cli_state *cli, fstring netname, uint32 ty
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+static NTSTATUS rpc_share_migrate_shares_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -2819,16 +2923,16 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
char *password = NULL; /* don't allow a share password */
uint32 i;
- BOOL got_dst_srvsvc_pipe = False;
+ struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
uint32 level = 502; /* includes secdesc */
- result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
if (!W_ERROR_IS_OK(result))
goto done;
/* connect destination PI_SRVSVC */
- nt_status = connect_dst_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
@@ -2854,7 +2958,7 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
printf("migrating: [%s], path: %s, comment: %s, without share-ACLs\n",
netname, path, remark);
- result = cli_srvsvc_net_share_add(cli_dst, mem_ctx, netname, type, remark,
+ result = rpccli_srvsvc_net_share_add(srvsvc_pipe, mem_ctx, netname, type, remark,
ctr_src.share.info502[i].info_502.perms,
ctr_src.share.info502[i].info_502.max_uses,
ctr_src.share.info502[i].info_502.num_uses,
@@ -2876,8 +2980,7 @@ rpc_share_migrate_shares_internals(const DOM_SID *domain_sid, const char *domain
nt_status = NT_STATUS_OK;
done:
- if (got_dst_srvsvc_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
@@ -3038,7 +3141,7 @@ BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
const char *sharename)
{
- NTSTATUS nt_status;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
switch (net_mode_share) {
case NET_MODE_SHARE_MIGRATE:
@@ -3066,7 +3169,6 @@ BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
return True;
}
-
/**
* Sync all files inside a remote share to another share (over smb)
*
@@ -3082,10 +3184,14 @@ BOOL copy_top_level_perms(struct copy_clistate *cp_clistate,
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+static NTSTATUS rpc_share_migrate_files_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -3100,7 +3206,7 @@ rpc_share_migrate_files_internals(const DOM_SID *domain_sid, const char *domain_
dst = SMB_STRDUP(opt_destination?opt_destination:"127.0.0.1");
- result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -3216,27 +3322,31 @@ static int rpc_share_migrate_files(int argc, const char **argv)
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_migrate_security_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+static NTSTATUS rpc_share_migrate_security_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
SRV_SHARE_INFO_CTR ctr_src;
SRV_SHARE_INFO info;
uint32 i;
- BOOL got_dst_srvsvc_pipe = False;
+ struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
uint32 level = 502; /* includes secdesc */
- result = get_share_info(cli, mem_ctx, level, argc, argv, &ctr_src);
+ result = get_share_info(pipe_hnd, mem_ctx, level, argc, argv, &ctr_src);
if (!W_ERROR_IS_OK(result))
goto done;
/* connect destination PI_SRVSVC */
- nt_status = connect_dst_pipe(&cli_dst, PI_SRVSVC, &got_dst_srvsvc_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &srvsvc_pipe, PI_SRVSVC);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
@@ -3273,7 +3383,7 @@ rpc_share_migrate_security_internals(const DOM_SID *domain_sid, const char *doma
info.share.info502 = ctr_src.share.info502[i];
/* finally modify the share on the dst server */
- result = cli_srvsvc_net_share_set_info(cli_dst, mem_ctx, netname, level, &info);
+ result = rpccli_srvsvc_net_share_set_info(srvsvc_pipe, mem_ctx, netname, level, &info);
if (!W_ERROR_IS_OK(result)) {
printf("cannot set share-acl: %s\n", dos_errstr(result));
@@ -3285,8 +3395,7 @@ rpc_share_migrate_security_internals(const DOM_SID *domain_sid, const char *doma
nt_status = NT_STATUS_OK;
done:
- if (got_dst_srvsvc_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
@@ -3399,10 +3508,11 @@ static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
* For a specific domain on the server, fetch all the aliases
* and their members. Add all of them to the server_aliases.
*/
-static NTSTATUS
-rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *connect_pol,
- const DOM_SID *domain_sid)
+
+static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *connect_pol,
+ const DOM_SID *domain_sid)
{
uint32 start_idx, max_entries, num_entries, i;
struct acct_info *groups;
@@ -3411,7 +3521,7 @@ rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result))
@@ -3421,7 +3531,7 @@ rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
max_entries = 250;
do {
- result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_enum_als_groups(pipe_hnd, mem_ctx, &domain_pol,
&start_idx, max_entries,
&groups, &num_entries);
@@ -3432,21 +3542,21 @@ rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
DOM_SID *members;
int j;
- result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_alias(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
groups[i].rid,
&alias_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_query_aliasmem(cli, mem_ctx,
+ result = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx,
&alias_pol,
&alias.num_members,
&members);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_samr_close(cli, mem_ctx, &alias_pol);
+ result = rpccli_samr_close(pipe_hnd, mem_ctx, &alias_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -3470,7 +3580,7 @@ rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = NT_STATUS_OK;
done:
- cli_samr_close(cli, mem_ctx, &domain_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
return result;
}
@@ -3478,16 +3588,20 @@ rpc_fetch_domain_aliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*
* Dump server_aliases as names for debugging purposes.
*/
-static NTSTATUS
-rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+static NTSTATUS rpc_aliaslist_dump(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
int i;
NTSTATUS result;
POLICY_HND lsa_pol;
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&lsa_pol);
if (!NT_STATUS_IS_OK(result))
@@ -3501,7 +3615,7 @@ rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
struct full_alias *alias = &server_aliases[i];
- result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol, 1,
+ result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol, 1,
&alias->sid,
&domains, &names, &types);
if (!NT_STATUS_IS_OK(result))
@@ -3514,7 +3628,7 @@ rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
continue;
}
- result = cli_lsa_lookup_sids(cli, mem_ctx, &lsa_pol,
+ result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &lsa_pol,
alias->num_members,
alias->members,
&domains, &names, &types);
@@ -3530,7 +3644,7 @@ rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
DEBUG(1, ("\n"));
}
- cli_lsa_close(cli, mem_ctx, &lsa_pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
return NT_STATUS_OK;
}
@@ -3539,30 +3653,34 @@ rpc_aliaslist_dump(const DOM_SID *domain_sid, const char *domain_name,
* Fetch a list of all server aliases and their members into
* server_aliases.
*/
-static NTSTATUS
-rpc_aliaslist_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+static NTSTATUS rpc_aliaslist_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result;
POLICY_HND connect_pol;
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
+ result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
&global_sid_Builtin);
if (!NT_STATUS_IS_OK(result))
goto done;
- result = rpc_fetch_domain_aliases(cli, mem_ctx, &connect_pol,
+ result = rpc_fetch_domain_aliases(pipe_hnd, mem_ctx, &connect_pol,
domain_sid);
- cli_samr_close(cli, mem_ctx, &connect_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
done:
return result;
}
@@ -3662,8 +3780,7 @@ static void collect_alias_memberships(NT_USER_TOKEN *token)
}
}
-static BOOL get_user_sids(const char *domain, const char *user,
- NT_USER_TOKEN *token)
+static BOOL get_user_sids(const char *domain, const char *user, NT_USER_TOKEN *token)
{
struct winbindd_request request;
struct winbindd_response response;
@@ -3749,6 +3866,7 @@ static BOOL get_user_sids(const char *domain, const char *user,
/**
* Get a list of all user tokens we want to look at
**/
+
static BOOL get_user_tokens(int *num_tokens, struct user_token **user_tokens)
{
struct winbindd_request request;
@@ -3884,19 +4002,22 @@ static BOOL get_user_tokens_from_file(FILE *f,
* Show the list of all users that have access to a share
*/
-static void show_userlist(struct cli_state *cli,
- TALLOC_CTX *mem_ctx, const char *netname,
- int num_tokens, struct user_token *tokens)
+static void show_userlist(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const char *netname,
+ int num_tokens,
+ struct user_token *tokens)
{
int fnum;
SEC_DESC *share_sd = NULL;
SEC_DESC *root_sd = NULL;
+ struct cli_state *cli = pipe_hnd->cli;
int i;
SRV_SHARE_INFO info;
WERROR result;
uint16 cnum;
- result = cli_srvsvc_net_share_get_info(cli, mem_ctx, netname,
+ result = rpccli_srvsvc_net_share_get_info(pipe_hnd, mem_ctx, netname,
502, &info);
if (!W_ERROR_IS_OK(result)) {
@@ -4005,12 +4126,13 @@ static void rpc_share_userlist_usage(void)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
int ret;
BOOL r;
@@ -4073,7 +4195,7 @@ rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
d_printf("%s\n", netname);
- show_userlist(cli, mem_ctx, netname,
+ show_userlist(pipe_hnd, mem_ctx, netname,
num_tokens, tokens);
}
done:
@@ -4086,8 +4208,7 @@ rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
return NT_STATUS_OK;
}
-static int
-rpc_share_allowedusers(int argc, const char **argv)
+static int rpc_share_allowedusers(int argc, const char **argv)
{
int result;
@@ -4192,13 +4313,16 @@ static int rpc_file_usage(int argc, const char **argv)
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_file_close_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
- result = cli_srvsvc_net_file_close(cli, mem_ctx, atoi(argv[0]));
+ result = rpccli_srvsvc_net_file_close(pipe_hnd, mem_ctx, atoi(argv[0]));
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -4257,10 +4381,13 @@ static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx, int argc, const char **argv)
+static NTSTATUS rpc_file_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
SRV_FILE_INFO_CTR ctr;
WERROR result;
@@ -4274,8 +4401,8 @@ rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
if (argc > 0)
username = smb_xstrdup(argv[0]);
- result = cli_srvsvc_net_file_enum(
- cli, mem_ctx, 3, username, &ctr, preferred_len, &hnd);
+ result = rpccli_srvsvc_net_file_enum(pipe_hnd,
+ mem_ctx, 3, username, &ctr, preferred_len, &hnd);
if (!W_ERROR_IS_OK(result))
goto done;
@@ -4293,7 +4420,6 @@ rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-
/**
* List files for a user on a remote RPC server
*
@@ -4303,6 +4429,7 @@ rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name,
*
* @return A shell status integer (0 for success)
**/
+
static int rpc_file_user(int argc, const char **argv)
{
if (argc < 1) {
@@ -4315,7 +4442,6 @@ static int rpc_file_user(int argc, const char **argv)
argc, argv);
}
-
/**
* 'net rpc file' entrypoint.
* @param argc Standard main() style argc
@@ -4342,10 +4468,6 @@ int net_rpc_file(int argc, const char **argv)
return net_run_function(argc, argv, func, rpc_file_usage);
}
-/****************************************************************************/
-
-
-
/**
* ABORT the shutdown of a remote RPC Server over, initshutdown pipe
*
@@ -4363,14 +4485,16 @@ int net_rpc_file(int argc, const char **argv)
**/
static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = cli_shutdown_abort(cli, mem_ctx);
+ result = rpccli_shutdown_abort(pipe_hnd, mem_ctx);
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown successfully aborted\n");
@@ -4381,7 +4505,6 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
return result;
}
-
/**
* ABORT the shutdown of a remote RPC Server, over winreg pipe
*
@@ -4399,14 +4522,16 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
**/
static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = werror_to_ntstatus(cli_reg_abort_shutdown(cli, mem_ctx));
+ result = werror_to_ntstatus(rpccli_reg_abort_shutdown(pipe_hnd, mem_ctx));
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown successfully aborted\n");
@@ -4460,10 +4585,12 @@ static int rpc_shutdown_abort(int argc, const char **argv)
**/
static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *msg = "This machine will be shutdown shortly";
@@ -4471,16 +4598,13 @@ static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
if (opt_comment) {
msg = opt_comment;
- } else {
- msg = "";
}
-
if (opt_timeout) {
timeout = opt_timeout;
}
/* create an entry */
- result = cli_shutdown_init(cli, mem_ctx, msg, timeout, opt_reboot,
+ result = rpccli_shutdown_init(pipe_hnd, mem_ctx, msg, timeout, opt_reboot,
opt_force);
if (NT_STATUS_IS_OK(result)) {
@@ -4509,10 +4633,12 @@ static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
**/
static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *msg = "This machine will be shutdown shortly";
@@ -4550,7 +4676,7 @@ static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
}
/* create an entry */
- result = werror_to_ntstatus(cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force));
+ result = werror_to_ntstatus(rpccli_reg_shutdown(pipe_hnd, mem_ctx, msg, timeout, opt_reboot, opt_force));
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown of remote machine succeeded\n");
@@ -4607,10 +4733,13 @@ static int rpc_shutdown(int argc, const char **argv)
*/
static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
@@ -4633,14 +4762,14 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
strupper_m(acct_name);
/* Get samr policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
@@ -4652,7 +4781,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
unknown = 0xe00500b0; /* No idea what this is - a permission mask?
mimir: yes, most probably it is */
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
acct_name, acb_info, unknown,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result)) {
@@ -4688,7 +4817,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
ctr.info.id23 = &p23;
p23.passmustchange = 0;
- result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 23,
+ result = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 23,
&cli->user_session_key, &ctr);
if (!NT_STATUS_IS_OK(result)) {
@@ -4740,10 +4869,13 @@ static int rpc_trustdom_add(int argc, const char **argv)
*/
static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv) {
-
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
POLICY_HND connect_pol, domain_pol, user_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
@@ -4772,21 +4904,21 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
/* Get samr policy handle */
- result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ result = rpccli_samr_connect(pipe_hnd, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
/* Get domain policy handle */
- result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ result = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
domain_sid, &domain_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, 1,
+ result = rpccli_samr_lookup_names(pipe_hnd, mem_ctx, &domain_pol, flags, 1,
names, &num_rids,
&user_rids, &name_types);
@@ -4794,7 +4926,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
goto done;
}
- result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rids[0], &user_pol);
@@ -4810,7 +4942,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
/* remove the sid */
- result = cli_samr_remove_sid_foreign_domain(cli, mem_ctx, &user_pol,
+ result = rpccli_samr_remove_sid_foreign_domain(pipe_hnd, mem_ctx, &user_pol,
&trust_acct_sid);
if (!NT_STATUS_IS_OK(result)) {
@@ -4819,7 +4951,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
/* Delete user */
- result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
+ result = rpccli_samr_delete_dom_user(pipe_hnd, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -4868,8 +5000,9 @@ static int rpc_trustdom_del(int argc, const char **argv)
static int rpc_trustdom_establish(int argc, const char **argv)
{
- struct cli_state *cli;
+ struct cli_state *cli = NULL;
struct in_addr server_ip;
+ struct rpc_pipe_client *pipe_hnd = NULL;
POLICY_HND connect_hnd;
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
@@ -4954,34 +5087,38 @@ static int rpc_trustdom_establish(int argc, const char **argv)
* Call LsaOpenPolicy and LsaQueryInfo
*/
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
cli_shutdown(cli);
return -1;
}
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
+ nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True, SEC_RIGHTS_QUERY_VALUE,
&connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
}
/* Querying info level 5 */
- nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
+ nt_status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &connect_hnd,
5 /* info level */,
&domain_name_pol, &domain_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
}
if (push_ucs2_talloc(mem_ctx, &uni_domain_name, domain_name_pol) == (size_t)-1) {
DEBUG(0, ("Could not convert domain name %s to unicode\n",
domain_name_pol));
+ cli_shutdown(cli);
return -1;
}
@@ -4998,6 +5135,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
opt_password,
*domain_sid)) {
DEBUG(0, ("Storing password for trusted domain failed.\n"));
+ cli_shutdown(cli);
return -1;
}
@@ -5005,16 +5143,14 @@ static int rpc_trustdom_establish(int argc, const char **argv)
* Close the pipes and clean up
*/
- nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
+ nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't close LSA pipe. Error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
}
- if (cli->pipes[cli->pipe_idx].fnum)
- cli_nt_session_close(cli);
-
cli_shutdown(cli);
talloc_destroy(mem_ctx);
@@ -5074,9 +5210,12 @@ static int rpc_trustdom_usage(int argc, const char **argv)
static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
fstring str_sid;
sid_to_string(str_sid, domain_sid);
@@ -5100,7 +5239,7 @@ static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
}
-static NTSTATUS vampire_trusted_domain(struct cli_state *cli,
+static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
DOM_SID dom_sid,
@@ -5112,7 +5251,7 @@ static NTSTATUS vampire_trusted_domain(struct cli_state *cli,
DATA_BLOB data;
smb_ucs2_t *uni_dom_name;
- nt_status = cli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, pol, 4, &dom_sid, &info);
+ nt_status = rpccli_lsa_query_trusted_domain_info_by_sid(pipe_hnd, mem_ctx, pol, 4, &dom_sid, &info);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0,("Could not query trusted domain info. Error was %s\n",
@@ -5125,7 +5264,7 @@ static NTSTATUS vampire_trusted_domain(struct cli_state *cli,
memcpy(data.data, info->password.password.data, info->password.password.length);
data.length = info->password.password.length;
- cleartextpwd = decrypt_trustdom_secret(cli->pwd.password, &data);
+ cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password, &data);
if (cleartextpwd == NULL) {
DEBUG(0,("retrieved NULL password\n"));
@@ -5164,7 +5303,8 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
{
/* common variables */
TALLOC_CTX* mem_ctx;
- struct cli_state *cli;
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
NTSTATUS nt_status;
const char *domain_name = NULL;
DOM_SID *queried_dom_sid;
@@ -5204,27 +5344,32 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
return -1;
};
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
+ nt_errstr(nt_status) ));
+ cli_shutdown(cli);
return -1;
};
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
+ nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
&connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
};
/* query info level 5 to obtain sid of a domain being queried */
- nt_status = cli_lsa_query_info_policy(
- cli, mem_ctx, &connect_hnd, 5 /* info level */,
+ nt_status = rpccli_lsa_query_info_policy(
+ pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
&dummy, &queried_dom_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
}
@@ -5236,13 +5381,14 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
d_printf("Vampire trusted domains:\n\n");
do {
- nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
+ nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
&num_domains,
&trusted_dom_names, &domain_sids);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
};
@@ -5250,10 +5396,12 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
- nt_status = vampire_trusted_domain(cli, mem_ctx, &connect_hnd,
+ nt_status = vampire_trusted_domain(pipe_hnd, mem_ctx, &connect_hnd,
domain_sids[i], trusted_dom_names[i]);
- if (!NT_STATUS_IS_OK(nt_status))
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ cli_shutdown(cli);
return -1;
+ }
};
/*
@@ -5265,15 +5413,15 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
/* close this connection before doing next one */
- nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
+ nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
nt_errstr(nt_status)));
+ cli_shutdown(cli);
return -1;
};
/* close lsarpc pipe and connection to IPC$ */
- cli_nt_session_close(cli);
cli_shutdown(cli);
talloc_destroy(mem_ctx);
@@ -5284,7 +5432,8 @@ static int rpc_trustdom_list(int argc, const char **argv)
{
/* common variables */
TALLOC_CTX* mem_ctx;
- struct cli_state *cli, *remote_cli;
+ struct cli_state *cli = NULL, *remote_cli = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
NTSTATUS nt_status;
const char *domain_name = NULL;
DOM_SID *queried_dom_sid;
@@ -5331,12 +5480,14 @@ static int rpc_trustdom_list(int argc, const char **argv)
return -1;
};
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Could not initialise lsa pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
+ nt_errstr(nt_status) ));
return -1;
};
- nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
+ nt_status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
&connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
@@ -5345,8 +5496,8 @@ static int rpc_trustdom_list(int argc, const char **argv)
};
/* query info level 5 to obtain sid of a domain being queried */
- nt_status = cli_lsa_query_info_policy(
- cli, mem_ctx, &connect_hnd, 5 /* info level */,
+ nt_status = rpccli_lsa_query_info_policy(
+ pipe_hnd, mem_ctx, &connect_hnd, 5 /* info level */,
&dummy, &queried_dom_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
@@ -5363,7 +5514,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
d_printf("Trusted domains list:\n\n");
do {
- nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
+ nt_status = rpccli_lsa_enum_trust_dom(pipe_hnd, mem_ctx, &connect_hnd, &enum_ctx,
&num_domains,
&trusted_dom_names, &domain_sids);
@@ -5386,14 +5537,14 @@ static int rpc_trustdom_list(int argc, const char **argv)
} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
/* close this connection before doing next one */
- nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
+ nt_status = rpccli_lsa_close(pipe_hnd, mem_ctx, &connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
nt_errstr(nt_status)));
return -1;
};
- cli_nt_session_close(cli);
+ cli_rpc_pipe_close(pipe_hnd);
/*
* Listing trusting domains (stored in passdb backend, if local)
@@ -5404,13 +5555,14 @@ static int rpc_trustdom_list(int argc, const char **argv)
/*
* Open \PIPE\samr and get needed policy handles
*/
- if (!cli_nt_session_open(cli, PI_SAMR)) {
- DEBUG(0, ("Could not initialise samr pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &nt_status);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
return -1;
};
/* SamrConnect */
- nt_status = cli_samr_connect(cli, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
+ nt_status = rpccli_samr_connect(pipe_hnd, mem_ctx, SA_RIGHT_SAM_OPEN_DOMAIN,
&connect_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
@@ -5420,7 +5572,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
/* SamrOpenDomain - we have to open domain policy handle in order to be
able to enumerate accounts*/
- nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
+ nt_status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &connect_hnd,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
queried_dom_sid, &domain_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -5436,7 +5588,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
enum_ctx = 0; /* reset enumeration context from last enumeration */
do {
- nt_status = cli_samr_enum_dom_users(cli, mem_ctx, &domain_hnd,
+ nt_status = rpccli_samr_enum_dom_users(pipe_hnd, mem_ctx, &domain_hnd,
&enum_ctx, ACB_DOMTRUST, 0xffff,
&trusting_dom_names, &trusting_dom_rids,
&num_domains);
@@ -5490,18 +5642,17 @@ static int rpc_trustdom_list(int argc, const char **argv)
} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
/* close opened samr and domain policy handles */
- nt_status = cli_samr_close(cli, mem_ctx, &domain_hnd);
+ nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &domain_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Couldn't properly close domain policy handle for domain %s\n", domain_name));
};
- nt_status = cli_samr_close(cli, mem_ctx, &connect_hnd);
+ nt_status = rpccli_samr_close(pipe_hnd, mem_ctx, &connect_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Couldn't properly close samr policy handle for domain %s\n", domain_name));
};
/* close samr pipe and connection to IPC$ */
- cli_nt_session_close(cli);
cli_shutdown(cli);
talloc_destroy(mem_ctx);
@@ -5577,7 +5728,7 @@ BOOL net_rpc_check(unsigned flags)
/* dump sam database via samsync rpc calls */
static int rpc_samdump(int argc, const char **argv) {
- return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
+ return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
argc, argv);
}
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 8d19ad888f..6b762563b3 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -35,7 +35,6 @@
goto done; \
}
-
/**
* confirm that a domain join is still valid
*
@@ -44,44 +43,30 @@
**/
static int net_rpc_join_ok(const char *domain)
{
- struct cli_state *cli;
- uchar stored_md4_trust_password[16];
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
int retval = 1;
- uint32 channel;
+ NTSTATUS ret;
/* Connect to remote machine */
if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
return 1;
}
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
- goto done;
- }
+ pipe_hnd = cli_rpc_pipe_open_schannel(cli, PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain, &ret);
- if (!secrets_fetch_trust_account_password(domain,
- stored_md4_trust_password,
- NULL, &channel)) {
- DEBUG(0,("Could not retreive domain trust secret"));
+ if (!pipe_hnd) {
+ DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n", nt_errstr(ret) ));
goto done;
}
-
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, domain);
- if (! NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, channel, stored_md4_trust_password))) {
- DEBUG(0,("Error in domain join verfication (fresh connection)\n"));
- goto done;
- }
-
+
retval = 0; /* Success! */
done:
- /* Close down pipe - this will clean up open policy handles */
- if (cli->pipes[cli->pipe_idx].fnum)
- cli_nt_session_close(cli);
cli_shutdown(cli);
-
return retval;
}
@@ -103,7 +88,10 @@ int net_rpc_join_newstyle(int argc, const char **argv)
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
uint32 acb_info = ACB_WSTRUST;
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
uint32 sec_channel_type;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ struct rpc_pipe_client *netlogon_schannel_pipe = NULL;
/* rpc variables */
@@ -151,7 +139,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
#endif
}
- /* Connect to remote machine */
+ /* Make authenticated connection to remote machine */
if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC)))
return 1;
@@ -163,38 +151,41 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Fetch domain sid */
- if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Error connecting to LSA pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n",
+ nt_errstr(result) ));
goto done;
}
- CHECK_RPC_ERR(cli_lsa_open_policy(cli, mem_ctx, True,
+ CHECK_RPC_ERR(rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&lsa_pol),
"error opening lsa policy handle");
- CHECK_RPC_ERR(cli_lsa_query_info_policy(cli, mem_ctx, &lsa_pol,
+ CHECK_RPC_ERR(rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx, &lsa_pol,
5, &domain, &domain_sid),
"error querying info policy");
- cli_lsa_close(cli, mem_ctx, &lsa_pol);
-
- cli_nt_session_close(cli); /* Done with this pipe */
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
+ cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
/* Create domain user */
- if (!cli_nt_session_open(cli, PI_SAMR)) {
- DEBUG(0, ("Error connecting to SAM pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
+ if (!pipe_hnd) {
+ DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n",
+ nt_errstr(result) ));
goto done;
}
- CHECK_RPC_ERR(cli_samr_connect(cli, mem_ctx,
+ CHECK_RPC_ERR(rpccli_samr_connect(pipe_hnd, mem_ctx,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&sam_pol),
"could not connect to SAM database");
- CHECK_RPC_ERR(cli_samr_open_domain(cli, mem_ctx, &sam_pol,
+ CHECK_RPC_ERR(rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol,
SEC_RIGHTS_MAXIMUM_ALLOWED,
domain_sid, &domain_pol),
"could not open domain");
@@ -204,7 +195,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
strlower_m(acct_name);
const_acct_name = acct_name;
- result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
acct_name, acb_info,
0xe005000b, &user_pol,
&user_rid);
@@ -225,10 +216,11 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* We *must* do this.... don't ask... */
- if (NT_STATUS_IS_OK(result))
- cli_samr_close(cli, mem_ctx, &user_pol);
+ if (NT_STATUS_IS_OK(result)) {
+ rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
+ }
- CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx,
+ CHECK_RPC_ERR_DEBUG(rpccli_samr_lookup_names(pipe_hnd, mem_ctx,
&domain_pol, flags,
1, &const_acct_name,
&num_rids,
@@ -246,7 +238,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Open handle on user */
CHECK_RPC_ERR_DEBUG(
- cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
SEC_RIGHTS_MAXIMUM_ALLOWED,
user_rid, &user_pol),
("could not re-open existing user %s: %s\n",
@@ -273,7 +265,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
ctr.switch_value = 24;
ctr.info.id24 = &p24;
- CHECK_RPC_ERR(cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
+ CHECK_RPC_ERR(rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, 24,
&cli->user_session_key, &ctr),
"error setting trust account password");
@@ -295,26 +287,52 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Ignoring the return value is necessary for joining a domain
as a normal user with "Add workstation to domain" privilege. */
- result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 16,
+ result = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16,
&cli->user_session_key, &ctr);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
+ cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
+
/* Now check the whole process from top-to-bottom */
- cli_samr_close(cli, mem_ctx, &user_pol);
- cli_nt_session_close(cli); /* Done with this pipe */
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0,("Error connecting to NETLOGON pipe\n"));
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
+ if (!pipe_hnd) {
+ DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n",
+ nt_errstr(result) ));
goto done;
}
- /* ensure that schannel uses the right domain */
- fstrcpy(cli->domain, domain);
+ result = rpccli_netlogon_setup_creds(pipe_hnd,
+ cli->desthost,
+ domain,
+ global_myname(),
+ md4_trust_password,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("Error in domain join verification (credential setup failed): %s\n\n",
+ nt_errstr(result)));
- result = cli_nt_establish_netlogon(cli, sec_channel_type,
- md4_trust_password);
+ if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
+ (sec_channel_type == SEC_CHAN_BDC) ) {
+ d_printf("Please make sure that no computer account\n"
+ "named like this machine (%s) exists in the domain\n",
+ global_myname());
+ }
+
+ goto done;
+ }
+
+ netlogon_schannel_pipe = cli_rpc_pipe_open_schannel_with_key(cli,
+ PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain,
+ pipe_hnd->dc,
+ &result);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("Error domain join verification (reused connection): %s\n\n",
+ DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n",
nt_errstr(result)));
if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
@@ -327,6 +345,9 @@ int net_rpc_join_newstyle(int argc, const char **argv)
goto done;
}
+ cli_rpc_pipe_close(pipe_hnd);
+ cli_rpc_pipe_close(netlogon_schannel_pipe);
+
/* Now store the secret in the secrets database */
strupper_m(domain);
@@ -344,10 +365,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
retval = net_rpc_join_ok(domain);
done:
- /* Close down pipe - this will clean up open policy handles */
-
- if (cli->pipes[cli->pipe_idx].fnum)
- cli_nt_session_close(cli);
/* Display success or failure */
@@ -364,7 +381,6 @@ done:
return retval;
}
-
/**
* check that a join is OK
*
diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c
index e82db46b9f..d8f3099dec 100644
--- a/source3/utils/net_rpc_printer.c
+++ b/source3/utils/net_rpc_printer.c
@@ -49,9 +49,11 @@ static const struct table_node archi_table[]= {
* possibly be removed later on
*
**/
+
/****************************************************************************
-convert a security permissions into a string
+ Convert a security permissions into a string.
****************************************************************************/
+
char *get_sec_mask_str(uint32 type)
{
static fstring typestr="";
@@ -86,10 +88,10 @@ char *get_sec_mask_str(uint32 type)
return typestr;
}
-
/****************************************************************************
- display sec_ace structure
+ Display sec_ace structure.
****************************************************************************/
+
void display_sec_ace(SEC_ACE *ace)
{
fstring sid_str;
@@ -119,10 +121,10 @@ void display_sec_ace(SEC_ACE *ace)
printf("\t\tSID: %s\n\n", sid_str);
}
-
/****************************************************************************
- display sec_acl structure
+ Display sec_acl structure.
****************************************************************************/
+
void display_sec_acl(SEC_ACL *sec_acl)
{
int i;
@@ -138,8 +140,9 @@ void display_sec_acl(SEC_ACL *sec_acl)
}
/****************************************************************************
- display sec_desc structure
+ Display sec_desc structure.
****************************************************************************/
+
void display_sec_desc(SEC_DESC *sec)
{
fstring sid_str;
@@ -175,8 +178,9 @@ void display_sec_desc(SEC_DESC *sec)
**/
/****************************************************************************
-printer info level 3 display function
+ Printer info level 3 display function.
****************************************************************************/
+
static void display_print_driver_3(DRIVER_INFO_3 *i1)
{
fstring name = "";
@@ -233,7 +237,6 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1)
return;
}
-
static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
{
pstring text;
@@ -275,7 +278,6 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
}
-
/**
* Copies ACLs, DOS-attributes and timestamps from one
* file or directory from one connected share to another connected share
@@ -292,6 +294,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
*
* @return Normal NTSTATUS return.
**/
+
NTSTATUS net_copy_fileattr(TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
@@ -310,7 +313,6 @@ NTSTATUS net_copy_fileattr(TALLOC_CTX *mem_ctx,
if (!copy_timestamps && !copy_acls && !copy_attrs)
return NT_STATUS_OK;
-
/* open file/dir on the originating server */
DEBUGADD(3,("opening %s %s on originating server\n",
@@ -429,7 +431,6 @@ out:
return nt_status;
}
-
/**
* Copy a file or directory from a connected share to another connected share
*
@@ -445,6 +446,7 @@ out:
*
* @return Normal NTSTATUS return.
**/
+
NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
@@ -605,7 +607,6 @@ out:
return nt_status;
}
-
/**
* Copy a driverfile from on connected share to another connected share
* This silently assumes that a driver-file is picked up from
@@ -625,6 +626,7 @@ out:
*
* @return Normal NTSTATUS return.
**/
+
static NTSTATUS net_copy_driverfile(TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
@@ -673,7 +675,6 @@ out:
return nt_status;
}
-
/**
* Check for existing Architecture directory on a given server
*
@@ -682,8 +683,8 @@ out:
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-check_arch_dir(struct cli_state *cli_share, const char *short_archi)
+
+static NTSTATUS check_arch_dir(struct cli_state *cli_share, const char *short_archi)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -715,7 +716,6 @@ out:
return nt_status;
}
-
/**
* Copy a print-driver (level 3) from one connected print$-share to another
* connected print$-share
@@ -728,8 +728,8 @@ out:
*
* @return Normal NTSTATUS return.
**/
-static NTSTATUS
-copy_print_driver_3(TALLOC_CTX *mem_ctx,
+
+static NTSTATUS copy_print_driver_3(TALLOC_CTX *mem_ctx,
struct cli_state *cli_share_src,
struct cli_state *cli_share_dst,
const char *short_archi, DRIVER_INFO_3 *i1)
@@ -799,7 +799,6 @@ copy_print_driver_3(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-
/**
* net_spoolss-functions
* =====================
@@ -812,16 +811,18 @@ copy_print_driver_3(TALLOC_CTX *mem_ctx,
*
**/
-static BOOL
-net_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *name, uint32 flags, uint32 level,
- uint32 *num_printers, PRINTER_INFO_CTR *ctr)
+static BOOL net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ char *name,
+ uint32 flags,
+ uint32 level,
+ uint32 *num_printers,
+ PRINTER_INFO_CTR *ctr)
{
-
WERROR result;
/* enum printers */
- result = cli_spoolss_enum_printers(cli, mem_ctx, name, flags,
+ result = rpccli_spoolss_enum_printers(pipe_hnd, mem_ctx, name, flags,
level, num_printers, ctr);
if (!W_ERROR_IS_OK(result)) {
@@ -832,16 +833,17 @@ net_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- const char *printername, uint32 access_required,
- const char *username, POLICY_HND *hnd)
+static BOOL net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ const char *printername,
+ uint32 access_required,
+ const char *username,
+ POLICY_HND *hnd)
{
WERROR result;
fstring servername, printername2;
- slprintf(servername, sizeof(servername)-1, "\\\\%s", cli->desthost);
+ slprintf(servername, sizeof(servername)-1, "\\\\%s", pipe_hnd->cli->desthost);
fstrcpy(printername2, servername);
fstrcat(printername2, "\\");
@@ -851,7 +853,7 @@ net_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
servername, username, printername2, access_required));
/* open printer */
- result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername2,
+ result = rpccli_spoolss_open_printer_ex(pipe_hnd, mem_ctx, printername2,
"", access_required,
servername, username, hnd);
@@ -874,16 +876,16 @@ net_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 level,
- PRINTER_INFO_CTR *ctr)
+static BOOL net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ uint32 level,
+ PRINTER_INFO_CTR *ctr)
{
WERROR result;
/* getprinter call */
- result = cli_spoolss_getprinter(cli, mem_ctx, hnd, level, ctr);
+ result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr);
if (!W_ERROR_IS_OK(result)) {
printf("cannot get printer-info: %s\n", dos_errstr(result));
@@ -893,16 +895,16 @@ net_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, uint32 level,
- PRINTER_INFO_CTR *ctr)
+static BOOL net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ uint32 level,
+ PRINTER_INFO_CTR *ctr)
{
WERROR result;
/* setprinter call */
- result = cli_spoolss_setprinter(cli, mem_ctx, hnd, level, ctr, 0);
+ result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0);
if (!W_ERROR_IS_OK(result)) {
printf("cannot set printer-info: %s\n", dos_errstr(result));
@@ -913,14 +915,15 @@ net_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
-static BOOL
-net_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, REGISTRY_VALUE *value)
+static BOOL net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ REGISTRY_VALUE *value)
{
WERROR result;
/* setprinterdata call */
- result = cli_spoolss_setprinterdata(cli, mem_ctx, hnd, value);
+ result = rpccli_spoolss_setprinterdata(pipe_hnd, mem_ctx, hnd, value);
if (!W_ERROR_IS_OK(result)) {
printf ("unable to set printerdata: %s\n", dos_errstr(result));
@@ -931,15 +934,16 @@ net_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
-static BOOL
-net_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, const char *keyname,
- uint16 **keylist)
+static BOOL net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ const char *keyname,
+ uint16 **keylist)
{
WERROR result;
/* enumprinterkey call */
- result = cli_spoolss_enumprinterkey(cli, mem_ctx, hnd, keyname, keylist, NULL);
+ result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, NULL);
if (!W_ERROR_IS_OK(result)) {
printf("enumprinterkey failed: %s\n", dos_errstr(result));
@@ -949,17 +953,17 @@ net_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 offered,
- POLICY_HND *hnd, const char *keyname,
- REGVAL_CTR *ctr)
+static BOOL net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ uint32 offered,
+ POLICY_HND *hnd,
+ const char *keyname,
+ REGVAL_CTR *ctr)
{
WERROR result;
/* enumprinterdataex call */
- result = cli_spoolss_enumprinterdataex(cli, mem_ctx, hnd, keyname, ctr);
+ result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, hnd, keyname, ctr);
if (!W_ERROR_IS_OK(result)) {
printf("enumprinterdataex failed: %s\n", dos_errstr(result));
@@ -970,15 +974,16 @@ net_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
-static BOOL
-net_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, char *keyname,
- REGISTRY_VALUE *value)
+static BOOL net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ char *keyname,
+ REGISTRY_VALUE *value)
{
WERROR result;
/* setprinterdataex call */
- result = cli_spoolss_setprinterdataex(cli, mem_ctx, hnd,
+ result = rpccli_spoolss_setprinterdataex(pipe_hnd, mem_ctx, hnd,
keyname, value);
if (!W_ERROR_IS_OK(result)) {
@@ -989,17 +994,18 @@ net_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hnd, int level, uint32 *num_forms,
- FORM_1 **forms)
+static BOOL net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hnd,
+ int level,
+ uint32 *num_forms,
+ FORM_1 **forms)
{
WERROR result;
/* enumforms call */
- result = cli_spoolss_enumforms(cli, mem_ctx, hnd, level, num_forms, forms);
+ result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx, hnd, level, num_forms, forms);
if (!W_ERROR_IS_OK(result)) {
printf("could not enum forms: %s\n", dos_errstr(result));
@@ -1009,18 +1015,17 @@ net_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_enumprinterdrivers (struct cli_state *cli, TALLOC_CTX *mem_ctx,
- uint32 level, const char *env,
- uint32 *num_drivers,
- PRINTER_DRIVER_CTR *ctr)
+static BOOL net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ uint32 level, const char *env,
+ uint32 *num_drivers,
+ PRINTER_DRIVER_CTR *ctr)
{
WERROR result;
/* enumprinterdrivers call */
- result = cli_spoolss_enumprinterdrivers(
- cli, mem_ctx, level,
+ result = rpccli_spoolss_enumprinterdrivers(
+ pipe_hnd, mem_ctx, level,
env, num_drivers, ctr);
if (!W_ERROR_IS_OK(result)) {
@@ -1031,9 +1036,7 @@ net_spoolss_enumprinterdrivers (struct cli_state *cli, TALLOC_CTX *mem_ctx,
return True;
}
-
-static BOOL
-net_spoolss_getprinterdriver(struct cli_state *cli,
+static BOOL net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
POLICY_HND *hnd, uint32 level,
const char *env, int version,
@@ -1042,8 +1045,8 @@ net_spoolss_getprinterdriver(struct cli_state *cli,
WERROR result;
/* getprinterdriver call */
- result = cli_spoolss_getprinterdriver(
- cli, mem_ctx, hnd, level,
+ result = rpccli_spoolss_getprinterdriver(
+ pipe_hnd, mem_ctx, hnd, level,
env, version, ctr);
if (!W_ERROR_IS_OK(result)) {
@@ -1060,15 +1063,14 @@ net_spoolss_getprinterdriver(struct cli_state *cli,
}
-static BOOL
-net_spoolss_addprinterdriver(struct cli_state *cli,
+static BOOL net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx, uint32 level,
PRINTER_DRIVER_CTR *ctr)
{
WERROR result;
/* addprinterdriver call */
- result = cli_spoolss_addprinterdriver(cli, mem_ctx, level, ctr);
+ result = rpccli_spoolss_addprinterdriver(pipe_hnd, mem_ctx, level, ctr);
/* be more verbose */
if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
@@ -1087,10 +1089,14 @@ net_spoolss_addprinterdriver(struct cli_state *cli,
* abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr
* for a single printer or for all printers depending on argc/argv
**/
-static BOOL
-get_printer_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int level, int argc, const char **argv,
- uint32 *num_printers, PRINTER_INFO_CTR *ctr)
+
+static BOOL get_printer_info(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int level,
+ int argc,
+ const char **argv,
+ uint32 *num_printers,
+ PRINTER_INFO_CTR *ctr)
{
POLICY_HND hnd;
@@ -1098,7 +1104,7 @@ get_printer_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* no arguments given, enumerate all printers */
if (argc == 0) {
- if (!net_spoolss_enum_printers(cli, mem_ctx, NULL,
+ if (!net_spoolss_enum_printers(pipe_hnd, mem_ctx, NULL,
PRINTER_ENUM_LOCAL|PRINTER_ENUM_SHARED,
level, num_printers, ctr))
return False;
@@ -1108,16 +1114,16 @@ get_printer_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* argument given, get a single printer by name */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, argv[0],
- MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd))
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0],
+ MAXIMUM_ALLOWED_ACCESS, pipe_hnd->cli->user_name, &hnd))
return False;
- if (!net_spoolss_getprinter(cli, mem_ctx, &hnd, level, ctr)) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, ctr)) {
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
return False;
}
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
*num_printers = 1;
@@ -1128,7 +1134,6 @@ out:
}
-
/**
* List print-queues (including local printers that are not shared)
*
@@ -1144,9 +1149,14 @@ out:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i, num_printers;
@@ -1156,7 +1166,7 @@ NTSTATUS rpc_printer_list_internals(const DOM_SID *domain_sid, const char *domai
printf("listing printers\n");
- if (!get_printer_info(cli, mem_ctx, level, argc, argv, &num_printers, &ctr))
+ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr))
return nt_status;
for (i = 0; i < num_printers; i++) {
@@ -1174,7 +1184,6 @@ NTSTATUS rpc_printer_list_internals(const DOM_SID *domain_sid, const char *domai
return NT_STATUS_OK;
}
-
/**
* List printer-drivers from a server
*
@@ -1190,9 +1199,14 @@ NTSTATUS rpc_printer_list_internals(const DOM_SID *domain_sid, const char *domai
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_driver_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_driver_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i;
@@ -1202,7 +1216,6 @@ NTSTATUS rpc_printer_driver_list_internals(const DOM_SID *domain_sid, const char
ZERO_STRUCT(drv_ctr_enum);
-
printf("listing printer-drivers\n");
for (i=0; archi_table[i].long_archi!=NULL; i++) {
@@ -1210,7 +1223,7 @@ NTSTATUS rpc_printer_driver_list_internals(const DOM_SID *domain_sid, const char
uint32 num_drivers;
/* enum remote drivers */
- if (!net_spoolss_enumprinterdrivers(cli, mem_ctx, level,
+ if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level,
archi_table[i].long_archi,
&num_drivers, &drv_ctr_enum)) {
@@ -1254,8 +1267,11 @@ done:
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv, uint32 action)
+static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv,
+ uint32 action)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i, num_printers;
@@ -1267,7 +1283,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
WERROR result;
const char *action_str;
- if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+ if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr))
return nt_status;
for (i = 0; i < num_printers; i++) {
@@ -1279,14 +1295,14 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
sizeof(sharename), -1, STR_TERMINATE);
/* open printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
- PRINTER_ALL_ACCESS, cli->user_name, &hnd))
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
+ PRINTER_ALL_ACCESS, pipe_hnd->cli->user_name, &hnd))
goto done;
got_hnd = True;
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli, mem_ctx, &hnd, level, &ctr_pub))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub))
goto done;
/* check action and set string */
@@ -1308,7 +1324,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
ctr_pub.printers_7->action = action;
- result = cli_spoolss_setprinter(cli, mem_ctx, &hnd, level, &ctr_pub, 0);
+ result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0);
if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) {
printf("cannot set printer-info: %s\n", dos_errstr(result));
goto done;
@@ -1321,30 +1337,42 @@ static NTSTATUS rpc_printer_publish_internals_args(struct cli_state *cli, TALLOC
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
return nt_status;
}
-NTSTATUS rpc_printer_publish_publish_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+NTSTATUS rpc_printer_publish_publish_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
- return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_PUBLISH);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_PUBLISH);
}
-NTSTATUS rpc_printer_publish_unpublish_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+NTSTATUS rpc_printer_publish_unpublish_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
- return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH);
}
-NTSTATUS rpc_printer_publish_update_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+NTSTATUS rpc_printer_publish_update_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
- return rpc_printer_publish_internals_args(cli, mem_ctx, argc, argv, SPOOL_DS_UPDATE);
+ return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UPDATE);
}
/**
@@ -1362,9 +1390,14 @@ NTSTATUS rpc_printer_publish_update_internals(const DOM_SID *domain_sid, const c
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i, num_printers;
@@ -1376,7 +1409,7 @@ NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid, const cha
BOOL got_hnd = False;
int state;
- if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
+ if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr))
return nt_status;
for (i = 0; i < num_printers; i++) {
@@ -1390,14 +1423,14 @@ NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid, const cha
sizeof(sharename), -1, STR_TERMINATE);
/* open printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli->user_name, &hnd))
goto done;
got_hnd = True;
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli, mem_ctx, &hnd, level, &ctr_pub))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub))
goto done;
rpcstr_pull(guid, ctr_pub.printers_7->guid.buffer, sizeof(guid), -1, STR_TERMINATE);
@@ -1426,7 +1459,7 @@ NTSTATUS rpc_printer_publish_list_internals(const DOM_SID *domain_sid, const cha
done:
if (got_hnd)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
return nt_status;
}
@@ -1446,9 +1479,14 @@ done:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
/* TODO: what now, info2 or info3 ?
convince jerry that we should add clientside setacls level 3 at least
@@ -1460,7 +1498,7 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
pstring printername = "", sharename = "";
BOOL got_hnd_src = False;
BOOL got_hnd_dst = False;
- BOOL got_dst_spoolss_pipe = False;
+ struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum;
struct cli_state *cli_dst = NULL;
@@ -1470,13 +1508,13 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
DEBUG(3,("copying printer ACLs\n"));
/* connect destination PI_SPOOLSS */
- nt_status = connect_dst_pipe(&cli_dst, PI_SPOOLSS, &got_dst_spoolss_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
/* enum source printers */
- if (!get_printer_info(cli, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1487,7 +1525,6 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
goto done;
}
-
/* do something for all printers */
for (i = 0; i < num_printers; i++) {
@@ -1510,30 +1547,27 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
*/
/* open src printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
got_hnd_src = True;
-
/* open dst printer handle */
- if (!net_spoolss_open_printer_ex(cli_dst, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
goto done;
got_hnd_dst = True;
-
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
goto done;
/* check for existing src printer */
- if (!net_spoolss_getprinter(cli, mem_ctx, &hnd_src, 3, &ctr_src))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &ctr_src))
goto done;
-
/* Copy Security Descriptor */
/* copy secdesc (info level 2) */
@@ -1543,7 +1577,7 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
if (opt_verbose)
display_sec_desc(ctr_dst.printers_2->secdesc);
- if (!net_spoolss_setprinter(cli_dst, mem_ctx, &hnd_dst, 2, &ctr_dst))
+ if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &ctr_dst))
goto done;
DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n"));
@@ -1551,12 +1585,12 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
/* close printer handles here */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
@@ -1566,20 +1600,20 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
done:
- if (got_hnd_src)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ if (got_hnd_src) {
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
+ }
- if (got_hnd_dst)
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ if (got_hnd_dst) {
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
+ }
- if (got_dst_spoolss_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
return nt_status;
}
-
/**
* Migrate printer-forms from a src server to the dst server
*
@@ -1595,9 +1629,14 @@ done:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
WERROR result;
@@ -1607,7 +1646,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
pstring printername = "", sharename = "";
BOOL got_hnd_src = False;
BOOL got_hnd_dst = False;
- BOOL got_dst_spoolss_pipe = False;
+ struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
PRINTER_INFO_CTR ctr_enum, ctr_dst;
uint32 num_forms;
@@ -1619,13 +1658,13 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
DEBUG(3,("copying forms\n"));
/* connect destination PI_SPOOLSS */
- nt_status = connect_dst_pipe(&cli_dst, PI_SPOOLSS, &got_dst_spoolss_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
/* enum src printers */
- if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr_enum)) {
+ if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr_enum)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1654,7 +1693,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
/* open src printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
@@ -1662,7 +1701,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
/* open dst printer handle */
- if (!net_spoolss_open_printer_ex(cli_dst, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
goto done;
@@ -1670,11 +1709,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst))
goto done;
/* finally migrate forms */
- if (!net_spoolss_enumforms(cli, mem_ctx, &hnd_src, level, &num_forms, &forms))
+ if (!net_spoolss_enumforms(pipe_hnd, mem_ctx, &hnd_src, level, &num_forms, &forms))
goto done;
DEBUG(1,("got %d forms for printer\n", num_forms));
@@ -1711,7 +1750,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
/* FIXME: there might be something wrong with samba's
builtin-forms */
- result = cli_spoolss_addform(cli_dst, mem_ctx,
+ result = rpccli_spoolss_addform(pipe_hnd_dst, mem_ctx,
&hnd_dst, 1, &form);
if (!W_ERROR_IS_OK(result)) {
d_printf("\tAddForm form %d: [%s] refused.\n",
@@ -1725,12 +1764,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
/* close printer handles here */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
}
@@ -1740,20 +1779,17 @@ NTSTATUS rpc_printer_migrate_forms_internals(const DOM_SID *domain_sid, const ch
done:
if (got_hnd_src)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
if (got_hnd_dst)
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
- if (got_dst_spoolss_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
return nt_status;
-
}
-
/**
* Migrate printer-drivers from a src server to the dst server
*
@@ -1769,9 +1805,14 @@ done:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uint32 i, p;
@@ -1780,9 +1821,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
pstring printername = "", sharename = "";
BOOL got_hnd_src = False;
BOOL got_hnd_dst = False;
- BOOL got_dst_spoolss_pipe = False;
BOOL got_src_driver_share = False;
BOOL got_dst_driver_share = False;
+ struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
PRINTER_DRIVER_CTR drv_ctr_src, drv_ctr_dst;
PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst;
@@ -1799,7 +1840,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
DEBUG(3,("copying printer-drivers\n"));
- nt_status = connect_dst_pipe(&cli_dst, PI_SPOOLSS, &got_dst_spoolss_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
@@ -1823,7 +1864,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
/* enum src printers */
- if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &info_ctr_enum)) {
+ if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_ctr_enum)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1851,20 +1892,20 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
printername, sharename);
/* open dst printer handle */
- if (!net_spoolss_open_printer_ex(cli_dst, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
goto done;
got_hnd_dst = True;
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst))
goto done;
/* open src printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
- MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
+ MAXIMUM_ALLOWED_ACCESS, pipe_hnd->cli->user_name, &hnd_src))
goto done;
got_hnd_src = True;
@@ -1876,7 +1917,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
for (i=0; archi_table[i].long_archi!=NULL; i++) {
/* getdriver src */
- if (!net_spoolss_getprinterdriver(cli, mem_ctx, &hnd_src,
+ if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src,
level, archi_table[i].long_archi,
archi_table[i].version, &drv_ctr_src))
continue;
@@ -1903,7 +1944,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
/* adddriver dst */
- if (!net_spoolss_addprinterdriver(cli_dst, mem_ctx, level, &drv_ctr_src)) {
+ if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_ctr_src)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1922,7 +1963,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
/* setdriver dst */
init_unistr(&info_ctr_dst.printers_2->drivername, drivername);
- if (!net_spoolss_setprinter(cli_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) {
+ if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1932,13 +1973,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
/* close dst */
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
/* close src */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
}
@@ -1948,13 +1989,12 @@ NTSTATUS rpc_printer_migrate_drivers_internals(const DOM_SID *domain_sid, const
done:
if (got_hnd_src)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
if (got_hnd_dst)
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
- if (got_dst_spoolss_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
@@ -1968,7 +2008,6 @@ done:
}
-
/**
* Migrate printer-queues from a src to the dst server
* (requires a working "addprinter command" to be installed for the local smbd)
@@ -1985,9 +2024,14 @@ done:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -1999,18 +2043,18 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
pstring printername, sharename;
BOOL got_hnd_src = False;
BOOL got_hnd_dst = False;
- BOOL got_dst_spoolss_pipe = False;
+ struct rpc_pipe_client *pipe_hnd_dst = NULL;
DEBUG(3,("copying printers\n"));
/* connect destination PI_SPOOLSS */
- nt_status = connect_dst_pipe(&cli_dst, PI_SPOOLSS, &got_dst_spoolss_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
/* enum printers */
- if (!get_printer_info(cli, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -2039,7 +2083,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
/* open dst printer handle */
- if (!net_spoolss_open_printer_ex(cli_dst, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) {
DEBUG(1,("could not open printer: %s\n", sharename));
@@ -2049,18 +2093,18 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) {
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) {
printf ("could not get printer, creating printer.\n");
} else {
DEBUG(1,("printer already exists: %s\n", sharename));
/* close printer handles here */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
continue;
@@ -2071,21 +2115,21 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
we first need a handle for that */
/* open src printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
got_hnd_src = True;
/* getprinter on the src server */
- if (!net_spoolss_getprinter(cli, mem_ctx, &hnd_src, level, &ctr_src))
+ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src))
goto done;
/* copy each src printer to a dst printer 1:1,
maybe some values have to be changed though */
d_printf("creating printer: %s\n", printername);
- result = cli_spoolss_addprinterex (cli_dst, mem_ctx, level, &ctr_src);
+ result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src);
if (W_ERROR_IS_OK(result))
d_printf ("printer [%s] successfully added.\n", printername);
@@ -2098,12 +2142,12 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
/* close printer handles here */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
}
@@ -2112,19 +2156,17 @@ NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const
done:
if (got_hnd_src)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
if (got_hnd_dst)
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
- if (got_dst_spoolss_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
return nt_status;
}
-
/**
* Migrate Printer-Settings from a src server to the dst server
* (for this to work, printers and drivers already have to be migrated earlier)
@@ -2141,9 +2183,14 @@ done:
*
* @return Normal NTSTATUS return.
**/
-NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+
+NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
/* FIXME: Here the nightmare begins */
@@ -2156,7 +2203,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
pstring printername = "", sharename = "";
BOOL got_hnd_src = False;
BOOL got_hnd_dst = False;
- BOOL got_dst_spoolss_pipe = False;
+ struct rpc_pipe_client *pipe_hnd_dst = NULL;
POLICY_HND hnd_src, hnd_dst;
PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish;
REGVAL_CTR *reg_ctr;
@@ -2171,13 +2218,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
DEBUG(3,("copying printer settings\n"));
/* connect destination PI_SPOOLSS */
- nt_status = connect_dst_pipe(&cli_dst, PI_SPOOLSS, &got_dst_spoolss_pipe);
+ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
/* enum src printers */
- if (!get_printer_info(cli, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
+ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -2210,7 +2257,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* open src printer handle */
- if (!net_spoolss_open_printer_ex(cli, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
goto done;
@@ -2218,7 +2265,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* open dst printer handle */
- if (!net_spoolss_open_printer_ex(cli_dst, mem_ctx, sharename,
+ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
goto done;
@@ -2226,7 +2273,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst,
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
level, &ctr_dst))
goto done;
@@ -2245,13 +2292,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
/* check for existing dst printer */
- if (!net_spoolss_getprinter(cli_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish))
+ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish))
goto done;
ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH;
/* ignore False from setprinter due to WERR_IO_PENDING */
- net_spoolss_setprinter(cli_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish);
+ net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish);
DEBUG(3,("republished printer\n"));
}
@@ -2278,7 +2325,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
init_unistr(&ctr_dst.printers_2->devmode->devicename,
devicename);
#endif
- if (!net_spoolss_setprinter(cli_dst, mem_ctx, &hnd_dst,
+ if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
level, &ctr_dst))
goto done;
@@ -2288,13 +2335,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* STEP 2: COPY REGISTRY VALUES */
/* please keep in mind that samba parse_spools gives horribly
- crippled results when used to cli_spoolss_enumprinterdataex
+ crippled results when used to rpccli_spoolss_enumprinterdataex
a win2k3-server. (Bugzilla #1851)
FIXME: IIRC I've seen it too on a win2k-server
*/
/* enumerate data on src handle */
- result = cli_spoolss_enumprinterdata(cli, mem_ctx, &hnd_src, p, 0, 0,
+ result = rpccli_spoolss_enumprinterdata(pipe_hnd, mem_ctx, &hnd_src, p, 0, 0,
&val_needed, &data_needed, NULL);
/* loop for all printerdata of "PrinterDriverData" */
@@ -2302,8 +2349,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
REGISTRY_VALUE value;
- result = cli_spoolss_enumprinterdata(
- cli, mem_ctx, &hnd_src, p++, val_needed,
+ result = rpccli_spoolss_enumprinterdata(
+ pipe_hnd, mem_ctx, &hnd_src, p++, val_needed,
data_needed, 0, 0, &value);
/* loop for all reg_keys */
@@ -2314,7 +2361,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
display_reg_value(SPOOL_PRINTERDATA_KEY, value);
/* set_value */
- if (!net_spoolss_setprinterdata(cli_dst, mem_ctx,
+ if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx,
&hnd_dst, &value))
goto done;
@@ -2330,7 +2377,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
respond to enumprinterkey, win2k does, so continue
in case of an error */
- if (!net_spoolss_enumprinterkey(cli, mem_ctx, &hnd_src, "", &keylist)) {
+ if (!net_spoolss_enumprinterkey(pipe_hnd, mem_ctx, &hnd_src, "", &keylist)) {
printf("got no key-data\n");
continue;
}
@@ -2355,7 +2402,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
return NT_STATUS_NO_MEMORY;
/* enumerate all src subkeys */
- if (!net_spoolss_enumprinterdataex(cli, mem_ctx, 0,
+ if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0,
&hnd_src, subkey,
reg_ctr))
goto done;
@@ -2426,7 +2473,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
display_reg_value(subkey, value);
/* here we have to set all subkeys on the dst server */
- if (!net_spoolss_setprinterdataex(cli_dst, mem_ctx, &hnd_dst,
+ if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
subkey, &value))
goto done;
@@ -2436,7 +2483,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
display_reg_value(subkey, *(reg_ctr->values[j]));
/* here we have to set all subkeys on the dst server */
- if (!net_spoolss_setprinterdataex(cli_dst, mem_ctx, &hnd_dst,
+ if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
subkey, reg_ctr->values[j]))
goto done;
@@ -2446,7 +2493,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
subkey, reg_ctr->values[j]->valuename));
}
-
+
TALLOC_FREE( reg_ctr );
}
@@ -2454,12 +2501,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const
/* close printer handles here */
if (got_hnd_src) {
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
got_hnd_src = False;
}
if (got_hnd_dst) {
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
got_hnd_dst = False;
}
@@ -2473,13 +2520,12 @@ done:
SAFE_FREE(unc_name);
if (got_hnd_src)
- cli_spoolss_close_printer(cli, mem_ctx, &hnd_src);
+ rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src);
if (got_hnd_dst)
- cli_spoolss_close_printer(cli_dst, mem_ctx, &hnd_dst);
+ rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst);
- if (got_dst_spoolss_pipe) {
- cli_nt_session_close(cli_dst);
+ if (cli_dst) {
cli_shutdown(cli_dst);
}
return nt_status;
diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c
index 8bb01cd89a..33ccb6c1b7 100644
--- a/source3/utils/net_rpc_registry.c
+++ b/source3/utils/net_rpc_registry.c
@@ -22,7 +22,6 @@
#include "regfio.h"
#include "reg_objects.h"
-
/********************************************************************
********************************************************************/
@@ -85,9 +84,13 @@ void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
WERROR result = WERR_GENERAL_FAILURE;
uint32 hive;
@@ -108,13 +111,13 @@ static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, cons
/* open the top level hive and then the registry key */
- result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
+ result = rpccli_reg_connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Unable to connect to remote registry\n");
return werror_to_ntstatus(result);
}
- result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
+ result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Unable to open [%s]\n", argv[0]);
return werror_to_ntstatus(result);
@@ -128,7 +131,7 @@ static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, cons
time_t modtime;
fstring keyname, classname;
- result = cli_reg_enum_key( cli, mem_ctx, &pol_key, idx,
+ result = rpccli_reg_enum_key(pipe_hnd, mem_ctx, &pol_key, idx,
keyname, classname, &modtime );
if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
@@ -159,7 +162,7 @@ static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, cons
fstrcpy( name, "" );
ZERO_STRUCT( value );
- result = cli_reg_enum_val( cli, mem_ctx, &pol_key, idx,
+ result = rpccli_reg_enum_val(pipe_hnd, mem_ctx, &pol_key, idx,
name, &type, &value );
if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
@@ -180,8 +183,8 @@ static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, cons
out:
/* cleanup */
- cli_reg_close( cli, mem_ctx, &pol_key );
- cli_reg_close( cli, mem_ctx, &pol_hive );
+ rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
+ rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
return werror_to_ntstatus(result);
}
@@ -198,9 +201,13 @@ static int rpc_registry_enumerate( int argc, const char **argv )
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_registry_save_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
WERROR result = WERR_GENERAL_FAILURE;
uint32 hive;
@@ -219,19 +226,19 @@ static NTSTATUS rpc_registry_save_internal( const DOM_SID *domain_sid, const cha
/* open the top level hive and then the registry key */
- result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
+ result = rpccli_reg_connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Unable to connect to remote registry\n");
return werror_to_ntstatus(result);
}
- result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
+ result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Unable to open [%s]\n", argv[0]);
return werror_to_ntstatus(result);
}
- result = cli_reg_save_key( cli, mem_ctx, &pol_key, argv[1] );
+ result = rpccli_reg_save_key(pipe_hnd, mem_ctx, &pol_key, argv[1] );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
}
@@ -239,8 +246,8 @@ static NTSTATUS rpc_registry_save_internal( const DOM_SID *domain_sid, const cha
/* cleanup */
- cli_reg_close( cli, mem_ctx, &pol_key );
- cli_reg_close( cli, mem_ctx, &pol_hive );
+ rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
+ rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
return werror_to_ntstatus(result);
}
@@ -490,5 +497,3 @@ int net_rpc_registry(int argc, const char **argv)
return net_help_registry( argc, argv );
}
-
-
diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c
index 3a986ed251..a563475ee1 100644
--- a/source3/utils/net_rpc_rights.c
+++ b/source3/utils/net_rpc_rights.c
@@ -23,22 +23,23 @@
/********************************************************************
********************************************************************/
-static NTSTATUS sid_to_name(struct cli_state *cli,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid, fstring name)
+static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid,
+ fstring name)
{
POLICY_HND pol;
uint32 *sid_types;
NTSTATUS result;
char **domains, **names;
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
if ( !NT_STATUS_IS_OK(result) )
return result;
- result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
+ result = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
if ( NT_STATUS_IS_OK(result) ) {
if ( *domains[0] )
@@ -47,14 +48,14 @@ static NTSTATUS sid_to_name(struct cli_state *cli,
fstrcpy( name, names[0] );
}
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
return result;
}
/********************************************************************
********************************************************************/
-static NTSTATUS name_to_sid(struct cli_state *cli,
+static NTSTATUS name_to_sid(struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
DOM_SID *sid, const char *name)
{
@@ -64,31 +65,31 @@ static NTSTATUS name_to_sid(struct cli_state *cli,
DOM_SID *sids;
/* maybe its a raw SID */
- if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) )
- {
+ if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) ) {
return NT_STATUS_OK;
}
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
if ( !NT_STATUS_IS_OK(result) )
return result;
- result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
+ result = rpccli_lsa_lookup_names(pipe_hnd, mem_ctx, &pol, 1, &name, &sids, &sid_types);
if ( NT_STATUS_IS_OK(result) )
sid_copy( sid, &sids[0] );
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
return result;
}
/********************************************************************
********************************************************************/
-static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
- POLICY_HND *pol )
+static NTSTATUS enum_privileges(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *ctx,
+ POLICY_HND *pol )
{
NTSTATUS result;
uint32 enum_context = 0;
@@ -103,7 +104,7 @@ static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
uint16 lang_id_desc;
fstring description;
- result = cli_lsa_enum_privilege(cli, ctx, pol, &enum_context,
+ result = rpccli_lsa_enum_privilege(pipe_hnd, ctx, pol, &enum_context,
pref_max_length, &count, &privs_name, &privs_high, &privs_low);
if ( !NT_STATUS_IS_OK(result) )
@@ -116,7 +117,7 @@ static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
/* try to get the description */
- if ( !NT_STATUS_IS_OK(cli_lsa_get_dispname(cli, ctx, pol,
+ if ( !NT_STATUS_IS_OK(rpccli_lsa_get_dispname(pipe_hnd, ctx, pol,
privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) )
{
d_printf("??????\n");
@@ -127,21 +128,23 @@ static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
}
return NT_STATUS_OK;
-
}
/********************************************************************
********************************************************************/
-static NTSTATUS check_privilege_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
- POLICY_HND *pol, DOM_SID *sid, const char *right)
+static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *ctx,
+ POLICY_HND *pol,
+ DOM_SID *sid,
+ const char *right)
{
NTSTATUS result;
uint32 count;
char **rights;
int i;
- result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
+ result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights);
if (!NT_STATUS_IS_OK(result)) {
return result;
@@ -163,15 +166,17 @@ static NTSTATUS check_privilege_for_user( TALLOC_CTX *ctx, struct cli_state *cli
/********************************************************************
********************************************************************/
-static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
- POLICY_HND *pol, DOM_SID *sid )
+static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *ctx,
+ POLICY_HND *pol,
+ DOM_SID *sid )
{
NTSTATUS result;
uint32 count;
char **rights;
int i;
- result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
+ result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights);
if (!NT_STATUS_IS_OK(result))
return result;
@@ -189,8 +194,10 @@ static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli
/********************************************************************
********************************************************************/
-static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *cli,
- POLICY_HND *pol, const char *privilege)
+static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *ctx,
+ POLICY_HND *pol,
+ const char *privilege)
{
NTSTATUS result;
uint32 enum_context=0;
@@ -200,7 +207,7 @@ static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *c
int i;
fstring name;
- result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
+ result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context,
pref_max_length, &count, &sids);
if (!NT_STATUS_IS_OK(result))
@@ -211,7 +218,7 @@ static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *c
for ( i=0; i<count; i++ ) {
- result = check_privilege_for_user( ctx, cli, pol, &sids[i], privilege);
+ result = check_privilege_for_user( pipe_hnd, ctx, pol, &sids[i], privilege);
if ( ! NT_STATUS_IS_OK(result)) {
if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
@@ -222,7 +229,7 @@ static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *c
/* try to convert the SID to a name. Fall back to
printing the raw SID if necessary */
- result = sid_to_name( cli, ctx, &sids[i], name );
+ result = sid_to_name( pipe_hnd, ctx, &sids[i], name );
if ( !NT_STATUS_IS_OK (result) )
fstrcpy( name, sid_string_static(&sids[i]) );
@@ -235,8 +242,9 @@ static NTSTATUS enum_accounts_for_privilege(TALLOC_CTX *ctx, struct cli_state *c
/********************************************************************
********************************************************************/
-static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli,
- POLICY_HND *pol )
+static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *ctx,
+ POLICY_HND *pol)
{
NTSTATUS result;
uint32 enum_context=0;
@@ -246,7 +254,7 @@ static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state
int i;
fstring name;
- result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
+ result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context,
pref_max_length, &count, &sids);
if (!NT_STATUS_IS_OK(result))
@@ -257,13 +265,13 @@ static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state
/* try to convert the SID to a name. Fall back to
printing the raw SID if necessary */
- result = sid_to_name( cli, ctx, &sids[i], name );
+ result = sid_to_name(pipe_hnd, ctx, &sids[i], name );
if ( !NT_STATUS_IS_OK (result) )
fstrcpy( name, sid_string_static(&sids[i]) );
d_printf("%s\n", name);
- result = enum_privileges_for_user( ctx, cli, pol, &sids[i] );
+ result = enum_privileges_for_user(pipe_hnd, ctx, pol, &sids[i] );
if ( !NT_STATUS_IS_OK(result) )
return result;
@@ -277,9 +285,13 @@ static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_rights_list_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND pol;
NTSTATUS result;
@@ -291,7 +303,7 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
uint16 lang_id_desc;
- result = cli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
if ( !NT_STATUS_IS_OK(result) )
@@ -300,7 +312,7 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
/* backwards compatibility; just list available privileges if no arguement */
if (argc == 0) {
- result = enum_privileges( mem_ctx, cli, &pol );
+ result = enum_privileges(pipe_hnd, mem_ctx, &pol );
goto done;
}
@@ -308,18 +320,17 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
int i = 1;
if (argv[1] == NULL) {
- result = enum_privileges( mem_ctx, cli, &pol );
+ result = enum_privileges(pipe_hnd, mem_ctx, &pol );
goto done;
}
- while ( argv[i] != NULL )
- {
+ while ( argv[i] != NULL ) {
fstrcpy( privname, argv[i] );
i++;
/* verify that this is a valid privilege for error reporting */
- result = cli_lsa_get_dispname(cli, mem_ctx, &pol, privname, lang_id,
+ result = rpccli_lsa_get_dispname(pipe_hnd, mem_ctx, &pol, privname, lang_id,
lang_id_sys, description, &lang_id_desc);
if ( !NT_STATUS_IS_OK(result) ) {
@@ -330,7 +341,7 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
continue;
}
- result = enum_accounts_for_privilege(mem_ctx, cli, &pol, privname);
+ result = enum_accounts_for_privilege(pipe_hnd, mem_ctx, &pol, privname);
if (!NT_STATUS_IS_OK(result)) {
d_printf("Error enumerating accounts for privilege %s [%s].\n",
privname, nt_errstr(result));
@@ -346,16 +357,16 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
int i = 1;
if (argv[1] == NULL) {
- result = enum_privileges_for_accounts(mem_ctx, cli, &pol);
+ result = enum_privileges_for_accounts(pipe_hnd, mem_ctx, &pol);
goto done;
}
while (argv[i] != NULL) {
- result = name_to_sid(cli, mem_ctx, &sid, argv[i]);
+ result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[i]);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = enum_privileges_for_user(mem_ctx, cli, &pol, &sid);
+ result = enum_privileges_for_user(pipe_hnd, mem_ctx, &pol, &sid);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -372,14 +383,14 @@ static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char
goto done;
}
- result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
+ result = enum_privileges_for_user(pipe_hnd, mem_ctx, &pol, &sid );
done:
- cli_lsa_close(cli, mem_ctx, &pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
return result;
}
@@ -387,9 +398,13 @@ done:
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND dom_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -401,18 +416,18 @@ static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char
return NT_STATUS_OK;
}
- result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
+ result = rpccli_lsa_add_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid,
argc-1, argv+1);
if (!NT_STATUS_IS_OK(result))
@@ -426,7 +441,7 @@ static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char
argv[0], nt_errstr(result));
}
- cli_lsa_close(cli, mem_ctx, &dom_pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
return result;
}
@@ -434,9 +449,13 @@ static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_rights_revoke_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND dom_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -448,18 +467,18 @@ static NTSTATUS rpc_rights_revoke_internal( const DOM_SID *domain_sid, const cha
return NT_STATUS_OK;
}
- result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ result = name_to_sid(pipe_hnd, mem_ctx, &sid, argv[0]);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&dom_pol);
if (!NT_STATUS_IS_OK(result))
return result;
- result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
+ result = rpccli_lsa_remove_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid,
False, argc-1, argv+1);
if (!NT_STATUS_IS_OK(result))
@@ -473,7 +492,7 @@ done:
argv[0], nt_errstr(result));
}
- cli_lsa_close(cli, mem_ctx, &dom_pol);
+ rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
return result;
}
@@ -541,5 +560,3 @@ int net_rpc_rights(int argc, const char **argv)
return net_help_rights( argc, argv );
}
-
-
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index 403250675a..f4a0ab90e8 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -6,6 +6,7 @@
Copyright (C) Tim Potter 2001,2002
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
Modified by Volker Lendecke 2002
+ Copyright (C) Jeremy Allison 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
@@ -41,7 +42,6 @@ static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
d_printf("\n");
}
-
static const char *display_time(NTTIME *nttime)
{
static fstring string;
@@ -210,10 +210,9 @@ static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta)
}
}
-
-static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds)
+static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type)
{
- unsigned sync_context = 0;
+ uint32 sync_context = 0;
NTSTATUS result;
int i;
TALLOC_CTX *mem_ctx;
@@ -241,13 +240,12 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret
}
do {
- result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds, db_type,
+ result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, db_type,
sync_context,
&num_deltas, &hdr_deltas, &deltas);
if (NT_STATUS_IS_ERR(result))
break;
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), ret_creds);
for (i = 0; i < num_deltas; i++) {
display_sam_entry(&hdr_deltas[i], &deltas[i]);
}
@@ -259,41 +257,47 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret
/* dump sam database via samsync rpc calls */
NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
+#if 0
+ /* net_rpc.c now always tries to create an schannel pipe.. */
+
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uchar trust_password[16];
- DOM_CRED ret_creds;
- uint32 sec_channel;
-
- ZERO_STRUCT(ret_creds);
-
- fstrcpy(cli->domain, domain_name);
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 sec_channel_type = 0;
if (!secrets_fetch_trust_account_password(domain_name,
trust_password,
- NULL, &sec_channel)) {
+ NULL, &sec_channel_type)) {
DEBUG(0,("Could not fetch trust account password\n"));
goto fail;
}
- if (!NT_STATUS_IS_OK(nt_status = cli_nt_establish_netlogon(cli, sec_channel,
- trust_password))) {
+ nt_status = rpccli_netlogon_setup_creds(pipe_hnd,
+ cli->desthost,
+ domain_name,
+ global_myname(),
+ trust_password,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
goto fail;
}
+#endif
- dump_database(cli, SAM_DATABASE_DOMAIN, &ret_creds);
- dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds);
- dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds);
-
- nt_status = NT_STATUS_OK;
+ dump_database(pipe_hnd, SAM_DATABASE_DOMAIN);
+ dump_database(pipe_hnd, SAM_DATABASE_BUILTIN);
+ dump_database(pipe_hnd, SAM_DATABASE_PRIVS);
-fail:
- cli_nt_session_close(cli);
- return nt_status;
+ return NT_STATUS_OK;
}
/* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
@@ -301,8 +305,7 @@ fail:
(!old_string && new_string) ||\
(old_string && new_string && (strcmp(old_string, new_string) != 0))
-static NTSTATUS
-sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
+static NTSTATUS sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
{
const char *old_string, *new_string;
time_t unix_time, stored_time;
@@ -529,7 +532,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
add_ret = smbrun(add_script,NULL);
DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' "
"gave %d\n", add_script, add_ret));
- }
+ }
/* try and find the possible unix account again */
if ( !(passwd = Get_Pwnam(account)) ) {
@@ -590,8 +593,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
return nt_ret;
}
-static NTSTATUS
-fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
+static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
{
fstring name;
fstring comment;
@@ -651,8 +653,7 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
+static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
{
int i;
TALLOC_CTX *t = NULL;
@@ -832,8 +833,7 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
+static NTSTATUS fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
{
#if 0 /*
* commented out right now after talking to Volker. Can't
@@ -998,42 +998,41 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta)
}
- if (!account_policy_set(AP_PASSWORD_HISTORY, delta->pwd_history_len))
+ if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, delta->pwd_history_len))
return nt_status;
- if (!account_policy_set(AP_MIN_PASSWORD_LEN, delta->min_pwd_len))
+ if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, delta->min_pwd_len))
return nt_status;
- if (!account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
return nt_status;
- if (!account_policy_set(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
return nt_status;
- if (!account_policy_set(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
return nt_status;
- if (!account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout))
+ if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout))
return nt_status;
- if (!account_policy_set(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
+ if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
return nt_status;
if (u_lockouttime != -1)
u_lockouttime /= 60;
- if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime))
+ if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime))
return nt_status;
- if (!account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
+ if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
return nt_status;
return NT_STATUS_OK;
}
-static void
-fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
+static void fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
DOM_SID dom_sid)
{
switch(hdr_delta->type) {
@@ -1098,11 +1097,9 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
}
}
-static NTSTATUS
-fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
- DOM_SID dom_sid)
+static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, DOM_SID dom_sid)
{
- unsigned sync_context = 0;
+ uint32 sync_context = 0;
NTSTATUS result;
int i;
TALLOC_CTX *mem_ctx;
@@ -1129,17 +1126,13 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
}
do {
- result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds,
+ result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx,
db_type, sync_context,
&num_deltas,
&hdr_deltas, &deltas);
if (NT_STATUS_IS_OK(result) ||
NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
- ret_creds);
-
for (i = 0; i < num_deltas; i++) {
fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
}
@@ -1154,8 +1147,7 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
return result;
}
-static NTSTATUS
-populate_ldap_for_ldif(fstring sid, const char *suffix, const char
+static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char
*builtin_sid, FILE *add_fd)
{
char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix;
@@ -1448,8 +1440,7 @@ populate_ldap_for_ldif(fstring sid, const char *suffix, const char
return NT_STATUS_OK;
}
-static NTSTATUS
-map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid,
+static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid,
const char *suffix, const char *builtin_sid)
{
char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ',');
@@ -1521,8 +1512,7 @@ map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
+static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
FILE *add_fd, fstring sid, char *suffix)
{
fstring groupname;
@@ -1579,8 +1569,7 @@ fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
+static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
ACCOUNTMAP *accountmap, FILE *add_fd,
fstring sid, char *suffix, int alloced)
{
@@ -1724,8 +1713,7 @@ fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
+static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
FILE *add_fd, fstring sid, char *suffix,
unsigned db_type)
{
@@ -1798,8 +1786,7 @@ fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, SAM_DELTA_HDR *hdr_delta,
+static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, SAM_DELTA_HDR *hdr_delta,
GROUPMAP *groupmap, ACCOUNTMAP *accountmap,
FILE *mod_fd, int alloced)
{
@@ -1841,16 +1828,16 @@ fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, SAM_DELTA_HDR *hdr_delta,
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_database_to_ldif(struct cli_state *cli, unsigned db_type,
- DOM_CRED *ret_creds, DOM_SID dom_sid,
- const char *user_file)
+static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd,
+ uint32 db_type,
+ DOM_SID dom_sid,
+ const char *user_file)
{
char *suffix;
const char *builtin_sid = "S-1-5-32";
char *ldif_file;
fstring sid, domainname;
- unsigned sync_context = 0;
+ uint32 sync_context = 0;
NTSTATUS result;
int k;
TALLOC_CTX *mem_ctx;
@@ -1956,7 +1943,7 @@ fetch_database_to_ldif(struct cli_state *cli, unsigned db_type,
}
do {
- result = cli_netlogon_sam_sync(cli, mem_ctx, ret_creds,
+ result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx,
db_type, sync_context,
&num_deltas, &hdr_deltas,
&deltas);
@@ -1965,9 +1952,6 @@ fetch_database_to_ldif(struct cli_state *cli, unsigned db_type,
return NT_STATUS_OK;
}
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred),
- ret_creds);
-
/* Re-allocate memory for groupmap and accountmap arrays */
groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP,
num_deltas+num_alloced);
@@ -2138,18 +2122,16 @@ int rpc_vampire_usage(int argc, const char **argv)
/* dump sam database via samsync rpc calls */
NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
{
NTSTATUS result;
- uchar trust_password[16];
- DOM_CRED ret_creds;
fstring my_dom_sid_str;
fstring rem_dom_sid_str;
- uint32 sec_channel;
-
- ZERO_STRUCT(ret_creds);
if (!sid_equal(domain_sid, get_global_sam_sid())) {
d_printf("Cannot import users from %s at this time, "
@@ -2164,29 +2146,11 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
return NT_STATUS_UNSUCCESSFUL;
}
- fstrcpy(cli->domain, domain_name);
-
- if (!secrets_fetch_trust_account_password(domain_name,
- trust_password, NULL,
- &sec_channel)) {
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- d_printf("Could not retrieve domain trust secret\n");
- goto fail;
- }
-
- result = cli_nt_establish_netlogon(cli, sec_channel, trust_password);
-
- if (!NT_STATUS_IS_OK(result)) {
- d_printf("Failed to setup BDC creds\n");
- goto fail;
- }
-
if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
- result = fetch_database_to_ldif(cli, SAM_DATABASE_DOMAIN,
- &ret_creds, *domain_sid, argv[1]);
+ result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_DOMAIN,
+ *domain_sid, argv[1]);
} else {
- result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds,
- *domain_sid);
+ result = fetch_database(pipe_hnd, SAM_DATABASE_DOMAIN, *domain_sid);
}
if (!NT_STATUS_IS_OK(result)) {
@@ -2199,12 +2163,10 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
}
if (argc >= 1 && (strcmp(argv[0], "ldif") == 0)) {
- result = fetch_database_to_ldif(cli, SAM_DATABASE_BUILTIN,
- &ret_creds, global_sid_Builtin,
- argv[1]);
+ result = fetch_database_to_ldif(pipe_hnd, SAM_DATABASE_BUILTIN,
+ global_sid_Builtin, argv[1]);
} else {
- result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds,
- global_sid_Builtin);
+ result = fetch_database(pipe_hnd, SAM_DATABASE_BUILTIN, global_sid_Builtin);
}
if (!NT_STATUS_IS_OK(result)) {
@@ -2219,4 +2181,3 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
fail:
return result;
}
-
diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c
index 8f93ab3d06..3cc4790884 100644
--- a/source3/utils/net_rpc_service.c
+++ b/source3/utils/net_rpc_service.c
@@ -24,8 +24,11 @@
/********************************************************************
********************************************************************/
-static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hSCM, const char *service, uint32 *state )
+static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM,
+ const char *service,
+ uint32 *state )
{
POLICY_HND hService;
SERVICE_STATUS service_status;
@@ -33,7 +36,7 @@ static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* now cycle until the status is actually 'watch_state' */
- result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
+ result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
service, SC_RIGHT_SVC_QUERY_STATUS );
if ( !W_ERROR_IS_OK(result) ) {
@@ -41,12 +44,12 @@ static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
- result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status );
+ result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
if ( W_ERROR_IS_OK(result) ) {
*state = service_status.state;
}
- cli_svcctl_close_service( cli, mem_ctx, &hService );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
return result;
}
@@ -54,9 +57,12 @@ static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/********************************************************************
********************************************************************/
-static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hSCM, const char *service,
- uint32 watch_state, uint32 *final_state )
+static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM,
+ const char *service,
+ uint32 watch_state,
+ uint32 *final_state )
{
uint32 i;
uint32 state = 0;
@@ -67,7 +73,7 @@ static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
while ( (state != watch_state ) && i<30 ) {
/* get the status */
- result = query_service_state( cli, mem_ctx, hSCM, service, &state );
+ result = query_service_state(pipe_hnd, mem_ctx, hSCM, service, &state );
if ( !W_ERROR_IS_OK(result) ) {
break;
}
@@ -86,9 +92,12 @@ static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/********************************************************************
********************************************************************/
-static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *hSCM, const char *service,
- uint32 control, uint32 watch_state )
+static WERROR control_service(struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ POLICY_HND *hSCM,
+ const char *service,
+ uint32 control,
+ uint32 watch_state )
{
POLICY_HND hService;
WERROR result = WERR_GENERAL_FAILURE;
@@ -97,7 +106,7 @@ static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Open the Service */
- result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
+ result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService,
service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
if ( !W_ERROR_IS_OK(result) ) {
@@ -107,7 +116,7 @@ static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* get the status */
- result = cli_svcctl_control_service( cli, mem_ctx, &hService,
+ result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService,
control, &service_status );
if ( !W_ERROR_IS_OK(result) ) {
@@ -117,12 +126,12 @@ static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* loop -- checking the state until we are where we want to be */
- result = watch_service_state( cli, mem_ctx, hSCM, service, watch_state, &state );
+ result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state );
d_printf("%s service is %s.\n", service, svc_status_string(state));
done:
- cli_svcctl_close_service( cli, mem_ctx, &hService );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
return result;
}
@@ -130,9 +139,13 @@ done:
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_list_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM;
ENUM_SERVICES_STATUS *services;
@@ -147,13 +160,13 @@ static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char
return NT_STATUS_OK;
}
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
- result = cli_svcctl_enumerate_services( cli, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
+ result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32,
SVCCTL_STATE_ALL, &num_services, &services );
if ( !W_ERROR_IS_OK(result) ) {
@@ -172,7 +185,7 @@ static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char
}
done:
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
@@ -180,9 +193,13 @@ done:
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM, hService;
WERROR result = WERR_GENERAL_FAILURE;
@@ -200,7 +217,7 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
/* Open the Service Control Manager */
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
@@ -208,7 +225,7 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
/* Open the Service */
- result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService, servicename,
+ result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename,
(SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) );
if ( !W_ERROR_IS_OK(result) ) {
@@ -218,7 +235,7 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
/* get the status */
- result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status );
+ result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Query status request failed. [%s]\n", dos_errstr(result));
goto done;
@@ -228,7 +245,7 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
/* get the config */
- result = cli_svcctl_query_config( cli, mem_ctx, &hService, &config );
+ result = rpccli_svcctl_query_config(pipe_hnd, mem_ctx, &hService, &config );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Query config request failed. [%s]\n", dos_errstr(result));
goto done;
@@ -268,19 +285,22 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
}
done:
- cli_svcctl_close_service( cli, mem_ctx, &hService );
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
-
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
+
return werror_to_ntstatus(result);
}
-
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
@@ -295,16 +315,16 @@ static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char
/* Open the Service Control Manager */
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
- result = control_service( cli, mem_ctx, &hSCM, servicename,
+ result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
@@ -312,9 +332,13 @@ static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
@@ -329,16 +353,16 @@ static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const cha
/* Open the Service Control Manager */
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
- result = control_service( cli, mem_ctx, &hSCM, servicename,
+ result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
@@ -346,9 +370,13 @@ static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const cha
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
@@ -363,16 +391,16 @@ static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const ch
/* Open the Service Control Manager */
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
- result = control_service( cli, mem_ctx, &hSCM, servicename,
+ result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
@@ -380,9 +408,13 @@ static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const ch
/********************************************************************
********************************************************************/
-static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv )
+static NTSTATUS rpc_service_start_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
{
POLICY_HND hSCM, hService;
WERROR result = WERR_GENERAL_FAILURE;
@@ -398,7 +430,7 @@ static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const cha
/* Open the Service Control Manager */
- result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
+ result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
@@ -406,7 +438,7 @@ static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const cha
/* Open the Service */
- result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService,
+ result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService,
servicename, SC_RIGHT_SVC_START );
if ( !W_ERROR_IS_OK(result) ) {
@@ -416,13 +448,13 @@ static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const cha
/* get the status */
- result = cli_svcctl_start_service( cli, mem_ctx, &hService, NULL, 0 );
+ result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Query status request failed. [%s]\n", dos_errstr(result));
goto done;
}
- result = watch_service_state( cli, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
+ result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
d_printf("Successfully started service: %s\n", servicename );
@@ -430,9 +462,9 @@ static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const cha
d_printf("Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
done:
- cli_svcctl_close_service( cli, mem_ctx, &hService );
- cli_svcctl_close_service( cli, mem_ctx, &hSCM );
-
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hService );
+ rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM );
+
return werror_to_ntstatus(result);
}
@@ -525,5 +557,3 @@ int net_rpc_service(int argc, const char **argv)
return net_help_service( argc, argv );
}
-
-
diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c
index d584597273..960379b383 100644
--- a/source3/utils/net_status.c
+++ b/source3/utils/net_status.c
@@ -31,7 +31,7 @@ static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
- if (!process_exists(sessionid.pid)) {
+ if (!process_exists_by_pid(sessionid.pid)) {
return 0;
}
@@ -101,8 +101,8 @@ static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
return 0;
}
- d_printf("%-10.10s %5d %-12s %s",
- crec.name,(int)crec.pid,
+ d_printf("%-10.10s %s %-12s %s",
+ crec.name,procid_str_static(&crec.pid),
crec.machine,
asctime(LocalTime(&crec.start)));
@@ -125,7 +125,7 @@ static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
- if (!process_exists(sessionid.pid))
+ if (!process_exists_by_pid(sessionid.pid))
return 0;
ids->num_entries += 1;
@@ -156,14 +156,15 @@ static int show_share_parseable(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
}
for (i=0; i<ids->num_entries; i++) {
- if (ids->entries[i].pid == crec.pid) {
+ struct process_id id = pid_to_procid(ids->entries[i].pid);
+ if (procid_equal(&id, &crec.pid)) {
guest = False;
break;
}
}
- d_printf("%s\\%d\\%s\\%s\\%s\\%s\\%s",
- crec.name,(int)crec.pid,
+ d_printf("%s\\%s\\%s\\%s\\%s\\%s\\%s",
+ crec.name,procid_str_static(&crec.pid),
guest ? "" : uidtoname(ids->entries[i].uid),
guest ? "" : gidtoname(ids->entries[i].gid),
crec.machine,
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 3fdd657a2d..4f3bb4d414 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -465,6 +465,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_st
{
NTSTATUS status;
if ( (opt_username == NULL) || (opt_domain == NULL) ) {
+ status = NT_STATUS_UNSUCCESSFUL;
DEBUG(1, ("Need username and domain for NTLMSSP\n"));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -693,7 +694,8 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
data_blob_free(&reply);
DEBUG(10, ("NTLMSSP challenge\n"));
} else if (NT_STATUS_IS_OK(nt_status)) {
- x_fprintf(x_stdout, "AF\n");
+ char *reply_base64 = base64_encode_data_blob(reply);
+ x_fprintf(x_stdout, "AF %s\n", reply_base64);
DEBUG(10, ("NTLMSSP OK!\n"));
if (ntlmssp_state)
ntlmssp_end(&ntlmssp_state);
@@ -753,7 +755,7 @@ static void offer_gss_spnego_mechs(void) {
/* Server negTokenInit (mech offerings) */
spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 3);
+ spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(char *, 2);
#ifdef HAVE_KRB5
spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
@@ -793,6 +795,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
DATA_BLOB token;
NTSTATUS status;
ssize_t len;
+ TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request");
char *user = NULL;
char *domain = NULL;
@@ -857,6 +860,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
return;
}
+ status = NT_STATUS_UNSUCCESSFUL;
if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
if ( request.negTokenInit.mechToken.data == NULL ) {
@@ -895,7 +899,6 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
char *principal;
- DATA_BLOB auth_data;
DATA_BLOB ap_rep;
DATA_BLOB session_key;
@@ -910,11 +913,13 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
response.negTokenTarg.responseToken = data_blob(NULL, 0);
- status = ads_verify_ticket(lp_realm(),
+ status = ads_verify_ticket(mem_ctx, lp_realm(),
&request.negTokenInit.mechToken,
- &principal, &auth_data, &ap_rep,
+ &principal, NULL, &ap_rep,
&session_key);
+ talloc_destroy(mem_ctx);
+
/* Now in "principal" we have the name we are
authenticated as. */
@@ -934,7 +939,6 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
user = SMB_STRDUP(principal);
data_blob_free(&ap_rep);
- data_blob_free(&auth_data);
SAFE_FREE(principal);
}
@@ -1052,15 +1056,16 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
}
spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = my_mechs;
+ spnego.negTokenInit.mechTypes = CONST_DISCARD(char **,my_mechs);
spnego.negTokenInit.reqFlags = 0;
spnego.negTokenInit.mechListMIC = null_blob;
status = ntlmssp_update(client_ntlmssp_state, null_blob,
&spnego.negTokenInit.mechToken);
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
+ if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||
+ NT_STATUS_IS_OK(status)) ) {
+ DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n",
nt_errstr(status)));
ntlmssp_end(&client_ntlmssp_state);
return False;
@@ -1121,7 +1126,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
spnego.type = SPNEGO_NEG_TOKEN_TARG;
spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
- spnego.negTokenTarg.supportedMech = OID_NTLMSSP;
+ spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;
spnego.negTokenTarg.responseToken = request;
spnego.negTokenTarg.mechListMIC = null_blob;
@@ -1166,7 +1171,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
spnego.negTokenInit.mechListMIC.length);
principal[spnego.negTokenInit.mechListMIC.length] = '\0';
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0);
if (retval) {
@@ -1189,7 +1194,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
return False;
}
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0);
if (retval) {
DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
@@ -1305,7 +1310,7 @@ static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper
/* The server offers a list of mechanisms */
- const char **mechType = spnego.negTokenInit.mechTypes;
+ const char **mechType = (const char **)spnego.negTokenInit.mechTypes;
while (*mechType != NULL) {
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index c88c0d7579..dacaa1e26f 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -119,6 +119,27 @@ static int export_groups (struct pdb_context *in, struct pdb_context *out) {
}
/*********************************************************
+ Add all currently available account policy from tdb to one backend
+ ********************************************************/
+
+static int export_account_policies (struct pdb_context *in, struct pdb_context *out)
+{
+ int i;
+
+ for (i=1; decode_account_policy_name(i) != NULL; i++) {
+ uint32 policy_value;
+ if (NT_STATUS_IS_ERR(in->pdb_get_account_policy(in, i, &policy_value))) {
+ fprintf(stderr, "Can't get account policy from tdb\n");
+ return -1;
+ }
+ out->pdb_set_account_policy(out, i, policy_value);
+ }
+
+ return 0;
+}
+
+
+/*********************************************************
Print info from sam structure
**********************************************************/
@@ -652,6 +673,7 @@ int main (int argc, char **argv)
static char *backend_in = NULL;
static char *backend_out = NULL;
static BOOL transfer_groups = False;
+ static BOOL transfer_account_policies = False;
static BOOL force_initialised_password = False;
static char *logon_script = NULL;
static char *profile_path = NULL;
@@ -683,8 +705,8 @@ int main (int argc, char **argv)
{"drive", 'D', POPT_ARG_STRING, &home_drive, 0, "set home drive", NULL},
{"script", 'S', POPT_ARG_STRING, &logon_script, 0, "set logon script", NULL},
{"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
- {"user-SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
- {"group-SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL},
+ {"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
+ {"group SID", 'G', POPT_ARG_STRING, &group_sid, 0, "set group SID or RID", NULL},
{"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
{"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
{"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
@@ -693,6 +715,7 @@ int main (int argc, char **argv)
{"import", 'i', POPT_ARG_STRING, &backend_in, 0, "import user accounts from this backend", NULL},
{"export", 'e', POPT_ARG_STRING, &backend_out, 0, "export user accounts to this backend", NULL},
{"group", 'g', POPT_ARG_NONE, &transfer_groups, 0, "use -i and -e for groups", NULL},
+ {"policies", 'y', POPT_ARG_NONE, &transfer_account_policies, 0, "use -i and -e to move account policies between backends", NULL},
{"account-policy", 'P', POPT_ARG_STRING, &account_policy, 0,"value of an account policy (like maximum password age)",NULL},
{"value", 'C', POPT_ARG_LONG, &account_policy_value, 'C',"set the account policy to this value", NULL},
{"account-control", 'c', POPT_ARG_STRING, &account_control, 0, "Values of account control", NULL},
@@ -792,20 +815,22 @@ int main (int argc, char **argv)
SAFE_FREE(apn);
exit(1);
}
- if (!account_policy_get(field, &value)) {
+ if (!pdb_get_account_policy(field, &value)) {
fprintf(stderr, "valid account policy, but unable to fetch value!\n");
- exit(1);
+ if (!account_policy_value_set)
+ exit(1);
}
+ printf("account policy \"%s\" description: %s\n", account_policy, account_policy_get_desc(field));
if (account_policy_value_set) {
- printf("account policy value for %s was %u\n", account_policy, value);
- if (!account_policy_set(field, account_policy_value)) {
+ printf("account policy \"%s\" value was: %u\n", account_policy, value);
+ if (!pdb_set_account_policy(field, account_policy_value)) {
fprintf(stderr, "valid account policy, but unable to set value!\n");
exit(1);
}
- printf("account policy value for %s is now %lu\n", account_policy, account_policy_value);
+ printf("account policy \"%s\" value is now: %lu\n", account_policy, account_policy_value);
exit(0);
} else {
- printf("account policy value for %s is %u\n", account_policy, value);
+ printf("account policy \"%s\" value is: %u\n", account_policy, value);
exit(0);
}
}
@@ -829,7 +854,10 @@ int main (int argc, char **argv)
} else {
bout = bdef;
}
- if (transfer_groups) {
+ if (transfer_account_policies) {
+ if (!(checkparms & BIT_USER))
+ return export_account_policies(bin, bout);
+ } else if (transfer_groups) {
if (!(checkparms & BIT_USER))
return export_groups(bin, bout);
} else {
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 00000b5cfb..36efcc247d 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -64,6 +64,7 @@ static const struct perm_value standard_values[] = {
};
static struct cli_state *global_hack_cli;
+static struct rpc_pipe_client *global_pipe_hnd;
static POLICY_HND pol;
static BOOL got_policy_hnd;
@@ -76,8 +77,10 @@ static BOOL cacls_open_policy_hnd(void)
/* Initialise cli LSA connection */
if (!global_hack_cli) {
+ NTSTATUS ret;
global_hack_cli = connect_one("IPC$");
- if (!cli_nt_session_open (global_hack_cli, PI_LSARPC)) {
+ global_pipe_hnd = cli_rpc_pipe_open_noauth(global_hack_cli, PI_LSARPC, &ret);
+ if (!global_pipe_hnd) {
return False;
}
}
@@ -89,7 +92,7 @@ static BOOL cacls_open_policy_hnd(void)
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
- if (!NT_STATUS_IS_OK(cli_lsa_open_policy(global_hack_cli, global_hack_cli->mem_ctx, True,
+ if (!NT_STATUS_IS_OK(rpccli_lsa_open_policy(global_pipe_hnd, global_hack_cli->mem_ctx, True,
GENERIC_EXECUTE_ACCESS, &pol))) {
return False;
}
@@ -114,7 +117,7 @@ static void SidToString(fstring str, DOM_SID *sid)
/* Ask LSA to convert the sid to a name */
if (!cacls_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_sids(global_hack_cli, global_hack_cli->mem_ctx,
+ !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, global_hack_cli->mem_ctx,
&pol, 1, sid, &domains,
&names, &types)) ||
!domains || !domains[0] || !names || !names[0]) {
@@ -141,7 +144,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
}
if (!cacls_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_names(global_hack_cli, global_hack_cli->mem_ctx,
+ !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, global_hack_cli->mem_ctx,
&pol, 1, &str, &sids,
&types))) {
result = False;
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index c0de85cea5..a0304eb89a 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -34,7 +34,8 @@ static int num_replies; /* Used by message callback fns */
/* Send a message to a destination pid. Zero means broadcast smbd. */
-static BOOL send_message(pid_t pid, int msg_type, const void *buf, int len,
+static BOOL send_message(struct process_id pid, int msg_type,
+ const void *buf, int len,
BOOL duplicates)
{
TDB_CONTEXT *tdb;
@@ -44,7 +45,7 @@ static BOOL send_message(pid_t pid, int msg_type, const void *buf, int len,
if (!message_init())
return False;
- if (pid != 0)
+ if (procid_to_pid(&pid) != 0)
return message_send_pid(pid, msg_type, buf, len, duplicates);
tdb = tdb_open_log(lock_path("connections.tdb"), 0,
@@ -84,15 +85,17 @@ static void wait_replies(BOOL multiple_replies)
/* Message handler callback that displays the PID and a string on stdout */
-static void print_pid_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void print_pid_string_cb(int msg_type, struct process_id pid, void *buf, size_t len)
{
- printf("PID %u: %.*s", (unsigned int)pid, (int)len, (const char *)buf);
+ printf("PID %u: %.*s", (unsigned int)procid_to_pid(&pid),
+ (int)len, (const char *)buf);
num_replies++;
}
/* Message handler callback that displays a string on stdout */
-static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void print_string_cb(int msg_type, struct process_id pid,
+ void *buf, size_t len)
{
printf("%.*s", (int)len, (const char *)buf);
num_replies++;
@@ -100,7 +103,8 @@ static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
/* Send no message. Useful for testing. */
-static BOOL do_noop(const pid_t pid, const int argc, const char **argv)
+static BOOL do_noop(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> noop\n");
@@ -114,7 +118,8 @@ static BOOL do_noop(const pid_t pid, const int argc, const char **argv)
/* Send a debug string */
-static BOOL do_debug(const pid_t pid, const int argc, const char **argv)
+static BOOL do_debug(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> debug "
@@ -128,7 +133,8 @@ static BOOL do_debug(const pid_t pid, const int argc, const char **argv)
/* Force a browser election */
-static BOOL do_election(const pid_t pid, const int argc, const char **argv)
+static BOOL do_election(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> force-election\n");
@@ -141,13 +147,15 @@ static BOOL do_election(const pid_t pid, const int argc, const char **argv)
/* Ping a samba daemon process */
-static void pong_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void pong_cb(int msg_type, struct process_id pid, void *buf, size_t len)
{
- printf("PONG from pid %u\n", (unsigned int)pid);
+ char *src_string = procid_str(NULL, &pid);
+ printf("PONG from pid %s\n", src_string);
+ talloc_free(src_string);
num_replies++;
}
-static BOOL do_ping(const pid_t pid, const int argc, const char **argv)
+static BOOL do_ping(const struct process_id pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> ping\n");
@@ -161,7 +169,7 @@ static BOOL do_ping(const pid_t pid, const int argc, const char **argv)
message_register(MSG_PONG, pong_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
@@ -175,7 +183,8 @@ static BOOL do_ping(const pid_t pid, const int argc, const char **argv)
/* Set profiling options */
-static BOOL do_profile(const pid_t pid, const int argc, const char **argv)
+static BOOL do_profile(const struct process_id pid,
+ const int argc, const char **argv)
{
int v;
@@ -203,7 +212,7 @@ static BOOL do_profile(const pid_t pid, const int argc, const char **argv)
/* Return the profiling level */
-static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void profilelevel_cb(int msg_type, struct process_id pid, void *buf, size_t len)
{
int level;
const char *s;
@@ -236,10 +245,11 @@ static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len)
break;
}
- printf("Profiling %s on pid %u\n",s,(unsigned int)pid);
+ printf("Profiling %s on pid %u\n",s,(unsigned int)procid_to_pid(&pid));
}
-static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len)
+static void profilelevel_rqst(int msg_type, struct process_id pid,
+ void *buf, size_t len)
{
int v = 0;
@@ -248,7 +258,8 @@ static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len)
send_message(pid, MSG_PROFILELEVEL, &v, sizeof(int), False);
}
-static BOOL do_profilelevel(const pid_t pid, const int argc, const char **argv)
+static BOOL do_profilelevel(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> profilelevel\n");
@@ -263,7 +274,7 @@ static BOOL do_profilelevel(const pid_t pid, const int argc, const char **argv)
message_register(MSG_PROFILELEVEL, profilelevel_cb);
message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
@@ -277,7 +288,8 @@ static BOOL do_profilelevel(const pid_t pid, const int argc, const char **argv)
/* Display debug level settings */
-static BOOL do_debuglevel(const pid_t pid, const int argc, const char **argv)
+static BOOL do_debuglevel(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> debuglevel\n");
@@ -291,7 +303,7 @@ static BOOL do_debuglevel(const pid_t pid, const int argc, const char **argv)
message_register(MSG_DEBUGLEVEL, print_pid_string_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
@@ -305,7 +317,8 @@ static BOOL do_debuglevel(const pid_t pid, const int argc, const char **argv)
/* Send a print notify message */
-static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
+static BOOL do_printnotify(const struct process_id pid,
+ const int argc, const char **argv)
{
const char *cmd;
@@ -428,7 +441,8 @@ static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
return False;
}
- notify_printer_byname(argv[2], attribute, argv[4]);
+ notify_printer_byname(argv[2], attribute,
+ CONST_DISCARD(char *, argv[4]));
goto send;
}
@@ -443,7 +457,8 @@ send:
/* Close a share */
-static BOOL do_closeshare(const pid_t pid, const int argc, const char **argv)
+static BOOL do_closeshare(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> close-share "
@@ -457,7 +472,8 @@ static BOOL do_closeshare(const pid_t pid, const int argc, const char **argv)
/* Force a SAM synchronisation */
-static BOOL do_samsync(const pid_t pid, const int argc, const char **argv)
+static BOOL do_samsync(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samsync\n");
@@ -470,7 +486,8 @@ static BOOL do_samsync(const pid_t pid, const int argc, const char **argv)
/* Force a SAM replication */
-static BOOL do_samrepl(const pid_t pid, const int argc, const char **argv)
+static BOOL do_samrepl(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samrepl\n");
@@ -483,7 +500,8 @@ static BOOL do_samrepl(const pid_t pid, const int argc, const char **argv)
/* Display talloc pool usage */
-static BOOL do_poolusage(const pid_t pid, const int argc, const char **argv)
+static BOOL do_poolusage(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> pool-usage\n");
@@ -497,7 +515,7 @@ static BOOL do_poolusage(const pid_t pid, const int argc, const char **argv)
message_register(MSG_POOL_USAGE, print_string_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
@@ -511,7 +529,8 @@ static BOOL do_poolusage(const pid_t pid, const int argc, const char **argv)
/* Perform a dmalloc mark */
-static BOOL do_dmalloc_mark(const pid_t pid, const int argc, const char **argv)
+static BOOL do_dmalloc_mark(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> dmalloc-mark\n");
@@ -524,7 +543,8 @@ static BOOL do_dmalloc_mark(const pid_t pid, const int argc, const char **argv)
/* Perform a dmalloc changed */
-static BOOL do_dmalloc_changed(const pid_t pid, const int argc, const char **argv)
+static BOOL do_dmalloc_changed(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> "
@@ -538,7 +558,8 @@ static BOOL do_dmalloc_changed(const pid_t pid, const int argc, const char **arg
/* Shutdown a server process */
-static BOOL do_shutdown(const pid_t pid, const int argc, const char **argv)
+static BOOL do_shutdown(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> shutdown\n");
@@ -550,7 +571,8 @@ static BOOL do_shutdown(const pid_t pid, const int argc, const char **argv)
/* Notify a driver upgrade */
-static BOOL do_drvupgrade(const pid_t pid, const int argc, const char **argv)
+static BOOL do_drvupgrade(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> drvupgrade "
@@ -562,7 +584,8 @@ static BOOL do_drvupgrade(const pid_t pid, const int argc, const char **argv)
pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False);
}
-static BOOL do_reload_config(const pid_t pid, const int argc, const char **argv)
+static BOOL do_reload_config(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> reload-config\n");
@@ -583,8 +606,8 @@ static void my_make_nmb_name( struct nmb_name *n, const char *name, int type)
push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
}
-static BOOL do_nodestatus(const pid_t pid, const int argc,
- const char **argv)
+static BOOL do_nodestatus(const struct process_id pid,
+ const int argc, const char **argv)
{
struct packet_struct p;
@@ -623,7 +646,8 @@ static BOOL do_nodestatus(const pid_t pid, const int argc,
static const struct {
const char *name; /* Option name */
- BOOL (*fn)(const pid_t pid, const int argc, const char **argv);
+ BOOL (*fn)(const struct process_id pid,
+ const int argc, const char **argv);
const char *help; /* Short help text */
} msg_types[] = {
{ "debug", do_debug, "Set debuglevel" },
@@ -674,33 +698,39 @@ static void usage(poptContext *pc)
/* Return the pid number for a string destination */
-static pid_t parse_dest(const char *dest)
+static struct process_id parse_dest(const char *dest)
{
+ struct process_id result;
pid_t pid;
/* Zero is a special return value for broadcast smbd */
- if (strequal(dest, "smbd"))
- return 0;
+ if (strequal(dest, "smbd")) {
+ return interpret_pid("0");
+ }
/* Try self - useful for testing */
- if (strequal(dest, "self"))
- return sys_getpid();
+ if (strequal(dest, "self")) {
+ return pid_to_procid(sys_getpid());
+ }
/* Check for numeric pid number */
- if ((pid = atoi(dest)) != 0)
- return pid;
+ result = interpret_pid(dest);
+ if (procid_valid(&result)) {
+ return result;
+ }
/* Look up other destinations in pidfile directory */
- if ((pid = pidfile_pid(dest)) != 0)
- return pid;
+ if ((pid = pidfile_pid(dest)) != 0) {
+ return pid_to_procid(pid);
+ }
fprintf(stderr,"Can't find pid for destination '%s'\n", dest);
- return -1;
+ return result;
}
/* Execute smbcontrol command */
@@ -708,13 +738,15 @@ static pid_t parse_dest(const char *dest)
static BOOL do_command(int argc, const char **argv)
{
const char *dest = argv[0], *command = argv[1];
- pid_t pid;
+ struct process_id pid;
int i;
/* Check destination */
- if ((pid = parse_dest(dest)) == -1)
+ pid = parse_dest(dest);
+ if (!procid_valid(&pid)) {
return False;
+ }
/* Check command */
diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c
index 81f7dd42bb..c516fbb218 100644
--- a/source3/utils/smbcquotas.c
+++ b/source3/utils/smbcquotas.c
@@ -34,7 +34,8 @@ static BOOL verbose;
enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA};
enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
-static struct cli_state *cli_ipc = NULL;
+static struct cli_state *cli_ipc;
+static struct rpc_pipe_client *global_pipe_hnd;
static POLICY_HND pol;
static BOOL got_policy_hnd;
@@ -47,8 +48,10 @@ static BOOL cli_open_policy_hnd(void)
/* Initialise cli LSA connection */
if (!cli_ipc) {
+ NTSTATUS ret;
cli_ipc = connect_one("IPC$");
- if (!cli_nt_session_open (cli_ipc, PI_LSARPC)) {
+ global_pipe_hnd = cli_rpc_pipe_open_noauth(cli_ipc, PI_LSARPC, &ret);
+ if (!global_pipe_hnd) {
return False;
}
}
@@ -60,7 +63,7 @@ static BOOL cli_open_policy_hnd(void)
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
- if (!NT_STATUS_IS_OK(cli_lsa_open_policy(cli_ipc, cli_ipc->mem_ctx, True,
+ if (!NT_STATUS_IS_OK(rpccli_lsa_open_policy(global_pipe_hnd, cli_ipc->mem_ctx, True,
GENERIC_EXECUTE_ACCESS, &pol))) {
return False;
}
@@ -85,7 +88,7 @@ static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric)
/* Ask LSA to convert the sid to a name */
if (!cli_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_sids(cli_ipc, cli_ipc->mem_ctx,
+ !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, cli_ipc->mem_ctx,
&pol, 1, sid, &domains,
&names, &types)) ||
!domains || !domains[0] || !names || !names[0]) {
@@ -112,7 +115,7 @@ static BOOL StringToSid(DOM_SID *sid, const char *str)
}
if (!cli_open_policy_hnd() ||
- !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx,
+ !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, cli_ipc->mem_ctx,
&pol, 1, &str, &sids,
&types))) {
result = False;
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 96e4bd266b..4709cfbaee 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -98,7 +98,7 @@ static BOOL Ucrit_addPid( pid_t pid )
return True;
}
-static void print_share_mode(share_mode_entry *e, char *fname)
+static void print_share_mode(const struct share_mode_entry *e, char *fname)
{
static int count;
if (count==0) {
@@ -108,8 +108,8 @@ static void print_share_mode(share_mode_entry *e, char *fname)
}
count++;
- if (Ucrit_checkPid(e->pid)) {
- d_printf("%-5d ",(int)e->pid);
+ if (Ucrit_checkPid(procid_to_pid(&e->pid))) {
+ d_printf("%s ",procid_str_static(&e->pid));
switch (map_share_mode_to_deny_mode(e->share_access,
e->private_options)) {
case DENY_NONE: d_printf("DENY_NONE "); break;
@@ -154,7 +154,7 @@ static void print_share_mode(share_mode_entry *e, char *fname)
}
}
-static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
+static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid,
enum brl_type lock_type,
br_off start, br_off size)
{
@@ -166,8 +166,8 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
}
count++;
- d_printf("%6d %05x:%05x %s %9.0f %9.0f\n",
- (int)pid, (int)dev, (int)ino,
+ d_printf("%s %05x:%05x %s %9.0f %9.0f\n",
+ procid_str_static(&pid), (int)dev, (int)ino,
lock_type==READ_LOCK?"R":"W",
(double)start, (double)size);
}
@@ -550,8 +550,8 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
return 0;
}
- d_printf("%-10s %5d %-12s %s",
- crec.name,(int)crec.pid,
+ d_printf("%-10s %s %-12s %s",
+ crec.name,procid_str_static(&crec.pid),
crec.machine,
asctime(LocalTime(&crec.start)));
@@ -568,7 +568,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
- if (!process_exists(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
+ if (!process_exists_by_pid(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
return 0;
}
diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index 2b72479ac0..b4561b58de 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -206,7 +206,7 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
poptContext pc;
static const char *term_code = "";
static char *parameter_name = NULL;
- static char *section_name = NULL;
+ static const char *section_name = NULL;
static char *new_local_machine = NULL;
const char *cname;
const char *caddr;
diff --git a/source3/web/diagnose.c b/source3/web/diagnose.c
index d259717da0..c7a7a3598e 100644
--- a/source3/web/diagnose.c
+++ b/source3/web/diagnose.c
@@ -21,8 +21,6 @@
#include "includes.h"
#include "web/swat_proto.h"
-extern struct in_addr loopback_ip;
-
#ifdef WITH_WINBIND
/* check to see if winbind is running by pinging it */
@@ -37,6 +35,7 @@ BOOL winbindd_running(void)
response */
BOOL nmbd_running(void)
{
+ extern struct in_addr loopback_ip;
int fd, count, flags;
struct in_addr *ip_list;
@@ -61,6 +60,7 @@ BOOL nmbd_running(void)
BOOL smbd_running(void)
{
static struct cli_state cli;
+ extern struct in_addr loopback_ip;
if (!cli_initialise(&cli))
return False;
diff --git a/source3/web/neg_lang.c b/source3/web/neg_lang.c
index cc2924afde..ca671822d8 100644
--- a/source3/web/neg_lang.c
+++ b/source3/web/neg_lang.c
@@ -54,8 +54,8 @@ struct pri_list {
};
static int qsort_cmp_list(const void *x, const void *y) {
- struct pri_list *a = CONST_DISCARD(struct pri_list *, x);
- struct pri_list *b = CONST_DISCARD(struct pri_list *, y);
+ struct pri_list *a = (struct pri_list *)x;
+ struct pri_list *b = (struct pri_list *)y;
if (a->pri > b->pri) return -1;
if (a->pri == b->pri) return 0;
return 1;
diff --git a/source3/web/startstop.c b/source3/web/startstop.c
index 9ffda5bb94..8f28748918 100644
--- a/source3/web/startstop.c
+++ b/source3/web/startstop.c
@@ -121,11 +121,11 @@ void stop_winbindd(void)
}
#endif
/* kill a specified process */
-void kill_pid(pid_t pid)
+void kill_pid(struct process_id pid)
{
if (geteuid() != 0) return;
- if (pid <= 0) return;
+ if (procid_to_pid(&pid) <= 0) return;
- kill(pid, SIGTERM);
+ kill(procid_to_pid(&pid), SIGTERM);
}
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 871e07b5d0..edc0318373 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -28,14 +28,14 @@
PIDMAP {
PIDMAP *next, *prev;
- pid_t pid;
+ struct process_id pid;
char *machine;
};
static PIDMAP *pidmap;
static int PID_or_Machine; /* 0 = show PID, else show Machine name */
-static pid_t smbd_pid;
+static struct process_id smbd_pid;
/* from 2nd call on, remove old list */
static void initPid2Machine (void)
@@ -55,7 +55,7 @@ static void initPid2Machine (void)
}
/* add new PID <-> Machine name mapping */
-static void addPid2Machine (pid_t pid, char *machine)
+static void addPid2Machine (struct process_id pid, char *machine)
{
/* show machine name rather PID on table "Open Files"? */
if (PID_or_Machine) {
@@ -75,7 +75,7 @@ static void addPid2Machine (pid_t pid, char *machine)
}
/* lookup PID <-> Machine name mapping */
-static char *mapPid2Machine (pid_t pid)
+static char *mapPid2Machine (struct process_id pid)
{
static char pidbuf [64];
PIDMAP *map;
@@ -83,7 +83,7 @@ static char *mapPid2Machine (pid_t pid)
/* show machine name rather PID on table "Open Files"? */
if (PID_or_Machine) {
for (map = pidmap; map != NULL; map = map->next) {
- if (pid == map->pid) {
+ if (procid_equal(&pid, &map->pid)) {
if (map->machine == NULL) /* no machine name */
break; /* show PID */
@@ -93,7 +93,8 @@ static char *mapPid2Machine (pid_t pid)
}
/* PID not in list or machine name NULL? return pid as string */
- snprintf (pidbuf, sizeof (pidbuf) - 1, "%lu", (unsigned long)pid);
+ snprintf (pidbuf, sizeof (pidbuf) - 1, "%s",
+ procid_str_static(&pid));
return pidbuf;
}
@@ -105,7 +106,7 @@ static char *tstring(time_t t)
return buf;
}
-static void print_share_mode(share_mode_entry *e, char *fname)
+static void print_share_mode(const struct share_mode_entry *e, char *fname)
{
char *utf8_fname;
int deny_mode = map_share_mode_to_deny_mode(e->share_access,
@@ -167,7 +168,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
if (crec.cnum == -1 && process_exists(crec.pid)) {
char buf[30];
- slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
+ slprintf(buf,sizeof(buf)-1,"kill_%s", procid_str_static(&crec.pid));
if (cgi_variable(buf)) {
kill_pid(crec.pid);
sleep(SLEEP_TIME);
@@ -186,18 +187,19 @@ static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
memcpy(&crec, dbuf.dptr, sizeof(crec));
- if (crec.cnum == -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
+ if (crec.cnum == -1 || !process_exists(crec.pid) ||
+ procid_equal(&crec.pid, &smbd_pid))
return 0;
addPid2Machine (crec.pid, crec.machine);
- printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
- (int)crec.pid,
+ printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td>\n",
+ procid_str_static(&crec.pid),
crec.machine,crec.addr,
tstring(crec.start));
if (geteuid() == 0) {
- printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
- (int)crec.pid);
+ printf("<td><input type=submit value=\"X\" name=\"kill_%s\"></td>\n",
+ procid_str_static(&crec.pid));
}
printf("</tr>\n");
@@ -217,9 +219,9 @@ static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
if (crec.cnum == -1 || !process_exists(crec.pid))
return 0;
- printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
+ printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n",
crec.name,uidtoname(crec.uid),
- gidtoname(crec.gid),(int)crec.pid,
+ gidtoname(crec.gid),procid_str_static(&crec.pid),
crec.machine,
tstring(crec.start));
return 0;
@@ -236,7 +238,7 @@ void status_page(void)
int nr_running=0;
BOOL waitup = False;
- smbd_pid = pidfile_pid("smbd");
+ smbd_pid = pid_to_procid(pidfile_pid("smbd"));
if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
stop_smbd();
diff --git a/source3/web/swat.c b/source3/web/swat.c
index 15612484a3..4082574e44 100644
--- a/source3/web/swat.c
+++ b/source3/web/swat.c
@@ -188,12 +188,12 @@ static const char* get_parm_translated(
if(strcmp(pLabel, pTranslated) != 0)
{
pstr_sprintf(output,
- "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
+ "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
pAnchor, pHelp, pLabel, pTranslated);
return output;
}
pstr_sprintf(output,
- "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
+ "<a href=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\" class=\"help_link\"> %s</a> %s",
pAnchor, pHelp, pLabel);
return output;
}
@@ -220,7 +220,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
ptr = lp_local_ptr(snum, ptr);
}
- printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
+ printf("<tr><td width=\"230\">%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
switch (parm->type) {
case P_CHAR:
printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
@@ -230,7 +230,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
break;
case P_LIST:
- printf("<input type=text size=40 name=\"parm_%s\" value=\"",
+ printf("<input type=text size=30 name=\"parm_%s\" value=\"",
make_parm_name(parm->label));
if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
char **list = *(char ***)ptr;
@@ -268,7 +268,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
case P_STRING:
case P_USTRING:
push_utf8_allocate(&utf8_s1, *(char **)ptr);
- printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
+ printf("<input type=text size=30 name=\"parm_%s\" value=\"%s\">",
make_parm_name(parm->label), fix_quotes(utf8_s1));
SAFE_FREE(utf8_s1);
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
@@ -278,7 +278,7 @@ static void show_parameter(int snum, struct parm_struct *parm)
case P_GSTRING:
case P_UGSTRING:
push_utf8_allocate(&utf8_s1, (char *)ptr);
- printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
+ printf("<input type=text size=30 name=\"parm_%s\" value=\"%s\">",
make_parm_name(parm->label), fix_quotes(utf8_s1));
SAFE_FREE(utf8_s1);
printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
@@ -523,42 +523,50 @@ static void commit_parameters(int snum)
}
/****************************************************************************
- spit out the html for a link with an image
+ generate html for rollovers
****************************************************************************/
-static void image_link(const char *name, const char *hlink, const char *src)
+static void rollover_link(const char *name, const char *id, const char *page)
{
- printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
- cgi_baseurl(), hlink, src, name);
+ if ( strcmp(page, id)==0 ) {
+ printf(" <img src=\"/swat/images/%s_flat.png\" alt=\"%s\" />\n",
+ id, name);
+ } else {
+ printf(" <a href=\"%s/%s\" onmouseover=\"swapImg('%s','%sOver')\" onmouseout=\"swapImg('%s','%sLink')\"><img src=\"/swat/images/%s_link.png\" name=\"%s\" alt=\"%s\" /></a>\n",
+ cgi_baseurl(), id, id, id, id, id, id, id, name);
+ }
}
/****************************************************************************
display the main navigation controls at the top of each page along
with a title
****************************************************************************/
-static void show_main_buttons(void)
+static void show_main_buttons(const char *page)
{
char *p;
- if ((p = cgi_user_name()) && strcmp(p, "root")) {
- printf(_("Logged in as <b>%s</b>"), p);
- printf("<p>\n");
- }
+ printf(" <div id=\"nav\">\n");
- image_link(_("Home"), "", "images/home.gif");
if (have_write_access) {
- image_link(_("Globals"), "globals", "images/globals.gif");
- image_link(_("Shares"), "shares", "images/shares.gif");
- image_link(_("Printers"), "printers", "images/printers.gif");
- image_link(_("Wizard"), "wizard", "images/wizard.gif");
+ rollover_link(_("Configure"), "conf", page);
+ rollover_link(_("Services"), "services", page);
}
- /* root always gets all buttons, otherwise look for -P */
+
+ /* root always gets all buttons, otherwise look for -P */
if ( have_write_access || (!passwd_only && have_read_access) ) {
- image_link(_("Status"), "status", "images/status.gif");
- image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
+ rollover_link(_("Status"), "status", page);
+ }
+ rollover_link(_("Password Management"), "passwd", page);
+
+ printf(" </div>\n\n");
+
+ /* Wrap the rest in a control div */
+ printf(" <div id=\"controls\">\n\n");
+
+ if ((p = cgi_user_name()) && strcmp(p, "root")) {
+ printf(_("Logged in as <b>%s</b>"), p);
+ printf("<p>\n");
}
- image_link(_("Password Management"), "passwd", "images/passwd.gif");
- printf("<HR>\n");
}
/****************************************************************************
@@ -576,11 +584,47 @@ static void ViewModeBoxes(int mode)
}
/****************************************************************************
- display a welcome page
+ display a welcome page (Read-only users under passwd only get a unique welcome)
****************************************************************************/
static void welcome_page(void)
{
- include_html("help/welcome.html");
+ if (passwd_only && !have_write_access) {
+ include_html("help/welcome_passwd_only.html");
+ } else {
+ include_html("help/welcome.html");
+ }
+}
+
+/****************************************************************************
+ display help page
+****************************************************************************/
+static void help_page(void)
+{
+ include_html("help/docs.html");
+}
+
+/****************************************************************************
+ display shares and printers links from an overall services page
+****************************************************************************/
+static void services_page(void)
+{
+ printf(" <div class=\"whereto\">\n");
+ printf(" <h2>File and Printer Shares</h2>\n\n");
+ printf(" <p>Follow the links below to edit service-level parameters for file and printer shares.</p>\n");
+ printf(" </div>\n\n");
+
+ printf(" <div class=\"view_conf\"><a href=\"viewconfig\" onclick=\"openHelp(this.href); return false\">View smb.conf file</a></div>\n\n");
+
+ printf(" <div class=\"services_opts\">\n");
+ printf(" <ul>\n");
+ printf(" <li><a href=\"shares\">File Shares</a></li>\n");
+ printf(" <li><a href=\"printers\">Printer Shares</a></li>\n");
+ printf(" </ul>\n");
+ printf(" </div>\n\n");
+
+ printf(" <div>\n");
+ printf(" <p>Shares may also be added via the links above.</p>\n");
+ printf(" </div>\n\n");
}
/****************************************************************************
@@ -648,7 +692,9 @@ static void rewritecfg_file(void)
{
commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(0);
- printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
+ printf("<h2>Samba Configuration Saved</h2>");
+ printf("<p>%s</p>\n", _("Note: smb.conf file has been read and rewritten"));
+ printf("<p>Return to the <a href=\"javascript:history.go(-1)\">previous page</a>.\n");
}
/****************************************************************************
@@ -760,7 +806,7 @@ static void wizard_page(void)
printf("<form method=post action=wizard>\n");
if (have_write_access) {
- printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
+ printf("%s\n", _("The &quot;Rewrite smb.conf file&quot; button will clear the smb.conf file of all default values and of comments."));
printf("%s", _("The same will happen if you press the commit button."));
printf("<br><br>\n");
printf("<center>");
@@ -820,14 +866,19 @@ static void wizard_page(void)
/****************************************************************************
- display a globals editing page
+ display a conf page for editing global parameters
****************************************************************************/
-static void globals_page(void)
+static void conf_page(void)
{
unsigned int parm_filter = FLAG_BASIC;
int mode = 0;
- printf("<H2>%s</H2>\n", _("Global Parameters"));
+ printf(" <div class=\"whereto\">\n");
+ printf(" <h2>Configuring Samba</h2>\n\n");
+ printf(" <p>The following menu allows for editing of global parameters affecting your Samba configuration.</p>\n");
+ printf(" </div>\n\n");
+
+ printf(" <div class=\"view_conf\"><a href=\"viewconfig\" onclick=\"openHelp(this.href); return false\">View smb.conf file</a></div>\n\n");
if (cgi_variable("Commit")) {
commit_parameters(GLOBAL_SECTION_SNUM);
@@ -841,7 +892,7 @@ static void globals_page(void)
if ( cgi_variable("AdvMode"))
mode = 1;
- printf("<form name=\"swatform\" method=post action=globals>\n");
+ printf("<form name=\"swatform\" method=post action=conf>\n");
ViewModeBoxes( mode );
switch ( mode ) {
@@ -885,6 +936,8 @@ static void shares_page(void)
snum = lp_servicenumber(share);
printf("<H2>%s</H2>\n", _("Share Parameters"));
+
+ printf(" <div class=\"view_conf\"><a href=\"services\">Return to Services Page</a><a href=\"viewconfig\" onclick=\"openHelp(this.href); return false\">View smb.conf file</a></div>\n\n");
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
@@ -1226,6 +1279,8 @@ static void printers_page(void)
snum = lp_servicenumber(share);
printf("<H2>%s</H2>\n", _("Printer Parameters"));
+
+ printf(" <div class=\"view_conf\"><a href=\"services\">Return to Services Page</a><a href=\"viewconfig\" onclick=\"openHelp(this.href); return false\">View smb.conf file</a></div>\n\n");
printf("<H3>%s</H3>\n", _("Important Note:"));
printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
@@ -1395,29 +1450,32 @@ static void printers_page(void)
have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
}
- show_main_buttons();
-
page = cgi_pathinfo();
- /* Root gets full functionality */
- if (have_read_access && strcmp(page, "globals")==0) {
- globals_page();
+ show_main_buttons(page);
+
+ if (have_read_access && strcmp(page,"conf")==0) {
+ conf_page();
+ } else if (have_read_access && strcmp(page,"viewconfig")==0) {
+ viewconfig_page();
+ } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
+ rewritecfg_file();
+ } else if (have_read_access && strcmp(page,"services")==0) {
+ services_page();
} else if (have_read_access && strcmp(page,"shares")==0) {
shares_page();
} else if (have_read_access && strcmp(page,"printers")==0) {
printers_page();
} else if (have_read_access && strcmp(page,"status")==0) {
status_page();
- } else if (have_read_access && strcmp(page,"viewconfig")==0) {
- viewconfig_page();
} else if (strcmp(page,"passwd")==0) {
passwd_page();
} else if (have_read_access && strcmp(page,"wizard")==0) {
wizard_page();
} else if (have_read_access && strcmp(page,"wizard_params")==0) {
wizard_params_page();
- } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
- rewritecfg_file();
+ } else if (have_read_access && strcmp(page,"help")==0) {
+ help_page();
} else {
welcome_page();
}