r10656: BIG merge from trunk. Features not copied over
authorGerald Carter <jerry@samba.org>
Fri, 30 Sep 2005 17:13:37 +0000 (17:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:04:48 +0000 (11:04 -0500)
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
(This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)

261 files changed:
examples/LDAP/samba.schema
source3/Makefile.in
source3/auth/auth.c
source3/auth/auth_domain.c
source3/auth/auth_ntlmssp.c
source3/auth/auth_util.c
source3/auth/auth_winbind.c
source3/client/mount.cifs.c
source3/client/smbspool.c
source3/configure.in
source3/groupdb/mapping.c
source3/include/ads.h
source3/include/asn_1.h
source3/include/authdata.h
source3/include/client.h
source3/include/dlinklist.h
source3/include/doserr.h
source3/include/includes.h
source3/include/messages.h
source3/include/module.h
source3/include/ntdomain.h
source3/include/ntlmssp.h
source3/include/passdb.h
source3/include/printing.h
source3/include/rpc_client.h
source3/include/rpc_dce.h
source3/include/rpc_dfs.h
source3/include/rpc_ds.h
source3/include/rpc_eventlog.h
source3/include/rpc_lsa.h
source3/include/rpc_misc.h
source3/include/rpc_netlogon.h
source3/include/rpc_ntsvcs.h [new file with mode: 0644]
source3/include/rpc_perfcount.h [new file with mode: 0644]
source3/include/rpc_perfcount_defs.h [new file with mode: 0644]
source3/include/rpc_reg.h
source3/include/rpc_samr.h
source3/include/rpc_secdes.h
source3/include/rpc_svcctl.h
source3/include/smb.h
source3/include/smb_ldap.h [new file with mode: 0644]
source3/include/smb_share_modes.h
source3/include/smbldap.h
source3/include/spnego.h
source3/include/srvstr.h
source3/lib/account_pol.c
source3/lib/arc4.c [new file with mode: 0644]
source3/lib/data_blob.c
source3/lib/debug.c
source3/lib/dmallocmsg.c
source3/lib/gencache.c
source3/lib/genrand.c
source3/lib/messages.c
source3/lib/module.c
source3/lib/pidfile.c
source3/lib/privileges.c
source3/lib/smbldap.c
source3/lib/smbldap_util.c
source3/lib/smbrun.c
source3/lib/tallocmsg.c
source3/lib/time.c
source3/lib/util.c
source3/libads/authdata.c
source3/libads/kerberos_verify.c
source3/libads/ldap.c
source3/libads/ldap_printer.c
source3/libads/sasl.c
source3/libsmb/cliconnect.c
source3/libsmb/clidgram.c
source3/libsmb/clientgen.c
source3/libsmb/clierror.c
source3/libsmb/clikrb5.c
source3/libsmb/clireadwrite.c
source3/libsmb/clispnego.c
source3/libsmb/clitrans.c
source3/libsmb/credentials.c
source3/libsmb/errormap.c
source3/libsmb/libsmb_compat.c
source3/libsmb/libsmbclient.c
source3/libsmb/ntlmssp.c
source3/libsmb/ntlmssp_parse.c
source3/libsmb/ntlmssp_sign.c
source3/libsmb/passchange.c
source3/libsmb/pwd_cache.c
source3/libsmb/smb_share_modes.c
source3/libsmb/smbdes.c
source3/libsmb/smbencrypt.c
source3/libsmb/smberr.c
source3/libsmb/spnego.c
source3/libsmb/trusts_util.c
source3/locking/brlock.c
source3/locking/locking.c
source3/modules/weird.c
source3/nmbd/asyncdns.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_elections.c
source3/nmbd/nmbd_packets.c
source3/nmbd/nmbd_synclists.c
source3/nmbd/nmbd_winsserver.c
source3/nsswitch/wb_common.c
source3/nsswitch/wbinfo.c
source3/nsswitch/winbindd.c
source3/nsswitch/winbindd.h
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_async.c
source3/nsswitch/winbindd_cache.c
source3/nsswitch/winbindd_cm.c
source3/nsswitch/winbindd_dual.c
source3/nsswitch/winbindd_group.c
source3/nsswitch/winbindd_misc.c
source3/nsswitch/winbindd_nss.h
source3/nsswitch/winbindd_pam.c
source3/pam_smbpass/pam_smb_auth.c
source3/param/loadparm.c
source3/passdb/lookup_sid.c
source3/passdb/passdb.c
source3/passdb/pdb_get_set.c
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_nds.c
source3/passdb/pdb_smbpasswd.c
source3/passdb/secrets.c
source3/passdb/util_sam_sid.c
source3/printing/notify.c
source3/printing/print_cups.c
source3/printing/print_generic.c
source3/printing/print_iprint.c
source3/printing/printing.c
source3/printing/printing_db.c
source3/profile/profile.c
source3/registry/reg_db.c
source3/registry/reg_dynamic.c
source3/registry/reg_eventlog.c
source3/registry/reg_frontend.c
source3/registry/reg_objects.c
source3/registry/reg_perfcount.c [new file with mode: 0644]
source3/registry/reg_printing.c
source3/registry/reg_util.c
source3/registry/regfio.c
source3/rpc_client/cli_dfs.c
source3/rpc_client/cli_ds.c
source3/rpc_client/cli_echo.c
source3/rpc_client/cli_lsarpc.c
source3/rpc_client/cli_netlogon.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/cli_reg.c
source3/rpc_client/cli_samr.c
source3/rpc_client/cli_shutdown.c
source3/rpc_client/cli_spoolss.c
source3/rpc_client/cli_spoolss_notify.c
source3/rpc_client/cli_srvsvc.c
source3/rpc_client/cli_svcctl.c
source3/rpc_client/cli_wkssvc.c
source3/rpc_parse/parse_buffer.c
source3/rpc_parse/parse_dfs.c
source3/rpc_parse/parse_ds.c
source3/rpc_parse/parse_echo.c
source3/rpc_parse/parse_eventlog.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_net.c
source3/rpc_parse/parse_ntsvcs.c [new file with mode: 0644]
source3/rpc_parse/parse_prs.c
source3/rpc_parse/parse_reg.c
source3/rpc_parse/parse_rpc.c
source3/rpc_parse/parse_samr.c
source3/rpc_parse/parse_svcctl.c
source3/rpc_server/srv_eventlog.c
source3/rpc_server/srv_eventlog_nt.c
source3/rpc_server/srv_lsa_hnd.c
source3/rpc_server/srv_lsa_nt.c
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_ntsvcs.c [new file with mode: 0644]
source3/rpc_server/srv_ntsvcs_nt.c [new file with mode: 0644]
source3/rpc_server/srv_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_reg.c
source3/rpc_server/srv_reg_nt.c
source3/rpc_server/srv_samr_nt.c
source3/rpc_server/srv_samr_util.c
source3/rpc_server/srv_spoolss_nt.c
source3/rpc_server/srv_srvsvc_nt.c
source3/rpc_server/srv_svcctl.c
source3/rpc_server/srv_svcctl_nt.c
source3/rpcclient/cmd_dfs.c
source3/rpcclient/cmd_ds.c
source3/rpcclient/cmd_echo.c
source3/rpcclient/cmd_lsarpc.c
source3/rpcclient/cmd_netlogon.c
source3/rpcclient/cmd_samr.c
source3/rpcclient/cmd_spoolss.c
source3/rpcclient/cmd_srvsvc.c
source3/rpcclient/cmd_test.c [new file with mode: 0644]
source3/rpcclient/cmd_wkssvc.c
source3/rpcclient/rpcclient.c
source3/rpcclient/rpcclient.h
source3/sam/idmap_rid.c
source3/sam/idmap_smbldap.c [new file with mode: 0644]
source3/script/installman.sh
source3/script/installswat.sh
source3/script/mkproto.awk
source3/script/tests/functions
source3/script/tests/t_001.sh
source3/services/services_db.c
source3/services/svc_netlogon.c [new file with mode: 0644]
source3/services/svc_rcinit.c
source3/services/svc_spoolss.c
source3/services/svc_winreg.c [new file with mode: 0644]
source3/smbd/blocking.c
source3/smbd/change_trust_pw.c
source3/smbd/chgpasswd.c
source3/smbd/close.c
source3/smbd/conn.c
source3/smbd/connection.c
source3/smbd/error.c
source3/smbd/files.c
source3/smbd/mangle_hash2.c
source3/smbd/message.c
source3/smbd/nttrans.c
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/oplock_irix.c
source3/smbd/oplock_linux.c
source3/smbd/process.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/sesssetup.c
source3/smbd/trans2.c
source3/tdb/tdbdump.c
source3/tdb/tdbtool.c
source3/tdb/tdbutil.c
source3/torture/locktest2.c
source3/torture/mangle_test.c
source3/torture/msgtest.c
source3/torture/t_asn1.c [new file with mode: 0644]
source3/torture/t_strappend.c [new file with mode: 0644]
source3/torture/torture.c
source3/torture/vfstest.c
source3/utils/log2pcaphex.c
source3/utils/net.c
source3/utils/net.h
source3/utils/net_ads.c
source3/utils/net_rpc.c
source3/utils/net_rpc_join.c
source3/utils/net_rpc_printer.c
source3/utils/net_rpc_registry.c
source3/utils/net_rpc_rights.c
source3/utils/net_rpc_samsync.c
source3/utils/net_rpc_service.c
source3/utils/net_status.c
source3/utils/ntlm_auth.c
source3/utils/pdbedit.c
source3/utils/smbcacls.c
source3/utils/smbcontrol.c
source3/utils/smbcquotas.c
source3/utils/status.c
source3/utils/testparm.c
source3/web/diagnose.c
source3/web/neg_lang.c
source3/web/startstop.c
source3/web/statuspage.c
source3/web/swat.c

index 2205c17309510238aeb36aa6f5c87ef558f01c93..daf4588ead5383b0a8217dc5f56b7ff2d860df57 100644 (file)
@@ -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 )
 
        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 )
 
        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               ##
 
 #######################################################################
 ##              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 $
        MUST ( sambaDomainName $ 
               sambaSID ) 
        MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
-             sambaAlgorithmicRidBase ) )
+             sambaAlgorithmicRidBase $ 
+             sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $
+             sambaMaxPwdAge $ sambaMinPwdAge $
+             sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $
+             sambaForceLogoff $ sambaRefuseMachinePwdChange ))
 
 ##
 ## used for idmap_ldap module
 
 ##
 ## 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 ) )
 ##     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 ) )
-
index 95457758a650eb88de1f6324b2d1bf26fb11fc67..07c348bd84e598f34177c145737a7914d7489550 100644 (file)
@@ -63,6 +63,7 @@ RPCLIBDIR = $(LIBDIR)/rpc
 IDMAPLIBDIR = $(LIBDIR)/idmap
 CHARSETLIBDIR = $(LIBDIR)/charset
 AUTHLIBDIR = $(LIBDIR)/auth
 IDMAPLIBDIR = $(LIBDIR)/idmap
 CHARSETLIBDIR = $(LIBDIR)/charset
 AUTHLIBDIR = $(LIBDIR)/auth
+CONFIGLIBDIR = $(LIBDIR)/config
 CONFIGDIR = @configdir@
 VARDIR = @localstatedir@
 MANDIR = @mandir@
 CONFIGDIR = @configdir@
 VARDIR = @localstatedir@
 MANDIR = @mandir@
@@ -101,8 +102,7 @@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
 LIBSMBSHAREMODES_MAJOR=0
 LIBSMBSHAREMODES_MINOR=1
 
 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 = 
 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/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) \
          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/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)
 
 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_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 \
 
 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
 
 
 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 \
 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
 
 
 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_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
 
 
 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 \
                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
 
 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
                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 \
 
 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) \
             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
 
 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_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) \
 
 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
 
 
 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.
 # 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) \
          $(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)
 
 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) \
            $(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)
 
 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@)
 
 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) \
 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) \
                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...
 
 ######################################################################
 # now the rules...
@@ -760,9 +758,7 @@ wins : SHOWFLAGS @WINBIND_WINS_NSS@
 
 modules: SHOWFLAGS proto_exists $(MODULES)
 
 
 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:
        $(EVERYTHING_PROGS)
 
 .SUFFIXES:
@@ -1045,16 +1041,6 @@ bin/libsmbsharemodes.a: $(LIBSMBSHAREMODES_PICOBJS)
        @echo Linking libsmbsharemodes non-shared library $@
        @-$(AR) -rc $@ $(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 $@
 # 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 $@`
 
        @$(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 \
 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)
 
        @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@
 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_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
 
 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.
 # 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 \
 
 #test: all
 #      @if test -z "$(SMB4TORTURE)"; then \
index 9886526cf96328fea79ee806e3c0984ac95a89cb..92c90b62410577c615b5daf007a9fafd5a4d2c97 100644 (file)
@@ -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", 
 
 #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"));
        DEBUG(100, ("lm:\n"));
        dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
        DEBUG(100, ("nt:\n"));
index cdf87adebb980c23b57695288ab93e6cb4e3e5d4..4abc6c6656044e31863e138a099007789f9d4ead 100644 (file)
@@ -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;
 {
         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
 
        /* 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.
         */
 
         * 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;
                return NT_STATUS_NO_LOGON_SERVERS;
+       }
        
        /* Attempt connection */
        *retry = True;
        
        /* 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>.
         */
 
         * 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 \
                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();
                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();
                cli_shutdown(*cli);
                release_server_mutex();
-               return result;
+               return NT_STATUS_NO_LOGON_SERVERS;
        }
 
        /* We exit here with the mutex *locked*. JRA */
 
        }
 
        /* We exit here with the mutex *locked*. JRA */
 
+       *pipe_ret = netlogon_pipe;
+
        return NT_STATUS_OK;
 }
 
        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,
 ************************************************************************/
 
 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;
 {
        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;
        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++) {
        /* 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) ) {
        }
 
        if ( !NT_STATUS_IS_OK(nt_status) ) {
@@ -181,13 +216,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
          * in the info3 structure.  
          */
 
          * 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();
 
           
        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,
                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 */
                          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 = 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..... */
 
        /* 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;
 }
        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;
                                        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();
        const char *domain = lp_workgroup();
-       uint32 sec_channel_type = 0;
        fstring dc_name;
        struct in_addr dc_ip;
 
        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;
        }
 
                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) ) {
        /* 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;
        }
        
                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;
 }
                
        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
        /* 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;
        
        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.
         */
 
         * 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;
        }
                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;
        }
        
                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;
 }
 
        return nt_status;
 }
index 11d9aa09c4c4992ca8b47199b841fa82f438533a..738af73f49691d3287c36c9135d48cabee1901cf 100644 (file)
@@ -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) {
                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) {
                *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);
                *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);
index 6624631b53dd5c5df1153abb787d55c779212d2c..194a1ad532da432dd8a917e9363eca49ff89104f 100644 (file)
@@ -372,7 +372,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                unsigned char local_lm_response[24];
                
 #ifdef DEBUG_PASSWORD
                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
 
                dump_data(100, plaintext_password.data, plaintext_password.length);
 #endif
 
@@ -640,6 +640,44 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
        return token;
 }
 
        return token;
 }
 
+/******************************************************************************
+ 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 
 /******************************************************************************
  * 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 
@@ -831,6 +869,61 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
        return nt_status;
 }
 
        return nt_status;
 }
 
+/***************************************************************************
+ 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
 /***************************************************************************
  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
  to a SAM_ACCOUNT
index 3a81cba626d7655acc5f3a46cf89a6d77c53d314..0c263b6ab31bc60ef42a545727dbadbd65ae1b29 100644 (file)
@@ -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);
                }
                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;
                }
                        DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
                        return NT_STATUS_UNSUCCESSFUL;
                }
index a6136a9e2c26cfb7f558db36f0f361c093a6180b..5750deb31ca82bf482743a78360645a891878719 100755 (executable)
@@ -39,7 +39,7 @@
 #include <fcntl.h>
 
 #define MOUNT_CIFS_VERSION_MAJOR "1"
 #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 ""
 
 #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(fs == NULL)
                return errno;
        line_buf = malloc(4096);
-       if(line_buf == NULL) {
-               fclose(fs);
+       if(line_buf == NULL)
                return -ENOMEM;
                return -ENOMEM;
-       }
 
        while(fgets(line_buf,4096,fs)) {
                /* parse line from credential file */
 
        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;
                        *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) {
                } 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;
        char *pass;
        int i,j;
        int number_of_commas = 0;
-       int len;
+       int len = strlen(*ppasswrd);
 
        if(ppasswrd == NULL)
                return;
        else 
                (pass = *ppasswrd);
 
 
        if(ppasswrd == NULL)
                return;
        else 
                (pass = *ppasswrd);
 
-       len = strlen(pass);
-
        for(i=0;i<len;i++)  {
                if(pass[i] == ',')
                        number_of_commas++;
        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;
        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;
        struct in_addr server_ipaddr;
+       int rc;
 
        if(length > 1023) {
                printf("mount error: UNC name too long");
 
        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(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;
                                *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) {
                                        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 */
                                        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;
                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)
        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");
                                        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)
                                if(flags & MS_NOEXEC)
                                        strcat(mountent.mnt_opts,",noexec");
                                if(flags & MS_NOSUID)
index d13ae39416f45994677ee1e0247d72ff04c5726a..da517297f71b01b74c229b67685f3c8f4f02a90c 100644 (file)
@@ -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 */
   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)) {
 
   /* 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
     if ((password = strchr_m(username, ':')) != NULL)
       *password++ = '\0';
     else
-      password = "";
+      password = null_str;
   }
   else
   {
   }
   else
   {
-    username = "";
-    password = "";
+    username = null_str;
+    password = null_str;
     server   = uri + 6;
   }
 
     server   = uri + 6;
   }
 
@@ -335,10 +338,8 @@ char * get_ticket_cache( uid_t uid )
 
   if ( ticket_file == NULL )
   {
 
   if ( ticket_file == NULL )
   {
-#ifdef DEVELOPER
     /* no ticket cache found */
     fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
     /* no ticket cache found */
     fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
-#endif
     return NULL;
   }
 
     return NULL;
   }
 
index aeb3dd5d47992eb745a24eff2ffba323d08af420..deeab5886fea98154d0a1f953d510ed05e337fe5 100644 (file)
@@ -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(EXTRA_BIN_PROGS)
 AC_SUBST(EXTRA_SBIN_PROGS)
 AC_SUBST(EXTRA_ALL_TARGETS)
+AC_SUBST(CONFIG_LIBS)
 
 # Set defaults
 PIE_CFLAGS=""
 
 # 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
        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
         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:
 
 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
 
 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"
 
 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"
     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
 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
 
         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")
        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
         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";
   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
     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_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"
 
   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>],
   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
 
              [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>],
   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
 )
 
   INSTALLCLIENT=installclientlib
 )
 
-
 INSTALLCLIENTCMD_SH=:
 INSTALLCLIENTCMD_A=:
 INSTALLCLIENT=
 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
 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)"
      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
         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
         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
 )
 
   INSTALLCLIENT=installclientlib
 )
 
-
 #################################################
 # these tests are taken from the GNU fileutils package
 AC_CHECKING(how to get filesystem space usage)
 #################################################
 # 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(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_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)
 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)
index a30e8eed784c7be4f4f7f7997ac5a3ec90a649d5..3ca074581c13440abc9ffdb5731afbc1475fb953 100644 (file)
@@ -2,7 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-2000,
  *  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
  *  
  *  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.
 ****************************************************************************/
 
  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;
 {
        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 */
 
 
        /* 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;
        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;
 }
 
        return True;
 }
 
-
 /****************************************************************************
  Create a UNIX group on demand.
 ****************************************************************************/
 /****************************************************************************
  Create a UNIX group on demand.
 ****************************************************************************/
@@ -988,8 +987,8 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
                        close(fd);
                }
 
                        close(fd);
                }
 
-       } 
-       
+       }
+
        if (*new_gid == 0) {
                struct group *grp = getgrnam(unix_group);
 
        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;
        }
                DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
                return ret;
        }
-
+               
        return -1;
 }
 
        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)
 {
 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;
 }
 
                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 (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);
 
                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;
        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);
                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;
                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;
 }
 
        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);
+}
+
+
index 8f6cc6e582b4b8e2cbe3b41bce20ca27c197974e..d2eeaab4d8488ad94ca88d6362585e50efc57568 100644 (file)
@@ -130,7 +130,7 @@ typedef void **ADS_MODLIST;
 #define UF_UNUSED_5                            0x00800000
 
 #define UF_UNUSED_6                            0x01000000
 #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
 
 #define UF_UNUSED_8                            0x04000000
 #define UF_UNUSED_9                            0x08000000
 
index 796c8bb7404e94e9127936f5406847451cf1bd88..63a18c4923041c2a1d0b8e5ffaa43c8199c2d2f6 100644 (file)
@@ -27,7 +27,7 @@ struct nesting {
        struct nesting *next;
 };
 
        struct nesting *next;
 };
 
-typedef struct {
+typedef struct asn1_data {
        uint8 *data;
        size_t length;
        off_t ofs;
        uint8 *data;
        size_t length;
        off_t ofs;
@@ -37,13 +37,16 @@ typedef struct {
 
 
 #define ASN1_APPLICATION(x) ((x)+0x60)
 
 
 #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_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_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
 
 #define ASN1_ENUMERATED 0xa
 #define ASN1_SET 0x31
 
index 1be127aaac6b543011a52e0246216e30e7885164..194429ab673c446c19d261dfb7b6e962f95ebc20 100644 (file)
 #define _AUTHDATA_H 
 
 #include "rpc_misc.h"
 #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
 
 
 #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;
 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;
 
 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 {
 } PAC_SIGNATURE_DATA;
 
 typedef struct group_membership {
@@ -50,6 +60,8 @@ typedef struct group_membership_array {
        GROUP_MEMBERSHIP *group_membership;
 } 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;
 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 */
        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;
 
        uint32 user_rid;
        uint32 group_rid;
@@ -90,15 +102,15 @@ typedef struct pac_logon_info {
        uint32 group_membership_ptr;
        uint32 user_flags;
 
        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;
        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;
 
        uint32 sid_count;
        uint32 ptr_extra_sids;
@@ -121,6 +133,14 @@ typedef struct pac_logon_info {
        DOM_SID2 res_group_dom_sid;
        GROUP_MEMBERSHIP_ARRAY res_groups;
 
        DOM_SID2 res_group_dom_sid;
        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
 } PAC_LOGON_INFO;
 
 typedef struct pac_info_ctr
@@ -134,18 +154,19 @@ typedef struct pac_info_ctr
        } pac;
 } 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;
        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;
 
 typedef struct pac_data {
        uint32 num_buffers;
        uint32 version;
-       PAC_INFO_HDR *pac_info_hdr_ptr;
+       PAC_BUFFER *pac_buffer;
 } PAC_DATA;
 
 
 } PAC_DATA;
 
 
index e9d40c3b7c9480eea1a631bd89df57b65da1cc7f..df52e227f0c55d611bf89eec96f1b7216e9dd759 100644 (file)
@@ -57,25 +57,39 @@ struct print_job_info
        time_t t;
 };
 
        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 {
+       struct rpc_pipe_client *prev, *next;
+
        TALLOC_CTX *mem_ctx;
 
        struct cli_state *cli;
 
        int pipe_idx;
        TALLOC_CTX *mem_ctx;
 
        struct cli_state *cli;
 
        int pipe_idx;
+       const char *pipe_name;
        uint16 fnum;
 
        uint16 fnum;
 
-       int pipe_auth_flags;
-
-       NTLMSSP_STATE *ntlmssp_pipe_state;
-       const char *user_name;
        const char *domain;
        const char *domain;
+       const char *user_name;
        struct pwd_info pwd;
 
        struct pwd_info pwd;
 
-       struct netsec_auth_struct auth_info;
-
        uint16 max_xmit_frag;
        uint16 max_recv_frag;
        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 {
 };
 
 struct cli_state {
@@ -92,8 +106,11 @@ struct cli_state {
        int privileges;
 
        fstring desthost;
        int privileges;
 
        fstring desthost;
-       fstring user_name;
+
+       /* The credentials used to open the cli_state connection. */
        fstring domain;
        fstring domain;
+       fstring user_name;
+       struct pwd_info pwd;
 
        /*
         * The following strings are the
 
        /*
         * The following strings are the
@@ -111,7 +128,6 @@ struct cli_state {
        fstring full_dest_host_name;
        struct in_addr dest_ip;
 
        fstring full_dest_host_name;
        struct in_addr dest_ip;
 
-       struct pwd_info pwd;
        DATA_BLOB secblob; /* cryptkey or negTokenInit */
        uint32 sesskey;
        int serverzone;
        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;
 
           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;
 
        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;
        /* 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
 };
 
 #define CLI_FULL_CONNECTION_DONT_SPNEGO 0x0001
index 794aea757662845bfee1bccf06f3b71470162064..c856aaa7625794dc20d2305ec66e4099c502e2e9 100644 (file)
                } \
 }
 
                } \
 }
 
+/* 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) \
 { \
 /* demote an element to the top of the list, needs a tmp pointer */
 #define DLIST_DEMOTE(list, p, tmp) \
 { \
index 7c98171250c1602c8393ea647a9cd7316e6ff1df..593d5d99eef62cb6af4a7c34b5720b477737c895 100644 (file)
@@ -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) 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
    
    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
 #define WERR_NOMEM W_ERROR(8)
 #define WERR_GENERAL_FAILURE W_ERROR(31)
 #define WERR_NOT_SUPPORTED W_ERROR(50)
 #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)
 #define WERR_PRINTQ_FULL W_ERROR(61)
 #define WERR_NO_SPOOL_SPACE W_ERROR(62)
 #define WERR_NO_SUCH_SHARE W_ERROR(67)
 #define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse)
 #define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued)
 
 #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 */
 
 
 /* DFS errors */
 
index 51aa218ac6c6eca212b75c939a76f06f2724e92e..573982903b8727904ed80825a6ae0b50b5d97e50 100644 (file)
@@ -27,7 +27,8 @@
 
 #ifndef __cplusplus
 #define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
 
 #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
 #define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
 #define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
 #define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
 #include <net/if.h>
 #endif
 
 #include <net/if.h>
 #endif
 
+
 #ifdef HAVE_SYS_MOUNT_H
 #include <sys/mount.h>
 #endif
 #ifdef HAVE_SYS_MOUNT_H
 #include <sys/mount.h>
 #endif
@@ -896,19 +898,17 @@ extern int errno;
 
 #include "privileges.h"
 
 
 #include "privileges.h"
 
-#include "rpc_creds.h"
+#include "rpc_misc.h"
+
+#include "rpc_dce.h"
 
 #include "mapping.h"
 
 #include "passdb.h"
 
 
 #include "mapping.h"
 
 #include "passdb.h"
 
-#include "ntdomain.h"
-
-#include "rpc_misc.h"
-
 #include "rpc_secdes.h"
 
 #include "rpc_secdes.h"
 
-#include "nt_printing.h"
+#include "authdata.h"
 
 #include "msdfs.h"
 
 
 #include "msdfs.h"
 
@@ -923,6 +923,29 @@ extern int errno;
 
 #include "auth.h"
 
 
 #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"
 #include "idmap.h"
 
 #include "client.h"
@@ -945,6 +968,8 @@ extern int errno;
 
 #include "spnego.h"
 
 
 #include "spnego.h"
 
+#include "rpc_client.h"
+
 /*
  * Type for wide character dirent structure.
  * Only d_name is defined by POSIX.
 /*
  * 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 "smbldap.h"
 
+#include "smb_ldap.h"
+
 /***** automatically generated prototypes *****/
 #ifndef NO_PROTO_H
 #include "proto.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 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);
 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);
index 1039e0d9a7074d31a85461418a9b5c30b3844f44..abe219374ed57eb59387625821a474aedc17cde1 100644 (file)
 #define MSG_SMB_SAM_SYNC     3003
 #define MSG_SMB_SAM_REPL     3004
 #define MSG_SMB_UNLOCK       3005
 #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
 
 /* winbind messages */
 #define MSG_WINBIND_FINISHED     4001
@@ -77,4 +82,8 @@
 #define FLAG_MSG_PRINT_NOTIFY  0x0008
 #define FLAG_MSG_PRINT_GENERAL 0x0010
 
 #define FLAG_MSG_PRINT_NOTIFY  0x0008
 #define FLAG_MSG_PRINT_GENERAL 0x0010
 
+struct process_id {
+       pid_t pid;
+};
+
 #endif
 #endif
index c41310c7f7536043f143d039ad6e0baed23bdacd..8b317a9d59df253405e78d69bcc329cb1325be5f 100644 (file)
@@ -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_idle_event_fn)(void **data,time_t *interval,time_t now);
 
-typedef void (smb_exit_event_fn)(void **data);
-
 #endif /* _MODULE_H */
 #endif /* _MODULE_H */
index 87fac492db39124aafff55692318f4b6eb4565fd..967aac2bb5f06fe9f4ea36e6fc089f2fa6a66d7f 100644 (file)
 #ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
 #define _NT_DOMAIN_H 
 
 #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.
 /*
  * 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.... */
        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;
 
 /*
 } prs_struct;
 
 /*
@@ -97,7 +74,7 @@ typedef struct _output_data {
         * The current PDU being returned. This inclues
         * headers, data and authentication footer.
         */
         * 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;
 
        /* 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
         * 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.
 
        /*
         * The amount of data needed to complete the in_pdu.
@@ -158,22 +135,22 @@ struct handle_list {
 
 /* Domain controller authentication protocol info */
 struct dcinfo {
 
 /* 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  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 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;
 
        BOOL challenge_sent;
        BOOL got_session_key;
        BOOL authenticated;
-
 };
 
 typedef struct pipe_rpc_fns {
 };
 
 typedef struct pipe_rpc_fns {
@@ -188,6 +165,46 @@ typedef struct pipe_rpc_fns {
        
 } 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.
 /*
  * 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. */
 
        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.
 
        /*
         * Windows user info.
@@ -233,14 +242,13 @@ typedef struct pipes_struct {
        fstring wks;
 
        /*
        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;
         */
 
        fstring pipe_user_name;
        struct current_user pipe_user;
-
        DATA_BLOB session_key;
        DATA_BLOB session_key;
-
        /*
         * Set to true when an RPC bind has been done on this pipe.
         */
        /*
         * 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;
 
 
        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. */
        TALLOC_CTX *mem_ctx;
 
        /* handle database to use on this pipe. */
@@ -383,27 +392,11 @@ typedef struct {
 
 /* end higher order functions */
 
 
 /* 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 */
 
 #endif /* _NT_DOMAIN_H */
index 267779c434d462334e40a9673fb40edc00edd4ae..30a37e06c3ef2e9dcef94988248eccada2de71ca 100644 (file)
@@ -34,7 +34,8 @@ enum NTLM_MESSAGE_TYPE
        NTLMSSP_NEGOTIATE = 1,
        NTLMSSP_CHALLENGE = 2,
        NTLMSSP_AUTH      = 3,
        NTLMSSP_NEGOTIATE = 1,
        NTLMSSP_CHALLENGE = 2,
        NTLMSSP_AUTH      = 3,
-       NTLMSSP_UNKNOWN   = 4
+       NTLMSSP_UNKNOWN   = 4,
+       NTLMSSP_DONE      = 5 /* samba final state */
 };
 
 /* NTLMSSP negotiation flags */
 };
 
 /* 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_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_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;
 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);
 
        const char *(*get_global_myname)(void);
        const char *(*get_domain)(void);
 
-       /* SMB Signing */
-       
-       uint32 ntlmssp_seq_num;
-
        /* ntlmv2 */
        /* 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 */
 
        /* 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.
 
        /* 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;
        DATA_BLOB stored_response; 
        
 } NTLMSSP_STATE;
-
index 114585346e16a97d6388d31fdc47cc648d664945..e985ab582dcbe666fd5b2a66563165d949ecd9af 100644 (file)
@@ -233,6 +233,7 @@ struct acct_info
 };
 
 struct samr_displayentry {
 };
 
 struct samr_displayentry {
+       uint32 idx;
        uint32 rid;
        uint16 acct_flags;
        const char *account_name;
        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. 
  */
 
  * 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 
 {
 
 typedef struct pdb_context 
 {
@@ -373,6 +374,14 @@ typedef struct pdb_context
                                    const char ***names,
                                    uint32 **attrs);
 
                                    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);
        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);
                                           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,
        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);
 
                                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);
        BOOL (*search_users)(struct pdb_methods *methods,
                             struct pdb_search *search,
                             uint16 acct_flags);
index 220fd08ef1e2ee0b3063dbfde309b91707d806d4..54f32d5954c3d0d975616e199856470fb98db58b 100644 (file)
@@ -57,7 +57,7 @@ struct printif
                    print_status_struct *status);
   int (*queue_pause)(int snum);
   int (*queue_resume)(int snum);
                    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);
   int (*job_pause)(int snum, struct printjob *pjob);
   int (*job_resume)(int snum, struct printjob *pjob);
   int (*job_submit)(int snum, struct printjob *pjob);
index 9ca2d5aa8c9f78108b14edb3b69f8995d3d21ba4..8a83c0f8ae87fc9c18e9b93977b55b989b9788ef 100644 (file)
 #define _RPC_CLIENT_H
 
 /* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */
 #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 ) \
                              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 ( 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 );\
 }
 
        }\
        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 ) \
                              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 ( 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 );\
        }\
        prs_mem_free( &q_ps );\
        prs_mem_free( &r_ps );\
index 88b8380870e3d0e4a9d11a8c2b96fc8aa66b0e60..3de4d2b691e71abdcb0865b5c61709d54d036549 100644 (file)
@@ -23,9 +23,6 @@
 #ifndef _DCE_RPC_H /* _DCE_RPC_H */
 #define _DCE_RPC_H 
 
 #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 {
 /* 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_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 */
 };
 
 /* DCE/RPC flags */
@@ -45,29 +42,41 @@ enum RPC_PKT_TYPE {
 #define RPC_FLG_LAST  0x02
 #define RPC_FLG_NOCALL 0x20
 
 #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
 
 #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 */
 
 /* 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
 #define RPC_PIPE_AUTH_SIGN_LEVEL 0x5
 #define RPC_PIPE_AUTH_SEAL_LEVEL 0x6
+#endif
 
 /* Netlogon schannel auth type and level */
 
 /* 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... */
 
 /* 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
 
 #define NETLOGON_NEG_SCHANNEL                  0x40000000
 #define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT      0x2010b000
 
-enum netsec_direction {
+enum schannel_direction {
        SENDER_IS_INITIATOR,
        SENDER_IS_ACCEPTOR
 };
 
        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 */
 
 /* 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 {
 
 /* 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;
 
        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) */
 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
 
 
 #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 */
 /* 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 */
        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 */
 
 /* 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 */
        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. */
 
 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;
 
        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 */
 #endif /* _DCE_RPC_H */
index 39316a5d5410de3a881b633fb0a63c2a8f88b306..7aee208c14b0fa3d8c333b8a3054e0054375ae5f 100644 (file)
 #define DFSFLAG_ADD_VOLUME           0x00000001
 #define DFSFLAG_RESTORE_VOLUME       0x00000002
 
 #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. */
 
 /* 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 */
        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  
 #endif  
index e06918730a4d437d916bab33273644167f2ed06c..24bf1e948a36b33744169a4b642a183e9724c5df 100644 (file)
@@ -21,9 +21,6 @@
 #ifndef _RPC_DS_H /* _RPC_LSA_H */
 #define _RPC_DS_H 
 
 #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
 /* Opcodes available on PIPE_LSARPC_DS */
 
 #define DS_GETPRIMDOMINFO      0x00
index b692a762257a1dcbd4ddb71c17fd7e6ee239a09f..7ce1199b213ac9577887400e50478000f6bebe20 100644 (file)
 #define EVENTLOG_AUDIT_FAILURE        0x0010
 
 
 #define EVENTLOG_AUDIT_FAILURE        0x0010
 
 
-typedef struct eventlog_q_open_eventlog
-{
-       uint32 unknown1;
+/***********************************/
+
+typedef struct {
+       uint16 unknown1;
        uint16 unknown2;
        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;
        POLICY_HND handle;
        WERROR status;
-}
-EVENTLOG_R_OPEN_EVENTLOG;
+} EVENTLOG_R_OPEN_EVENTLOG;
 
 
-typedef struct eventlog_q_close_eventlog
-{
+
+/***********************************/
+
+typedef struct {
        POLICY_HND handle;
        POLICY_HND handle;
-}
-EVENTLOG_Q_CLOSE_EVENTLOG;
+} EVENTLOG_Q_CLOSE_EVENTLOG;
 
 
-typedef struct eventlog_r_close_eventlog
-{
+typedef struct {
        POLICY_HND handle;
        WERROR status;
        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;
        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;
        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;
        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;
        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;
 {
        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;
        uint32 length;
        uint32 reserved1;
        uint32 record_number;
@@ -136,8 +133,7 @@ typedef struct eventlog_record
        uint32 data_offset;
 } 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;
        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;
 
        uint32 data_padding;
 } Eventlog_data_record;
 
-typedef struct eventlog_entry
-{
+typedef struct eventlog_entry {
        Eventlog_record record;
        Eventlog_data_record data_record;
        uint8 *data;
        Eventlog_record record;
        Eventlog_data_record data_record;
        uint8 *data;
@@ -160,8 +155,7 @@ typedef struct eventlog_entry
        struct eventlog_entry *next;
 } 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;
        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;
        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;
        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;
        WERROR status;
-}
-EVENTLOG_R_CLEAR_EVENTLOG;
+} EVENTLOG_R_CLEAR_EVENTLOG;
 
 #endif /* _RPC_EVENTLOG_H */
 
 #endif /* _RPC_EVENTLOG_H */
index 053a23b218508dee8cee55290d8ecda6e6996731..dd255c28d5d5e3b52166db8fe0a5375bb45c7d23 100644 (file)
@@ -24,8 +24,6 @@
 #ifndef _RPC_LSA_H /* _RPC_LSA_H */
 #define _RPC_LSA_H 
 
 #ifndef _RPC_LSA_H /* _RPC_LSA_H */
 #define _RPC_LSA_H 
 
-#include "rpc_misc.h"
-
 /* Opcodes available on PIPE_LSARPC */
 
 #if 0  /* UNIMPLEMENTED */
 /* Opcodes available on PIPE_LSARPC */
 
 #if 0  /* UNIMPLEMENTED */
index 9f35450d952a40d254b97f1cc028662e8b4197da..e5d91c1b6300750911fbb895981f7be3798e18ef 100644 (file)
@@ -21,9 +21,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
    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 
 
 #ifndef _RPC_MISC_H /* _RPC_MISC_H */
 #define _RPC_MISC_H 
 
@@ -302,8 +299,7 @@ typedef struct {
  **********************************************************************/
 
 /* DOM_CLNT_SRV - client / server names */
  **********************************************************************/
 
 /* 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 */
        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 */
 } 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 */
        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 */
 } 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 */
        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 */
        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 */
        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 */
        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 */
        uint32 low;
        uint32 high;
 } DOM_LOGON_ID;
 
 /* OWF INFO */
-typedef struct owf_info
-{
+typedef struct owf_info {
        uint8 data[16];
 } 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;
 
 typedef struct uint64_s
 {
        uint32 low;
        uint32 high;
 } UINT64_S;
 
-
-
-
-
 #endif /* _RPC_MISC_H */
 #endif /* _RPC_MISC_H */
index b3fe16ba2b32fda89dd4ec943a200ead6e1155b4..b004e26397ed673514de8c131a560384b3c48429 100644 (file)
 #define NL_CTRL_REPL_IN_PROGRESS 0x0002
 #define NL_CTRL_FULL_SYNC        0x0004
 
 #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 */
 #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 */
        uint32 ptr_user_info;
 
        NTTIME logon_time;            /* logon time */
@@ -145,8 +156,7 @@ typedef struct net_user_info_2
 #endif
 
 /* NET_USER_INFO_3 */
 #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 */
        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;
        
        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 */
        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;
 
        DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */
        uint32 *other_sids_attrib;
-
 } NET_USER_INFO_3;
 
 
 /* NETLOGON_INFO_1 - pdc status info, i presume */
 } 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 */
        uint32 flags;            /* 0x0 - undocumented */
        uint32 pdc_status;       /* 0x0 - undocumented */
-
 } NETLOGON_INFO_1;
 
 /* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */
 } 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 */
        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 */
 } 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 */
        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 */
        uint32 reserved_3;       /* 0x0 - undocumented */
        uint32 reserved_4;       /* 0x0 - undocumented */
        uint32 reserved_5;       /* 0x0 - undocumented */
-
 } NETLOGON_INFO_3;
 
 /********************************************************
 } NETLOGON_INFO_3;
 
 /********************************************************
@@ -250,8 +260,7 @@ typedef struct netlogon_3_info
 
 /* NET_Q_LOGON_CTRL - LSA Netr Logon Control */
 
 
 /* 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;
        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 */
 
 
 /* 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;
 
        uint32 switch_value;
        uint32 ptr;
 
@@ -273,22 +281,18 @@ typedef struct net_r_logon_ctrl_info
 } NET_R_LOGON_CTRL;
 
 
 } NET_R_LOGON_CTRL;
 
 
-typedef struct ctrl_data_info_5
-{
+typedef struct ctrl_data_info_5 {
        uint32          function_code;
        
        uint32          ptr_domain;
        UNISTR2         domain;
        uint32          function_code;
        
        uint32          ptr_domain;
        UNISTR2         domain;
-       
 } CTRL_DATA_INFO_5;
 
 } CTRL_DATA_INFO_5;
 
-typedef struct ctrl_data_info_6
-{
+typedef struct ctrl_data_info_6 {
        uint32          function_code;
        
        uint32          ptr_domain;
        UNISTR2         domain;
        uint32          function_code;
        
        uint32          ptr_domain;
        UNISTR2         domain;
-       
 } CTRL_DATA_INFO_6;
 
 
 } CTRL_DATA_INFO_6;
 
 
@@ -301,8 +305,7 @@ typedef struct ctrl_data_info_6
  ********************************************************/
 
 /* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */
  ********************************************************/
 
 /* 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 */
        
        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;
                CTRL_DATA_INFO_5 info5;
                CTRL_DATA_INFO_6 info6;
        } info;
-       
 } NET_Q_LOGON_CTRL2;
 
 /*******************************************************
 } NET_Q_LOGON_CTRL2;
 
 /*******************************************************
@@ -322,8 +324,7 @@ typedef struct net_q_logon_ctrl2_info
  *******************************************************/
 
 /* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */
  *******************************************************/
 
 /* 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;
 
        uint32       switch_value;  /* 0x1, 0x3 */
        uint32       ptr;
 
@@ -336,13 +337,11 @@ typedef struct net_r_logon_ctrl2_info
        } logon;
 
        NTSTATUS status; /* return code */
        } logon;
 
        NTSTATUS status; /* return code */
-
 } NET_R_LOGON_CTRL2;
 
 /* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */
 
 } 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;
        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 */
 
 
 /* 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 */
        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 */
        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 */
 } 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 */
        UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
 
        NTSTATUS status; /* return code */
-
 } NET_R_TRUST_DOM_LIST;
 
 
 /* NEG_FLAGS */
 } 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 */
 } 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 */
 } 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 */
        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 */
        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 */
        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 */
 } 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 */
        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 */
 } 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 */
        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 */
 
 
 /* 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 */
 } 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 */
 } 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) */
        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 */
        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 */
 } 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 */
        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 */
        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 */
 } 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 */
 } 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 */
 } 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;
        uint16          validation_level;
-
 } NET_Q_SAM_LOGON;
 
 /* NET_R_SAM_LOGON */
 } 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 */
     
        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 */
 } 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 */
 } 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 */
 } 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;
        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 */
        uint32 sync_context;
 
        uint32 max_size;       /* preferred maximum length */
-
 } NET_Q_SAM_SYNC;
 
 /* SAM_DELTA_HDR */
 } 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;
        uint16 type;  /* type of structure attached */
        uint16 type2;
        uint32 target_rid;
 
        uint32 type3;
        uint32 ptr_delta;
-
 } SAM_DELTA_HDR;
 
 /* LOCKOUT_STRING */
 } SAM_DELTA_HDR;
 
 /* LOCKOUT_STRING */
@@ -617,7 +572,6 @@ typedef struct account_lockout_string {
        UINT64_S reset_count;
        uint32 bad_attempt_lockout;
        uint32 dummy;
        UINT64_S reset_count;
        uint32 bad_attempt_lockout;
        uint32 dummy;
-
 } LOCKOUT_STRING;
 
 /* HDR_LOCKOUT_STRING */
 } LOCKOUT_STRING;
 
 /* HDR_LOCKOUT_STRING */
@@ -625,12 +579,10 @@ typedef struct hdr_account_lockout_string {
        uint16 size;
        uint16 length;
        uint32 buffer;
        uint16 size;
        uint16 length;
        uint32 buffer;
-
 } HDR_LOCKOUT_STRING;
 
 /* SAM_DOMAIN_INFO (0x1) */
 } 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;
 
        UNIHDR hdr_dom_name;
        UNIHDR hdr_oem_info;
 
@@ -666,13 +618,10 @@ typedef struct sam_domain_info_info
        uint32 unknown6;
        uint32 unknown7;
        uint32 unknown8;
        uint32 unknown6;
        uint32 unknown7;
        uint32 unknown8;
-
-
 } SAM_DOMAIN_INFO;
 
 /* SAM_GROUP_INFO (0x2) */
 } 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;
        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;
        UNISTR2 uni_grp_name;
        UNISTR2 uni_grp_desc;
        RPC_DATA_BLOB buf_sec_desc;
-
 } SAM_GROUP_INFO;
 
 /* SAM_PWD */
 } 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 */
        /* 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;
 
        UNIHDR hdr_empty_lm;
        UNIHDR hdr_empty_nt;
-
 } SAM_PWD;
 
 /* SAM_ACCOUNT_INFO (0x5) */
 } 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;
 
        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_PWD pass;
        RPC_DATA_BLOB buf_sec_desc;
        UNISTR2 uni_profile;
-
 } SAM_ACCOUNT_INFO;
 
 /* SAM_GROUP_MEM_INFO (0x8) */
 } 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;
        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) */
 } 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 */
        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;
        UNISTR2 uni_als_name;
        RPC_DATA_BLOB buf_sec_desc;
        UNISTR2 uni_als_desc;
-
 } SAM_ALIAS_INFO;
 
 /* SAM_ALIAS_MEM_INFO (0xC) */
 } 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];
        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;
        uint32 num_sids;
        uint32 *ptr_sids;
        DOM_SID2 *sids;
-
 } SAM_ALIAS_MEM_INFO;
 
 
 /* SAM_DELTA_POLICY (0x0D) */
 } 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 */
        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 */
 } SAM_DELTA_POLICY;
 
 /* SAM_DELTA_TRUST_DOMS */
-typedef struct
-{
+typedef struct {
        uint32 buf_size;
        SEC_DESC *sec_desc;
        DOM_SID2 sid;
        uint32 buf_size;
        SEC_DESC *sec_desc;
        DOM_SID2 sid;
@@ -860,12 +797,10 @@ typedef struct
 
        uint32 unknown3;
        UNISTR2 domain;
 
        uint32 unknown3;
        UNISTR2 domain;
-
 } SAM_DELTA_TRUSTDOMS;
 
 /* SAM_DELTA_PRIVS (0x10) */
 } SAM_DELTA_TRUSTDOMS;
 
 /* SAM_DELTA_PRIVS (0x10) */
-typedef struct
-{
+typedef struct {
        DOM_SID2 sid;
 
        uint32 priv_count;
        DOM_SID2 sid;
 
        uint32 priv_count;
@@ -896,8 +831,7 @@ typedef struct
 } SAM_DELTA_PRIVS;
 
 /* SAM_DELTA_SECRET */
 } SAM_DELTA_PRIVS;
 
 /* SAM_DELTA_SECRET */
-typedef struct
-{
+typedef struct {
        uint32 buf_size;
        SEC_DESC *sec_desc;
        UNISTR2 secret;
        uint32 buf_size;
        SEC_DESC *sec_desc;
        UNISTR2 secret;
@@ -928,19 +862,16 @@ typedef struct
 
        uint32 buf_size3;
        SEC_DESC *sec_desc2;
 
        uint32 buf_size3;
        SEC_DESC *sec_desc2;
-
 } SAM_DELTA_SECRET;
 
 /* SAM_DELTA_MOD_COUNT (0x16) */
 } 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;
 
         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;
        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 */
 } 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;
        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 */
 } 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;
        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 */
        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 */
 } 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 */
        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 (file)
index 0000000..947794b
--- /dev/null
@@ -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 (file)
index 0000000..0e3a6eb
--- /dev/null
@@ -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 (file)
index 0000000..3999a68
--- /dev/null
@@ -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 */
index f6ddf5b9adffda5f11ac0d8ca4105ae0b1d364b3..b24b640237fec10d1ecf0a9fd0598293a7d4aa01 100644 (file)
@@ -25,8 +25,6 @@
 #ifndef _RPC_REG_H /* _RPC_REG_H */
 #define _RPC_REG_H 
 
 #ifndef _RPC_REG_H /* _RPC_REG_H */
 #define _RPC_REG_H 
 
-#include "reg_objects.h"
-
 /* RPC opnum */
 
 #define REG_OPEN_HKCR          0x00
 /* 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_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
 
 #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_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"
 #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"
 #define REG_FULL_RESOURCE_DESCRIPTOR   9
 #define REG_RESOURCE_REQUIREMENTS_LIST 10
 
 #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 
 /* 
  * 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 {
 /* 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;
        uint32          access_granted;
        REGISTRY_HOOK   *hook;  
 } REGISTRY_KEY;
index fb829558d442e61ee499ac0cc4e2e2881ac33f81..6067587654e123c202ed16809d45b39521739775 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
 #define _RPC_SAMR_H 
 
 #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:
 /*******************************************************************
  the following information comes from a QuickView on samsrv.dll,
  and gives an idea of exactly what is needed:
index b2b97e391e00842812abc65eb15dd9ae785f3f7e..c385e41fd30954ad128bce8f392d458b1b7ee108 100644 (file)
@@ -481,13 +481,16 @@ typedef struct standard_mapping {
          SC_RIGHT_MGR_ENUMERATE_SERVICE        | \
          SC_RIGHT_MGR_QUERY_LOCK_STATUS )
 
          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 )
 
        ( 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 */ 
 
 
 /* Service Object Bits */ 
 
@@ -515,12 +518,14 @@ typedef struct standard_mapping {
          SC_RIGHT_SVC_STOP                     | \
          SC_RIGHT_SVC_PAUSE_CONTINUE )
 
          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 )
 
        ( STANDARD_RIGHTS_REQUIRED_ACCESS       | \
          SERVICE_READ_ACCESS                   | \
          SERVICE_EXECUTE_ACCESS                | \
          SC_RIGHT_SVC_CHANGE_CONFIG )
 
+#define SERVICE_ALL_ACCESS SERVICE_WRITE_ACCESS
+
           
 
 /*
           
 
 /*
index 77dd004fed40a4156b3909c88ed5b6c2529d761f..443a6588a661ab4a01bc79454a60765017810393 100644 (file)
 #ifndef _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
 #define _RPC_SVCCTL_H 
 
 #ifndef _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
 #define _RPC_SVCCTL_H 
 
-
 /* svcctl pipe */
 
 #define SVCCTL_CLOSE_SERVICE                   0x00
 #define SVCCTL_CONTROL_SERVICE                 0x01
 /* 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_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
 #define SVCCTL_ENUM_DEPENDENT_SERVICES_W       0x0d
 #define SVCCTL_ENUM_SERVICES_STATUS_W          0x0e
 #define SVCCTL_OPEN_SCMANAGER_W                        0x0f
 #define SVCCTL_CONTROL_STOP                    0x00000001
 #define SVCCTL_CONTROL_PAUSE                   0x00000002
 #define SVCCTL_CONTROL_CONTINUE                        0x00000003
 #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_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 */
 
 
 /* utility structures for RPCs */
 
@@ -127,13 +133,7 @@ typedef struct {
 } SERVICE_STATUS;
 
 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;
        uint32 process_id;
        uint32 service_flags;
 } SERVICE_STATUS_PROCESS;
@@ -158,7 +158,8 @@ typedef struct {
 } SERVICE_CONFIG;
 
 typedef struct {
 } SERVICE_CONFIG;
 
 typedef struct {
-        UNISTR2 *description;
+       uint32 unknown; 
+        UNISTR description;
 } SERVICE_DESCRIPTION;
 
 typedef struct {
 } SERVICE_DESCRIPTION;
 
 typedef struct {
@@ -168,20 +169,12 @@ typedef struct {
 
 typedef struct {
         uint32 reset_period;
 
 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;
         UNISTR2 *command;
-        uint32  nActions;
-        SC_ACTION *saActions;
-        UNISTR2 *description;
+        uint32  num_actions;
+        SC_ACTION *actions;
 } SERVICE_FAILURE_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 */
 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 */      
  
 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  */
 } SERVICE_CONTROL_OPS;
 
 /* structure to store the service handle information  */
@@ -341,6 +334,7 @@ typedef struct {
        WERROR status;
 } SVCCTL_R_ENUM_DEPENDENT_SERVICES;
 
        WERROR status;
 } SVCCTL_R_ENUM_DEPENDENT_SERVICES;
 
+
 /**************************/
 
 typedef struct {
 /**************************/
 
 typedef struct {
@@ -354,32 +348,58 @@ typedef struct {
        WERROR status;
 } SVCCTL_R_QUERY_SERVICE_CONFIG;
 
        WERROR status;
 } SVCCTL_R_QUERY_SERVICE_CONFIG;
 
+
+/**************************/
+
 typedef struct {
        POLICY_HND handle;
 typedef struct {
        POLICY_HND handle;
-        uint32 info_level;
+       uint32 level;
        uint32 buffer_size;
 } SVCCTL_Q_QUERY_SERVICE_CONFIG2;
 
 typedef struct {
        uint32 buffer_size;
 } SVCCTL_Q_QUERY_SERVICE_CONFIG2;
 
 typedef struct {
-       UNISTR2 *description;
-        uint32 returned;
+       RPC_BUFFER buffer;
        uint32 needed;
        uint32 needed;
-        uint32 offset;
        WERROR status;
 } SVCCTL_R_QUERY_SERVICE_CONFIG2;
 
        WERROR status;
 } SVCCTL_R_QUERY_SERVICE_CONFIG2;
 
+
+/**************************/
+
 typedef struct {
        POLICY_HND handle;
 typedef struct {
        POLICY_HND handle;
-        uint32 info_level;
+        uint32 level;
        uint32 buffer_size;
 } SVCCTL_Q_QUERY_SERVICE_STATUSEX;
 
 typedef struct {
        RPC_BUFFER buffer;
        uint32 buffer_size;
 } SVCCTL_Q_QUERY_SERVICE_STATUSEX;
 
 typedef struct {
        RPC_BUFFER buffer;
-        uint32 returned;
        uint32 needed;
        WERROR status;
 } SVCCTL_R_QUERY_SERVICE_STATUSEX;
 
        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 */
 
 #endif /* _RPC_SVCCTL_H */
 
index c0778383c652b7983bda1735fe7cc095c1554d72..61d2237b2dd638ee28bbf1449097ae7e991dcda7 100644 (file)
@@ -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_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 */
 
 /* 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;
 
 
 } 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;
 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;
        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;
        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 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 */
 
 typedef struct {
        fstring smb_name; /* user name from the client */
@@ -619,28 +629,19 @@ struct interface
        struct in_addr nmask;
 };
 
        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;
 /* 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 */
        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). */
        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;
        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
 
 #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 {
 
 /* 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;
        int cnum;
        fstring name;
 };
 
 struct connections_data {
        int magic;
-       pid_t pid;
+       struct process_id pid;
        int cnum;
        uid_t uid;
        gid_t gid;
        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,
 /* 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() \
 };
 
 #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) \
                                 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
                                 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 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 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.
 
 /*
  * On the wire return values for oplock types.
@@ -1483,95 +1501,23 @@ extern int chain_size;
 #define OPLOCKLEVEL_NONE 0
 #define OPLOCKLEVEL_II 1
 
 #define OPLOCKLEVEL_NONE 0
 #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
 
 /*
  * 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 {
 /* 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 (*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;
 };
 
 
        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 {
 /* 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"
 
 /* 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 */
 #endif /* _SMB_H */
diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h
new file mode 100644 (file)
index 0000000..144317c
--- /dev/null
@@ -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
index f61ba624c696d662b318c9b5479575c966728483..1e04ea496de2ca5ef4f4fd62c2746844e792c752 100644 (file)
@@ -55,7 +55,7 @@ struct smb_share_mode_entry {
        uint32_t access_mask;
        struct timeval open_time;
        uint32_t file_id;
        uint32_t access_mask;
        struct timeval open_time;
        uint32_t file_id;
-       pid_t pid;
+       struct process_id pid;
 };
 
 /*
 };
 
 /*
index df56f60bf39cdc1a8342d19dbdbe93158c4fe6ca..bea1a6d84a36c54dd3eec4bf6a4aa93009f64dfe 100644 (file)
@@ -1,5 +1,5 @@
 /* 
 /* 
-   Unix SMB/CIFS implementation.
+   Unix SMB/CIFS mplementation.
    LDAP protocol helper functions for SAMBA
    Copyright (C) Gerald Carter                 2001-2003
     
    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_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"
 
 #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_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_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;
 
 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 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 */
 
 /* Function declarations -- not included in proto.h so we don't
    have to worry about LDAP structure types */
index 8bb13bd354a3942641bbdc523727fdfe4b458770..66abe317053a7e268ac233738b96b62e8f2f1f2f 100644 (file)
@@ -43,7 +43,7 @@ typedef enum _spnego_negResult {
 } negResult_t;
 
 typedef struct spnego_negTokenInit {
 } negResult_t;
 
 typedef struct spnego_negTokenInit {
-       char **mechTypes;
+       const char **mechTypes;
        int reqFlags;
        DATA_BLOB mechToken;
        DATA_BLOB mechListMIC;
        int reqFlags;
        DATA_BLOB mechToken;
        DATA_BLOB mechListMIC;
index 04db59cf012859f60013ebb01a5e25c2083a8d26..1029df53aee8f53bd8e27340bea837f0374ca3d7 100644 (file)
@@ -18,8 +18,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
    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)
 
 #define srvstr_pull(base_ptr, dest, src, dest_len, src_len, flags) \
     pull_string(base_ptr, dest, src, dest_len, src_len, flags)
 
index 423dc1675a6d9b9cba04145de964586b0aa46e2a..b02edc5b40102e0f8fc64db1447d5986e6511043 100644 (file)
@@ -3,6 +3,7 @@
  *  account policy storage
  *  Copyright (C) Jean François Micouleau      1998-2001.
  *  Copyright (C) Andrew Bartlett              2002
  *  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
  *  
  *  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
 #include "includes.h"
 static TDB_CONTEXT *tdb; 
 
 #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)
 };
 
 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
 ****************************************************************************/
 
 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++) {
 {
        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;
                        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;
                        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;
 
 
 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;
 
        if (value)
                *value = 0;
@@ -199,18 +318,21 @@ BOOL account_policy_get(int field, uint32 *value)
        if (value)
                *value = regval;
 
        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;
 }
 
 
 /****************************************************************************
        return True;
 }
 
 
 /****************************************************************************
+Set an account policy (in tdb) 
 ****************************************************************************/
 ****************************************************************************/
+
 BOOL account_policy_set(int field, uint32 value)
 {
        fstring name;
 
 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) {
 
        fstrcpy(name, decode_account_policy_name(field));
        if (!*name) {
@@ -219,15 +341,71 @@ BOOL account_policy_set(int field, uint32 value)
        }
 
        if (!tdb_store_uint32(tdb, name, 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;
        }
 
                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;
 }
 
        
        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);
+}
+
+
 /****************************************************************************
 ****************************************************************************/
 
 /****************************************************************************
 ****************************************************************************/
 
diff --git a/source3/lib/arc4.c b/source3/lib/arc4.c
new file mode 100644 (file)
index 0000000..03ca54c
--- /dev/null
@@ -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;
+}
index 161f46a941723ffd439253b6089a79ca3ed52e32..ccd0d27f47b61a68e13ded9759df9e2b13fb36d1 100644 (file)
@@ -22,8 +22,9 @@
 #include "includes.h"
 
 /*******************************************************************
 #include "includes.h"
 
 /*******************************************************************
- free() a data blob
+ Free() a data blob.
 *******************************************************************/
 *******************************************************************/
+
 static void free_data_blob(DATA_BLOB *d)
 {
        if ((d) && (d->free)) {
 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)
 *******************************************************************/
 
 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;
 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) {
 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) {
 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);
 }
 void data_blob_clear_free(DATA_BLOB *d)
 {
        data_blob_clear(d);
        data_blob_free(d);
 }
-
index f877d540fb456081d228be7033b258d38c6e0a68..f3676070dcb6d8bb2c8e59e3d36540f9100971d5 100644 (file)
@@ -448,19 +448,22 @@ BOOL debug_parse_levels(const char *params_str)
  Receive a "set debug level" message.
 ****************************************************************************/
 
  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",
 {
        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",
                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);
 }
 
        debug_parse_levels(params_str);
 }
@@ -473,7 +476,8 @@ void debug_message_send(pid_t pid, const char *params_str)
 {
        if (!params_str)
                return;
 {
        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);
 }
 
                         False);
 }
 
@@ -481,11 +485,13 @@ void debug_message_send(pid_t pid, const char *params_str)
  Return current debug level.
 ****************************************************************************/
 
  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();
 
 {
        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);
        message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
 
        SAFE_FREE(message);
index a83ed518d7cf50f3f2bc1443f4237588ee1766d3..1b2308ecba65307ea22f4f75aeb723c7b604b56d 100644 (file)
@@ -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.
  **/
  * 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
                          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),
 
 
 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
                                        void *UNUSED(buf), size_t UNUSED(len))
 {
 #ifdef ENABLE_DMALLOC
index f2e267c9d4497d576881215d4b010f2879f4c100..85599c92d33725ed35c75a3809a2686006a93548 100644 (file)
@@ -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;
                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);
 
                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, "
                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;
        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);
 
        /* 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);
                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)));
                
                DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
                           keystr, valstr, ctime(&timeout)));
index 9ccddfa4c53776dca2c3c52716bd6917de226d0c..f37bbc9c2fd3b310e7971246d80aa2e5801af7c6 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "includes.h"
 
 
 #include "includes.h"
 
-static unsigned char hash[258];
+static unsigned char smb_arc4_state[258];
 static uint32 counter;
 
 static BOOL done_reseed = False;
 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.
 /****************************************************************
  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_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;
 }
 
        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;
 
        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;
                mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
                memcpy(p, tmp_buf, copy_len);
                p += copy_len;
index 7d3addd86a4d401c685552dea2fa285451bf1fcc..058bbc99b0bcce105609c18af40a633096a95ad0 100644 (file)
@@ -57,8 +57,8 @@ static int received_signal;
 struct message_rec {
        int msg_version;
        int msg_type;
 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;
 };
 
        size_t len;
 };
 
@@ -66,7 +66,7 @@ struct message_rec {
 static struct dispatch_fns {
        struct dispatch_fns *next, *prev;
        int msg_type;
 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;
 
 /****************************************************************************
 } *dispatch_fns;
 
 /****************************************************************************
@@ -83,10 +83,12 @@ static void sig_usr1(void)
  A useful function for testing the message system.
 ****************************************************************************/
 
  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";
 {
        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);
 }
 
        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.
 ******************************************************************/
 
  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;
 
 {
        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;
        
        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.
 ****************************************************************************/
 
  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.
        /*
         * 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));
        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)));
                }
                } 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.
 ****************************************************************************/
 
  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;
 {
        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.
         */
 
         * 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.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);
        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.
 ****************************************************************************/
 
  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);
 }
 {
        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.
 ****************************************************************************/
 
  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);
                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....
 ****************************************************************************/
 
  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;
 {
        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;
 
        *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;
 
        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.
 ****************************************************************************/
 
  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;
 {
        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;
 void message_dispatch(void)
 {
        int msg_type;
-       pid_t src;
+       struct process_id src;
        char *buf;
        char *msgs_buf;
        size_t len, total_len;
        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) {
                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) {
                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 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;
 
 {
        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) {
                /* 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);
                }
        }
                        tdb_delete(the_tdb, kbuf);
                }
        }
index 49121d12ca177d8617ad221be419200bc70972c3..885faf8d80e17afe2083a604eeb6af5087ff1024 100644 (file)
@@ -231,77 +231,3 @@ void smb_run_idle_events(time_t now)
 
        return;
 }
 
        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;
-}
index 20a8e82ce23e48df499a72e329dfdae365010ddb..b041eb7f1b2d5b1e2b300a0cff3b01c3661eb0c5 100644 (file)
@@ -57,7 +57,7 @@ pid_t pidfile_pid(const char *name)
                goto noproc;
        }
        
                goto noproc;
        }
        
-       if (!process_exists((pid_t)ret)) {
+       if (!process_exists_by_pid(ret)) {
                goto noproc;
        }
 
                goto noproc;
        }
 
index d95c1ba4c132b12e021b50ad8b62b7747a730423..ff0631b82f184c75cf42bcbb7ce8317698d91ccd 100644 (file)
@@ -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
 
 /*********************************************************************
  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 )
 *********************************************************************/
 
 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;
 
        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++ ) {
        
        
        for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
        
index cf7c8fc87f273f9aafe4b681ebbbca101357a0b6..f08a67a22c891f5cbc7c807458818ec1c5405734 100644 (file)
@@ -267,7 +267,11 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
                return; 
 
        while ( list[i] ) {
                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;
        }
 
                i+=1;
        }
 
index 798cb3fff74c17ca9a711b1a9bcc7dee3fbd6ae3..4679b864874a01115d5eb92f257691c5afd9bdc6 100644 (file)
 #include "includes.h"
 #include "smbldap.h"
 
 #include "includes.h"
 #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.
 /**********************************************************************
  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;
                }
                        
                        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);
                
        } 
                return smbldap_search_domain_info(ldap_state, result, domain_name, False);
                
        } 
index 13e330dd97a9d59c81096d979a8dfa8eb50464f0..6d6d7817f1abbc13b01c25724cb51f3ee7e19f0a 100644 (file)
@@ -225,10 +225,16 @@ int smbrunsecret(const char *cmd, const char *secret)
                 */
                int status = 0;
                pid_t wpid;
                 */
                int status = 0;
                pid_t wpid;
+               size_t towrite;
+               ssize_t wrote;
                
                close(ifd[0]);
                /* send the secret */
                
                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]);
 
                fsync(ifd[1]);
                close(ifd[1]);
 
index 8ee3c257f6b642723a795de60e36076aac946fd4..8f03fd66ff1888749bccb9cd26598a1d8660cb83 100644 (file)
@@ -30,7 +30,7 @@
  * Respond to a POOL_USAGE message by sending back string form of memory
  * usage stats.
  **/
  * 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;
                    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);
        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);
        
        message_send_pid(src_pid, MSG_POOL_USAGE,
                         reply_str, strlen(reply_str)+1, True);
index 5e0f5646fca9eb3385f4bc6e9adc93ed67821b1e..385762e82c2e2fe4d04ccb702f5b13327d90244c 100644 (file)
@@ -782,6 +782,15 @@ BOOL nt_time_is_zero(NTTIME *nt)
        return False;
 }
 
        return False;
 }
 
+/****************************************************************************
+ 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.
 ****************************************************************************/
 /****************************************************************************
  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 (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
 
 /****************************************************************************
  convert ASN.1 GeneralizedTime string to unix-time
index 39938921968dc82dd74c49a53a3c154449f23b56..a5cfe95b660fd931b168bdee55db0a82862aa03e 100644 (file)
@@ -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?
 ****************************************************************************/
 
  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. */
        /* 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;
 }
 
        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;
+}
index 2cc6c6ebae46c0325dbf553b538b88932a154064..2e7866c0559f314b91993e3279f34773727f49c7 100644 (file)
@@ -2,6 +2,11 @@
    Unix SMB/CIFS implementation.
    kerberos authorization data (PAC) utility library
    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003   
    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
    
    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
 
 #ifdef HAVE_KRB5
 
 
 #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)
 {
 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)
 {
 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;
 
 }
        return True;
 
 }
+#endif
 
 static BOOL pac_io_group_membership(const char *desc, 
                                    GROUP_MEMBERSHIP *membership,
 
 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)
 {
 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 (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;
                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;
                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;
                return False;
+
        if (!prs_uint32("pointer", ps, depth, &garbage))
                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))
        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("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;
                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("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", 
                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("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;
 
                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;
 
                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;
 
        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;
 
                                     &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;
                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;
 }
 
 
 
        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);
 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++;
        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 (!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;
                }
        }
                        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 False;
 
+
        return True;
 }
 
        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)
                                    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)) {
                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);
        }
 
                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);
        }
 
                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;
 }
 
        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)
                                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) {
                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++) {
                        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++) {
                                         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;
        }
                                             ps, depth))
                        return False;
        }
@@ -583,25 +628,300 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
        return True;
 }
 
        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;
        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);
 
 
        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
 }
 
 #endif
index 770d129e5dafd62278e0fde88687a55aceac31b1..6a5c6b6a491ce1e82677866664f521defca13fa7 100644 (file)
@@ -4,8 +4,9 @@
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Remus Koos 2001
    Copyright (C) Luke Howard 2003   
    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) 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
    
    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,
 ***********************************************************************************/
 
 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;
 {
        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;
                                        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) {
                                        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 {
                                                        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;
                                                        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,
 ***********************************************************************************/
 
 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;
 {
        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;
 
        krb5_enctype *enctypes = NULL;
        int i;
 
+       ZERO_STRUCTP(keyblock);
+
        if (!secrets_init()) {
                DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n"));
                return False;
        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_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;
                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)));
                        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:
        }
 
  out:
@@ -251,27 +265,33 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
  authorization_data if available.
 ***********************************************************************************/
 
  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 *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_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;
        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;
        char *host_princ_s = NULL;
        BOOL got_replay_mutex = False;
 
        BOOL auth_ok = False;
+       BOOL got_auth_data = False;
 
        ZERO_STRUCT(packet);
 
        ZERO_STRUCT(packet);
-       ZERO_STRUCTP(auth_data);
+       ZERO_STRUCT(auth_data);
        ZERO_STRUCTP(ap_rep);
        ZERO_STRUCTP(session_key);
 
        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()) {
        }
 
        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,
        }
        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;
 
        }
 
        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;
        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);
        }
 
        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
 
        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 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);
        }
        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),
 #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)) {
        }
 
        if (!NT_STATUS_IS_OK(sret)) {
-               data_blob_free(auth_data);
+               data_blob_free(&auth_data);
        }
 
        if (!NT_STATUS_IS_OK(sret)) {
        }
 
        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);
        }
 
                krb5_free_principal(context, host_princ);
        }
 
+       if (keyblock) {
+               krb5_free_keyblock(context, keyblock);
+       }
+
        if (tkt != NULL) {
                krb5_free_ticket(context, tkt);
        }
        if (tkt != NULL) {
                krb5_free_ticket(context, tkt);
        }
index 81afd7f49e3037ba235cef10fad9ef57a5b5dd2e..bf402b3499e27dafc3d74948579eb141e1bf5b07 100644 (file)
@@ -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",
        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;
                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,
                *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"));
                
                if (!*next_attribute) {
                        DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
index db544fe2092589b34f840b0e9e10e6472128a768..d6ac09d22bda5db4404917d44f3ddc64eafb3291 100644 (file)
@@ -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)
                                          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;
 
        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;
        }
        
        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, 
                                             "", 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)));
        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;
 
        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",
 
        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;
 
        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",
 
        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 );
 
        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;
 }
 
        return result;
 }
index 8fa62a5ade4e07d6ce0e18f36f4d9632df7c65e7..72cbf7264ec964bd22d74c06f546464ee2a29572 100644 (file)
@@ -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;
 
        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);
 
        if (rc) {
                return ADS_ERROR_KRB5(rc);
index 3d8e36c493a7911f3339e1f105a8078a92addab5..7ecc7695171e8c9b14773ed2e047b1863f203775 100644 (file)
@@ -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 */
        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)));
 
        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);
                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);
                        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;
 }
 
        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
 /**
    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) 
 {
                             int signing_state,
                             BOOL *retry) 
 {
-       struct ntuser_creds creds;
        NTSTATUS nt_status;
        struct cli_state *cli = NULL;
 
        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;
 
        *output_cli = cli;
        return NT_STATUS_OK;
index 819616105edc9d274a76fd26bf0f4fb76d8a6ef9..dfb613238f60facfd6799e9b1732aae89536008a 100644 (file)
@@ -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)));
 
        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);
 }
 
                                False);
 }
 
index f1794ab5dc8d041f8b2efc9d096a04eb2307927f..bc64cc919b7705aa59f6aedbefdaf1b28a6f5ab1 100644 (file)
@@ -221,15 +221,16 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
  Initialise credentials of a client structure.
 ****************************************************************************/
 
  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;
 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()) {
 
        /* 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);
 
        /* 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->initialised = 1;
        cli->allocated = alloced_cli;
 
-       cli->pipe_idx = -1;
-
        return cli;
 
         /* Clean up after malloc() error */
        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)
 {
 
 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
 
        /*
         * 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.
         */
         * 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);
                cli_tdis(cli);
+       }
         
        SAFE_FREE(cli->outbuf);
        SAFE_FREE(cli->inbuf);
         
        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);
 
        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->mem_ctx) {
                talloc_destroy(cli->mem_ctx);
                cli->mem_ctx = NULL;
        }
 
-       if (cli->fd != -1) 
+       if (cli->fd != -1) {
                close(cli->fd);
                close(cli->fd);
+       }
        cli->fd = -1;
        cli->smb_rw_error = 0;
        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);
        BOOL allocated = cli->allocated;
        cli_close_connection(cli);
        ZERO_STRUCTP(cli);
-       if (allocated)
+       if (allocated) {
                free(cli);
                free(cli);
+       }
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
index 355a2adf34d998cd86689ace555073fcd3dabc37..6938702e1e04f3c32a06ae7e3c1544da117e4cd5 100644 (file)
@@ -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 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;
+       }
+}
index 1741c1db3cdb703317de003f69ce2c2ec93ade07..e3ad5f17cb0b78018d3a3724a8e275a903c238d7 100644 (file)
@@ -3,6 +3,8 @@
    simple kerberos5 routines for active directory
    Copyright (C) Andrew Tridgell 2001
    Copyright (C) Luke Howard 2002-2003
    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
    
    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
 }
 #endif
 
 }
 #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 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
 #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
 #endif
+       return False;
 }
 
  krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt)
 }
 
  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, 
   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;
 {
        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, 
 
        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;
                                        principal,
                                        ccdef, &packet))) {
                goto failed;
@@ -550,10 +642,349 @@ failed:
 #endif
 }
 
 #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, 
 #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;
 {
         DEBUG(0,("NO KERBEROS SUPPORT\n"));
         return 1;
index 1220907629c368af5b41d31d4f2c0512020c6deb..55e36b646b9a67d5b1bd7a4a8184c9747516f541 100644 (file)
@@ -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
 ****************************************************************************/
 
               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 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;
        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)) {
        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,
 
                        if (!cli_issue_write(cli, fnum, offset + bsent,
                                        write_mode,
index 85b7bd9e1eec1f3cee0d87cf33bcbd2d43c01d71..33fc265f79847dda077707a9ed00a65b02b7789f 100644 (file)
@@ -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, 
 */
 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 */
 {
        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;
 
        if (retval)
                return retval;
index c6b1d465ffed05ea8b15e209f6cf3efb968245e7..5d3710b92e260f055c87e66e95ae9546d37b3134 100644 (file)
@@ -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,
 
 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_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);
                }
                        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_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);
                        }
                }
                                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);
                /* 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);
index 0d521bae8ac42c7421f6db043bee74a48c0e3217..3f2dcd850b33b887270d507146445abb3ae7bc26 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    code to manipulate domain credentials
    Copyright (C) Andrew Tridgell 1997-1998
    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
    
    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"
 
 /****************************************************************************
 #include "includes.h"
 
 /****************************************************************************
-represent a credential as a string
+ Represent a credential as a string.
 ****************************************************************************/
 ****************************************************************************/
+
 char *credstr(const uchar *cred)
 {
        static fstring buf;
 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
        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];
 
 {
        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]);
 
 
        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 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,("      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;
        }
                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;
 }
        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;
+}
index 8462fbee877d7cd7fe8f431b9f8fb976a44c6604..3c0b13ad6ff565d8fd9654d00f5f6c3698ae2a66 100644 (file)
@@ -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,        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},
        {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,        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},
        {ERRHRD,        ERRgeneral,     NT_STATUS_BAD_LOGON_SESSION_STATE},
        {ERRHRD,        ERRgeneral,     NT_STATUS_LOGON_SESSION_COLLISION},
        {ERRDOS,        206,    NT_STATUS_NAME_TOO_LONG},
index f9461f936834cce8d49f4b493e80f70f60ba9e7e..5699e153bbd2c59ba092e4cfaa687a169062b5f5 100644 (file)
@@ -420,7 +420,7 @@ int smbc_open_print_job(const char *fname)
 {
        SMBCFILE * file = statcont->open_print_job(statcont, fname);
        if (!file) return -1;
 {
        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)
 }
 
 int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn)
index fe8f878aa57c0cd0eb26293be3658aa2f9026bfb..1e729abb2218f4fd41b2e26cd981eeb60c2a17be 100644 (file)
@@ -80,6 +80,23 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
        return False;
 }
 
        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);
 
 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 in_addr ip;
        struct cli_state *ipc_cli;
+       struct rpc_pipe_client *pipe_hnd;
         NTSTATUS nt_status;
        SMBCSRV *ipc_srv=NULL;
 
         NTSTATUS nt_status;
        SMBCSRV *ipc_srv=NULL;
 
@@ -835,29 +853,27 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
                         return NULL;
                 }
 
                         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);
                 }
 
                 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)) 
                {
                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)) 
                    {
                        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
         */
        /*
         * 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;
 
 }
        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;
        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);
 
        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 */
 
        /* 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]) {
                                                 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;
        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) {
 
         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;
         }
 
                 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;
                                                  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 ... */
 
 
         /* 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 */
                 
                 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 */
 
 
         /* 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);
 
                 saverr = errno;  /* Save errno */
                 c_file->close_fn(c_file, fid1);
index b02c2384a8de62817a70390dc34c592481324512..6b551e8774c4bd7df761cfea90810f9b1517548f 100644 (file)
@@ -5,6 +5,7 @@
 
    Copyright (C) Andrew Tridgell      2001
    Copyright (C) Andrew Bartlett 2001-2003
 
    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
 
    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;
 
        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) {
        *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_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)) {
        }
 
        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
 
 /**
  * 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;
                }
                
                        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);
                
                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;
        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;
 
        /* 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;
                        }
                                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", 
                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", 
                        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);
                        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;
        }
 
                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) {
        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);
        
 
        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;
 }
 
        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_NTLM |
                NTLMSSP_NEGOTIATE_NTLM2 |
                NTLMSSP_NEGOTIATE_KEY_EXCH |
-               NTLMSSP_NEGOTIATE_SIGN;
+               NTLMSSP_NEGOTIATE_SIGN |
+               NTLMSSP_NEGOTIATE_SEAL;
 
        return NT_STATUS_OK;
 }
 
        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);
        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",
 
        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 {
                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);
                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()) {
                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);
                        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);
 
 
        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->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)));
 
        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)
 }
 
 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
@@ -1103,4 +1156,3 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
 
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
-
index 4b3043aec8076ddf8a63d5cf8e4ecc228d87e9d1..e71504867e956cf32a8c3b4841f767b10b8ffbf6 100644 (file)
@@ -216,7 +216,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
                                        /* if odd length and unicode */
                                        return False;
                                }
                                        /* 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) {
                                        return False;
 
                                if (0 < len1) {
@@ -244,7 +244,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
                                        return False;
                                }
 
                                        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) {
                                        return False;   
 
                                if (0 < len1) {
@@ -272,7 +272,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
                                        return False;
                                }
 
                                        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);
                                        return False;   
                        
                                *b = data_blob(blob->data + ptr, len1);
index b8105970762f4ce2617f3189879c48fa638204aa..51023ca35652562365a73d1daceb19bb5d1b6024 100644 (file)
@@ -2,8 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  Version 3.0
  *  NTLMSSP Signing routines
  *  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
  *  
  *  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
 #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"
 
 #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;
 {
        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);
        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 {
 }
 
 enum ntlmssp_direction {
@@ -103,64 +53,107 @@ enum ntlmssp_direction {
 };
 
 static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
 };
 
 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];
 {
        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;
                }
 
                        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:
                        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:
                                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;
                        }
                }
                                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);
        } 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;
                }
                
                        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, 
        }
        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;
                                    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;
        }
 
        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;
 }
 
        return nt_status;
 }
 
@@ -171,8 +164,9 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
  */
 
 NTSTATUS ntlmssp_check_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;
 {
        DATA_BLOB local_sig;
        NTSTATUS nt_status;
@@ -187,32 +181,51 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
                          (unsigned long)sig->length));
        }
 
                          (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)));
        
        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;
        }
        
                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;
 }
 
        return NT_STATUS_OK;
 }
 
-
 /**
  * Seal data with the NTLMSSP algorithm
  *
 /**
  * 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,
 
 NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
                             uchar *data, size_t length,
+                            uchar *whole_pdu, size_t pdu_length,
                             DATA_BLOB *sig)
 {      
                             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;
        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) {
        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);
        } 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,
                        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 */
                
                   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);
 
        dump_data_pw("ntlmssp sealed data\n", data, length);
 
-       /* increment counter on send */
-       ntlmssp_state->ntlmssp_seq_num++;
-
        return NT_STATUS_OK;
 }
 
        return NT_STATUS_OK;
 }
 
@@ -286,26 +298,27 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
  */
 
 NTSTATUS ntlmssp_unseal_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;
        }
 
 {
        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);
        dump_data_pw("ntlmssp sealed data\n", data, length);
+
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
        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 {
        } 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)
        {
 
        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;
                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;
                }
 
                        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 {
        } 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;
 }
 
        return NT_STATUS_OK;
 }
index 8bce9c86a1e336460e62b414d6d9876e10f834b6..b104a4678d9a4fa6530625cf673684b64cc7fb94 100644 (file)
 #include "includes.h"
 
 /*************************************************************
 #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;
 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 in_addr ip;
-       struct ntuser_creds creds;
 
        NTSTATUS result;
 
 
        NTSTATUS result;
 
@@ -85,11 +86,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
                        return False;
                }
 
                        return False;
                }
 
-               init_creds(&creds, "", "", NULL);
-               cli_init_creds(&cli, &creds);
+               cli_init_creds(&cli, "", "", NULL);
        } else {
        } 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)) {
        }
 
        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;
        }
 
                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()) {
                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) );
                        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 {
                                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;
                }
        }
 
                        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);
                                                             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... */
        }
 
        /* OK, that failed, so try again... */
-       cli_nt_session_close(&cli);
+       cli_rpc_pipe_close(pipe_hnd);
        
        /* Try anonymous NTLMSSP... */
        
        /* 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;
        
        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;
                /* 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))) {
        } 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()) {
                   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! */
 
                        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 {
                        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;
                }
                        cli_shutdown(&cli);
                        return False;
                }
index e010f226a02032e79859d2b09ebb1b374b0f2420..a0f3383e2970c38fc1c7200675508331df7db6ad 100644 (file)
@@ -60,4 +60,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
                clr[0] = 0;
 
 }
                clr[0] = 0;
 
 }
-
index 87a386307c1c245639bab6d38c2e2d477723cac4..7659d1cd6e8e492cc434d931842ef47a62dedaa3 100644 (file)
@@ -55,6 +55,12 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
        return smb_db;
 }
 
        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);
 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;
                        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
        } 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[];
        */
 };
           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.
  */
 
  * 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 &&
                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.
  */
 
  * 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;
 
        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. */
        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;
 
        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));
 
 
        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++) {
 
        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];
                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. */
 
                /* 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. */
                }
 
                        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;
                /* 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. */
        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. */
        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;
                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);
                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);
 
                        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;
                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. */
        }
 
        /* 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;
        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. */
        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 */
 
        /* 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);
 
 
        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 */
        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);
 
 
        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. */
        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;
        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;
 
        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... */
 
        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. */
        }
 
        /* 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. */
        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++) {
 
        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. */
 
                /* 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. */
                }
 
                        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. */
                }
 
                        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++;
        }
 
                num_share_modes++;
        }
@@ -383,10 +394,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
        }
 
        /* Copy the terminating filename. */
        }
 
        /* 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);
 
        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);
 
                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;
 
        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);
 
        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. */
        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;
 
        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;
 
        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++) {
 
        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. */
 
                /* 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. */
                }
 
                        continue; /* No longer exists. */
                }
 
index b7f0cd05c3308de80e554f23aaef0b3bc3ea79d9..dc49396d9e158ca9bf802d0fd52202b11aaf9407 100644 (file)
@@ -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);
 }
 
         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
 }
 
 /* Decode a sam password hash into a password.  The password hash is the
index 8361c35a8e2bfb3b7392ab8631c0b79a103e2f54..0c9eacfe4c0eb1e4878a0de6478b399c6ac2fc23 100644 (file)
@@ -308,32 +308,6 @@ void SMBsesskeygen_ntv1(const uchar kr[16],
 #endif
 }
 
 #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])
 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.
 ************************************************************/
  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;
 {
        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);
 
        
        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
 
        /* 
         * The length of the new password is in the last 4 bytes of
index a21063e52ac3371974d212cc4245ee61e73a636a..82a06bde2bcfbb2a3ab665bf684eb56b6b85b93b 100644 (file)
@@ -75,6 +75,7 @@ err_code_struct dos_msgs[] = {
   {"ERRlogonfailure",ERRlogonfailure,"Logon failure"},
   {"ERRdiskfull",ERRdiskfull,"Disk full"},
   {"ERRgeneral",ERRgeneral, "General failure"},
   {"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}};
 
   {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"},
   {NULL,-1,NULL}};
 
index 2eaec61ed792e3e7bed655b472a8db8fa869e1f7..2cf3480fce3a2156f2466e616bd87637636f6c85 100644 (file)
@@ -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));
 
                        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 = 
                        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;
                                asn1_read_OID(asn1, &token->mechTypes[i]);
                        }
                        token->mechTypes[i] = NULL;
index aab0d7d151745887958fee39912b9169cfadb848..50fa613e72cd50839b5e46b65fcb55c478664ab2 100644 (file)
  Caller must have the cli connected to the netlogon pipe
  already.
 **********************************************************/
  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;
 
                                         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",
 
        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
 **********************************************************/
 
  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)
                                      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
 **********************************************************/
 
  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) 
 {
                                           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);
        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 in_addr  dc_ip;
        uint32          enum_ctx = 0;
        struct cli_state *cli = NULL;
+       struct rpc_pipe_client *lsa_pipe;
        BOOL            retry;
 
        *domain_names = NULL;
        BOOL            retry;
 
        *domain_names = NULL;
@@ -156,21 +170,21 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
 
        /* open the LSARPC_PIPE */
 
 
        /* 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 */
 
                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 */
 
                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;
                num_domains, domain_names, sids);
        if ( !NT_STATUS_IS_OK(result) )
                goto done;
@@ -184,4 +198,3 @@ done:
 
        return NT_STATUS_IS_OK(result);
 }
 
        return NT_STATUS_IS_OK(result);
 }
-
index da7fc1e67d455a457a64dffb2c0ab84206164b8a..25a1ed5e2f6cad1fcc18e763a86358135fdf1fff 100644 (file)
@@ -39,7 +39,7 @@
 struct lock_context {
        uint16 smbpid;
        uint16 tid;
 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
 };
 
 /* 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)
 {
 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->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 ));
 
                        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;
 
                        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,
 ****************************************************************************/
 
 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)
 {
                  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,
 ****************************************************************************/
 
 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 *),
                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)) {
 
                                        /* 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,
 
                                                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,
 ****************************************************************************/
 
 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)
 {
                  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.
 ****************************************************************************/
 
  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;
 {
        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 &&
                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. */
                    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 &&
                                        continue;
 
                                if (pend_lock->context.tid == tid &&
-                                   pend_lock->context.pid == pid &&
+                                   procid_equal(&pend_lock->context.pid, &pid) &&
                                    pend_lock->fnum == fnum)
                                        continue;
 
                                    pend_lock->fnum == fnum)
                                        continue;
 
index 5bcf7f2eda8ec480a6868259ba68f9781a63e142..e3131e26a2a4da688a5aabeae9a8655fe7e767aa 100644 (file)
@@ -43,7 +43,6 @@ uint16 global_smbpid;
 
 /* the locking database handle */
 static TDB_CONTEXT *tdb;
 
 /* the locking database handle */
 static TDB_CONTEXT *tdb;
-static TDB_CONTEXT *deferred_open_tdb;
 
 struct locking_data {
         union {
 
 struct locking_data {
         union {
@@ -51,10 +50,10 @@ struct locking_data {
                        int num_share_mode_entries;
                        BOOL delete_on_close;
                } s;
                        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
         } 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[];
         */
 };
            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;
                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,
                        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,
                                     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);
        }
 
                                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,
 
        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);
 
                                  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 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);
                        }
                                                                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,
        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) {
                        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)
 {
 
 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;
 
        if (!lp_locking(SNUM(fsp->conn)))
                return;
@@ -324,20 +324,6 @@ BOOL locking_init(int read_only)
                return False;
        }
 
                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;
 
        if (!posix_locking_init(read_only))
                return False;
 
@@ -360,11 +346,6 @@ BOOL locking_end(void)
                        ret = False;
        }
 
                        ret = False;
        }
 
-       if (deferred_open_tdb) {
-               if (tdb_close(deferred_open_tdb) != 0)
-                       ret = False;
-       }
-               
        return ret;
 }
 
        return ret;
 }
 
@@ -372,6 +353,16 @@ BOOL locking_end(void)
  Form a static locking key for a dev/inode pair.
 ******************************************************************/
 
  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;
 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;
 
        memset(&key, '\0', sizeof(key));
        key.dev = dev;
-       key.inode = inode;
+       key.ino = inode;
        kbuf.dptr = (char *)&key;
        kbuf.dsize = sizeof(key);
        return kbuf;
 }
 
        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.
 ********************************************************************/
 
 /*******************************************************************
  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]: "
 {
        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",
                 "dev = 0x%x, inode = %.0f",
-                num, (unsigned long)e->pid,
+                num, procid_str_static(&e->pid),
                 e->share_access, e->private_options,
                 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;
                 (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;
 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++) {
        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.
 ********************************************************************/
 
  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;
        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;
        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;
        }
                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, 
 
 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, 
-                       voidstate)
+                       void *state)
 {
        struct locking_data *data;
 {
        struct locking_data *data;
-       share_mode_entry *shares;
+       struct share_mode_entry *shares;
        char *name;
        int i;
        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;
 
        /* 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);
 
        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.
 ********************************************************************/
 
  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 0;
-       return tdb_traverse(tdb, traverse_fn, (void*)fn);
+       return tdb_traverse(tdb, traverse_fn, fn);
 }
 }
index 3c59fd9d61f18b35115df84d0cb64b468524fd05..ccee9d71eddd94068d504163cdc9c1cc6368bb9a 100644 (file)
@@ -23,7 +23,7 @@
 
 static struct {
        char from;
 
 static struct {
        char from;
-       char *to;
+       const char *to;
        int len;
 } weird_table[] = {
        {'q', "^q^", 3},
        int len;
 } weird_table[] = {
        {'q', "^q^", 3},
index 653cb97fbb0678481f3b1cc8d70d0b20d7824145..4db54ea198cee9f05a95c8589bc6bda1a88bf919 100644 (file)
@@ -201,7 +201,7 @@ void run_dns_queue(void)
         /* Allow SIGTERM to kill us. */
         BlockSignals(False, SIGTERM);
 
         /* 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();
        }
                close(fd_in);
                start_async_dns();
        }
index bc58dd3a2814c0f6475fc4a3b72a6bd257db7b04..fcaba03b3dbaad5ce42eb4c53e45018c27dab2a9 100644 (file)
@@ -76,7 +76,8 @@ static void terminate(void)
  Handle a SHUTDOWN message from smbcontrol.
  **************************************************************************** */
 
  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();
 }
 {
        terminate();
 }
@@ -307,7 +308,8 @@ static BOOL reload_nmbd_services(BOOL test)
  * detects that there are no subnets.
  **************************************************************************** */
 
  * 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();
 {
        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;
 
                                 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)) {
 
        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",
                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) {
                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;
        }
 
                return;
        }
 
@@ -590,7 +594,8 @@ static void process(void)
 
                if(reload_after_sighup) {
                        DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
 
                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;
                        if(no_subnets)
                                return;
                        reload_after_sighup = 0;
index 470cf4277b52b4b2c1c4b23fae067394fd3d273e..6e8e8429becba31f767a2e32e231714ed86d78c4 100644 (file)
@@ -374,7 +374,8 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
  Process a internal Samba message forcing an election.
 ***************************************************************************/
 
  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;
 
 {
        struct subnet_record *subrec;
 
index 4baf2d3d6cecab6c108c4f48cf9de5c8c456d052..c25473c4fba17ade781b095ec42c5a92f0fb8db1 100644 (file)
@@ -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,
 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;
                        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,
 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;
                        nmb_namestr(&dgram->dest_name),
                        inet_ntoa(p->ip) ));
                return;
index 33690133bf88de614e6aa94eb17da3f805d0d970..28ad92ed108022ac277e51cd7d7c175c349f868b 100644 (file)
@@ -294,7 +294,7 @@ void sync_check_completion(void)
 
        for (s=syncs;s;s=next) {
                next = s->next;
 
        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);
                        /* it has completed - grab the info */
                        complete_sync(s);
                        DLIST_REMOVE(syncs, s);
index 86f5b9c4261de1cd57b2ee206efd1003c1310596..d76cb8f03226c30db9412c8feb95c915678fa418 100644 (file)
@@ -1874,7 +1874,8 @@ void wins_write_database(BOOL background)
  Process a internal Samba message receiving a wins record.
 ***************************************************************************/
 
  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;
 {
        WINS_RECORD *record;
        struct name_record *namerec = NULL;
index 6d09666525f7f2f142fbd189078ac57c2ff1a8e1..5521614965af548ceb8f5f6adb40f6ec581ea62e 100644 (file)
@@ -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 (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;
 }
        
        return NSS_STATUS_SUCCESS;
 }
index 34b2d6c9299f2d0fc707228a1812ee8ffa3552d9..60f1d6b7221d21f1722938a9554bd313c1c7b75a 100644 (file)
@@ -192,7 +192,6 @@ static BOOL wbinfo_get_userdomgroups(const char *user_sid)
        return True;
 }
 
        return True;
 }
 
-
 /* Convert NetBIOS name to IP */
 
 static BOOL wbinfo_wins_byname(char *name)
 /* Convert NetBIOS name to IP */
 
 static BOOL wbinfo_wins_byname(char *name)
index dffaad5ef00a173c200ec01702222d11fca7c720..565764fa4be23db39fe62996d561a61cfe93aaa7 100644 (file)
@@ -204,7 +204,7 @@ static void sigchld_handler(int signum)
 }
 
 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
 }
 
 /* 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();
 {
         /* 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*/
 }
 
 /* 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();
 }
 {
        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_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);
 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;
        }
 
                return;
        }
 
+       SAFE_FREE(state->request.extra_data);
        SAFE_FREE(state->response.extra_data);
 
        setup_async_read(&state->fd_event, &state->request, sizeof(uint32),
        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);
 }
 
                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);
 {
        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;
        }
 
                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);
 {
        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;
        }
 
                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;
        }
 
                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 */
 }
 
 /* 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"));
 
 
                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;
        }
 
                do_sighup = False;
        }
 
index 3a7728e4a2c82fb3fff2f037ddb99d13820aed71..0db109dacde06497926ff41d7009dc1e2958eeff 100644 (file)
@@ -47,6 +47,14 @@ struct fd_event {
        void *private_data;
 };
 
        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 */
 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;
 
        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;
 };
 
        struct rpc_pipe_client *netlogon_pipe;
 };
 
@@ -305,8 +307,6 @@ struct winbindd_idmap_methods {
 
 #include "nsswitch/winbindd_proto.h"
 
 
 #include "nsswitch/winbindd_proto.h"
 
-#include "rpc_parse.h"
-
 #define WINBINDD_ESTABLISH_LOOP 30
 #define WINBINDD_RESCAN_FREQ 300
 
 #define WINBINDD_ESTABLISH_LOOP 30
 #define WINBINDD_RESCAN_FREQ 300
 
index eda6dea2c48262bddbc3fd02bf95fd1884612ad2..dfabccd419443772e6ac4c4451c9b300a53188a9 100644 (file)
@@ -830,13 +830,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        *names       = NULL;
        *dom_sids    = NULL;
 
        *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 "
 
        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;
        }
        
                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);
                result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
                                                      cli->cli->desthost, 
                                                      flags, &domains,
                                                      (unsigned int *)&count);
+       }
        
        if ( NT_STATUS_IS_OK(result) && count) {
        
        
        if ( NT_STATUS_IS_OK(result) && count) {
        
index acae7e7f37144c188979fb0242d5dd3e7dff2037..d43671380d00dce4a6805ccc10cc71e1cce08b8b 100644 (file)
@@ -84,12 +84,12 @@ static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
                      &state->response, do_async_recv, state);
 }
 
                      &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;
 
 {
        struct do_async_state *state;
 
@@ -706,16 +706,16 @@ enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
        return WINBINDD_OK;
 }
 
        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;
 {
        int i;
        size_t buflen = 0;
-       ssize_t len = 0;
 
 
+       *len = 0;
        *result = NULL;
        for (i=0; i<num_sids; i++) {
        *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]));
        }
 
                               "%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;
 }
 
        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)
 {
        char *p, *q;
 
        p = sidstr;
        if (p == NULL)
-               return True;
+               return False;
 
        while (p[0] != '\0') {
                DOM_SID sid;
 
        while (p[0] != '\0') {
                DOM_SID sid;
@@ -754,6 +754,49 @@ static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr,
        return True;
 }
 
        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)
 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;
 {
        struct winbindd_request request;
        char *sidstr = NULL;
-       char *keystr;
+       ssize_t len;
 
        if (num_sids == 0) {
                cont(private_data, True, NULL, 0);
                return;
        }
 
 
        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;
                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);
 
        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;
 {
        DOM_SID *sids = NULL;
        int num_sids = 0;
-       char *key = state->request.data.dual_sidaliases.cache_key;
        char *sidstr;
        char *sidstr;
+       size_t len;
        int i, num_aliases;
        uint32 *alias_rids;
        NTSTATUS result;
 
        DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid));
 
        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 */
 
        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,
        }
 
        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;
        }
                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));
        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;
        }
        
        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);
 }
        do_async_domain(mem_ctx, domain, &request, query_user_recv,
                        cont, private_data);
 }
+
index ce291a6c25330bc1ebf1e888e1cae50d24c592db..78b49d01eac160f3d1cd9c306c7dddf2b2ed9134 100644 (file)
@@ -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)) {
        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 ));
 
                DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
                         kstr, domain->name ));
 
@@ -1048,7 +1049,6 @@ do_query:
        return status;
 }
 
        return status;
 }
 
-
 /* Lookup user information from a rid */
 static NTSTATUS query_user(struct winbindd_domain *domain, 
                           TALLOC_CTX *mem_ctx, 
 /* 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",
        /* 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),
 
        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",
        /* 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));
 
        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))) {
        }
 
        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;
        }
 
                SAFE_FREE(data.dptr);
                return False;
        }
 
+       dump_data(11, data.dptr, data.dsize);
+
        response->extra_data = data.dptr;
        return True;
 }
 
        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);
 }
 }
index 14221483adc5f075deb140488ea5b1f677b9bb0c..c91f9555682241c5d411740baf6e9920e4536abb 100644 (file)
@@ -73,7 +73,7 @@
    SAMR pipe as well for now.   --jerry
 ******************************************************************/
 
    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
 
 
 /* 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;
                                     fstring dcname, struct in_addr *dc_ip)
 {
        struct winbindd_domain *our_domain;
+       struct rpc_pipe_client *netlogon_pipe;
        NTSTATUS result;
        NTSTATUS result;
-       struct rpc_pipe_client *cli;
        TALLOC_CTX *mem_ctx;
 
        fstring tmp;
        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.... */
 
        /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
         * moment.... */
 
-       if (IS_DC)
+       if (IS_DC) {
                return False;
                return False;
+       }
 
 
-       if (domain->primary)
+       if (domain->primary) {
                return False;
                return False;
+       }
 
        our_domain = find_our_domain();
 
 
        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;
                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;
                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);
                                           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;
 
        /* 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);
 
 
        fstrcpy(dcname, p);
 
-       if (!resolve_name(dcname, dc_ip, 0x20))
+       if (!resolve_name(dcname, dc_ip, 0x20)) {
                return False;
                return False;
+       }
 
        return True;
 }
 
        return True;
 }
@@ -178,7 +179,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
                                      struct cli_state **cli,
                                      BOOL *retry)
 {
                                      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;
        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);
        
        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) {
        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;
        }
                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;
        }
 
                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;
                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,
 
                ads_status = cli_session_setup_spnego(*cli,
-                                                     machine_krb5_principal
+                                                     machine_account
                                                      machine_password, 
                                                      lp_workgroup());
                                                      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);
 
                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;
        /* 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)) {
                                      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;
                        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"));
 
        if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
                DEBUG(5, ("Connected anonymously\n"));
+               cli_init_creds(*cli, "", "", "");
                goto session_setup_done;
        }
 
                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 */
        *retry = False;
 
        /* set the domain if empty; needed for schannel connections */
-       if ( !*(*cli)->domain )
+       if ( !*(*cli)->domain ) {
                fstrcpy( (*cli)->domain, domain->name );
                fstrcpy( (*cli)->domain, domain->name );
-
-       (*cli)->pipe_auth_flags = 0;
+       }
 
        result = NT_STATUS_OK;
        add_failed_connection = False;
 
  done:
 
        result = NT_STATUS_OK;
        add_failed_connection = False;
 
  done:
-       if (got_mutex)
+       if (got_mutex) {
                secrets_named_mutex_release(controller);
                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);
 
        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);
                add_failed_connection_entry(domain->name, controller, result);
+       }
 
        return 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;
        for (retries = 0; retries < 3; retries++) {
 
                int fd = -1;
-               BOOL retry;
+               BOOL retry = False;
 
                result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
 
 
                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) {
 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) {
                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;
        }
 
                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) {
        if (conn->netlogon_pipe != NULL) {
-               cli_rpc_close(conn->netlogon_pipe);
+               cli_rpc_pipe_close(conn->netlogon_pipe);
                conn->netlogon_pipe = NULL;
        }
 
                conn->netlogon_pipe = NULL;
        }
 
-       if (conn->cli)
+       if (conn->cli) {
                cli_shutdown(conn->cli);
                cli_shutdown(conn->cli);
+       }
 
        conn->cli = NULL;
 }
 
        conn->cli = NULL;
 }
@@ -872,7 +910,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
                return;
        }
 
                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 "
 
        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);
        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;
 
        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;
 
            !(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;
 
        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"));
                              domain->name);
        if (!mem_ctx) {
                DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
+               cli_rpc_pipe_close(cli);
                return;
        }
 
                return;
        }
 
@@ -956,7 +995,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
        }
 done:
 
        }
 done:
 
-       cli_rpc_close(cli);
+       cli_rpc_pipe_close(cli);
        
        talloc_destroy(mem_ctx);
 
        
        talloc_destroy(mem_ctx);
 
@@ -965,20 +1004,28 @@ done:
        return;
 }
 
        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 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)
 
 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);
        NTSTATUS result;
 
        result = init_dc_connection(domain);
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                return result;
                return result;
+       }
 
        conn = &domain->conn;
 
        if (conn->samr_pipe == NULL) {
 
        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
 #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 */
 #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;
 
                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);
                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;
                        goto done;
+               }
 
                result = rpccli_samr_open_domain(conn->samr_pipe,
                                                 mem_ctx,
 
                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:
        }
 
  done:
+
        if (!NT_STATUS_IS_OK(result)) {
                invalidate_cm_connection(conn);
        if (!NT_STATUS_IS_OK(result)) {
                invalidate_cm_connection(conn);
-               return NT_STATUS_UNSUCCESSFUL;
+               return result;
        }
 
        *cli = conn->samr_pipe;
        }
 
        *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) {
        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
 #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 */
 #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;
 
                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;
 }
 
        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;
 {
        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;
        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;
        const char *account_name;
-       UTIME zerotime;
+       struct rpc_pipe_client *netlogon_pipe;
 
        result = init_dc_connection(domain);
 
        result = init_dc_connection(domain);
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                return result;
                return result;
+       }
 
        conn = &domain->conn;
 
        if (conn->netlogon_pipe != NULL) {
                *cli = conn->netlogon_pipe;
 
        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;
        }
 
                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;
                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;
                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 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() ) 
        {
                && !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;
                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;
                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) &&
        }
 
        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"));
                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) ||
                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;
                *cli = conn->netlogon_pipe;
-               *session_key = (unsigned char *)&conn->sess_key;
-               *credentials = &conn->clnt_cred;
                return NT_STATUS_OK;
        }
 
                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) {
 
        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;
        }
 
        *cli = conn->netlogon_pipe;
-       *session_key = (unsigned char *)&conn->sess_key;
-       *credentials = &conn->clnt_cred;
-               
        return NT_STATUS_OK;
 }
        return NT_STATUS_OK;
 }
index ec0b7a36e2fb976fb192efa503c49cb763e024e2..60b7411417226b2b65fadc67f90da5e91b35deb9 100644 (file)
 
 /* Read some data from a client connection */
 
 
 /* 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 */
 
        /* 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;
        }
                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;
 };
 
        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);
 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;
 }
 
        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);
 {
        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;
        }
 
                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,
        /* 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),
 
        setup_async_write(&child->event, request->request,
                          sizeof(*request->request),
-                         async_request_sent, request);
+                         async_main_request_sent, request);
        return;
 }
 
        return;
 }
 
@@ -205,31 +243,31 @@ struct domain_request_state {
        struct winbindd_domain *domain;
        struct winbindd_request *request;
        struct winbindd_response *response;
        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 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,
 {
        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"));
                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;
        }
 
                return;
        }
 
@@ -238,15 +276,15 @@ void async_domain_request(TALLOC_CTX *mem_ctx,
        state->request = request;
        state->response = response;
        state->continuation = continuation;
        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);
 }
 
 
        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 =
 {
        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
        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);
 }
 
                             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 =
 {
        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"));
 
        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,
                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 {
 }
 
 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 */
                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);
                }
 
 
                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);
                }
        }
 }
                }
        }
 }
index 6261dfb6165c6df1af0ddf3551bc449fba40a146..c52ee2d960c5d1c1f8e9b72630ce7cfc98a7edad 100644 (file)
@@ -1150,10 +1150,10 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma
        DOM_SID user_sid;
        NTSTATUS status;
 
        DOM_SID user_sid;
        NTSTATUS status;
 
-       int i, num_groups;
-       size_t bufsize;
-       ssize_t len;
+       char *sidstring;
+       size_t len;
        DOM_SID *groups;
        DOM_SID *groups;
+       int num_groups;
 
        /* Ensure null termination */
        state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
 
        /* 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;
        }
 
                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;
        }
 
                return WINBINDD_ERROR;
        }
 
-       state->response.data.num_entries = num_groups;
+       state->response.extra_data = sidstring;
        state->response.length += len+1;
        state->response.length += len+1;
+       state->response.data.num_entries = num_groups;
 
        return WINBINDD_OK;
 }
 
        return WINBINDD_OK;
 }
+
index 6f72a0e2c63f69de88fe2311e2ba124177e464d2..83c4c0f6ee5e5b391d1b68bfcae2b5c1c1721959 100644 (file)
@@ -58,12 +58,8 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do
        invalidate_cm_connection(&contact_domain->conn);
 
        {
        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)) {
        }
 
         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;
 {
        fstring dcname_slash;
        char *p;
-       struct rpc_pipe_client *cli;
+       struct rpc_pipe_client *netlogon_pipe;
        NTSTATUS result;
 
        state->request.domain_name
        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));
 
        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;
        }
 
 
        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);
 
                                           state->request.domain_name,
                                           dcname_slash);
 
@@ -202,11 +191,14 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
        }
 
        p = dcname_slash;
        }
 
        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);
 
        fstrcpy(state->response.data.dc_name, p);
-
        return WINBINDD_OK;
 }
 
        return WINBINDD_OK;
 }
 
index d012811d379b4f20e7f5409ade0c608ba31d1595..c1bb4b2600abbfe1aaa89712368ca016b1c0cd60 100644 (file)
@@ -175,6 +175,8 @@ typedef struct winbindd_gr {
 /* Flag to say this is a winbindd internal send - don't recurse. */
 #define WBFLAG_RECURSE                 0x0800
 
 /* 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 {
 /* 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 */
        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 */
 
        union {
                fstring winsreq;     /* WINS request */
@@ -240,10 +241,9 @@ struct winbindd_request {
                        gid_t gid;
                        fstring sid;
                } dual_idmapset;
                        gid_t gid;
                        fstring sid;
                } dual_idmapset;
-               struct {
-                       fstring cache_key;
-               } dual_sidaliases;
        } data;
        } data;
+       char *extra_data;
+       size_t extra_len;
        char null_term;
 };
 
        char null_term;
 };
 
index a0712144eeb5131682cfccbc7988f61745d2470a..c2324291a6389bca6f6098636239b8aed41a0a5a 100644 (file)
@@ -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 (!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;
        }
                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;
 {
        NTSTATUS result;
        fstring name_domain, name_user;
-       const char *srv_name_slash;
         NET_USER_INFO_3 info3;
         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;
        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];
        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));
        }
                                           local_nt_response, 
                                           sizeof(local_nt_response));
        }
-
        
        /* what domain should we contact? */
        
        
        /* 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();
        }
 
                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 {
        /* check authentication loop */
 
        do {
-               DOM_CRED clnt_creds;
 
                ZERO_STRUCT(info3);
 
                ZERO_STRUCT(info3);
-               ZERO_STRUCT(ret_creds);
                retry = False;
 
                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;
                }
 
 
                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
                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 );
 
                
        } 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 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));
                        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:
        }
 
 done:
+
        /* give us a more useful (more correct?) error code */
        /* 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;
        }
        
                result = NT_STATUS_NO_LOGON_SERVERS;
        }
        
@@ -450,7 +418,9 @@ done:
                char *afsname = SMB_STRDUP(lp_afs_username_map());
                char *cell;
 
                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);
 
                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);
                }
 
                        afsname = realloc_string_sub(afsname, "%s", sidstr);
                }
 
-               if (afsname == NULL) goto no_token;
+               if (afsname == NULL) {
+                       goto no_token;
+               }
 
                strlower_m(afsname);
 
 
                strlower_m(afsname);
 
@@ -474,7 +446,9 @@ done:
 
                cell = strchr(afsname, '@');
 
 
                cell = strchr(afsname, '@');
 
-               if (cell == NULL) goto no_token;
+               if (cell == NULL) {
+                       goto no_token;
+               }
 
                *cell = '\0';
                cell += 1;
 
                *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;
                                                 struct winbindd_cli_state *state) 
 {
        NTSTATUS result;
-       const char *srv_name_slash;
         NET_USER_INFO_3 info3;
         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;
        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;
 
        int attempts = 0;
        BOOL retry;
 
@@ -618,9 +588,10 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                goto done;
        }
 
                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? */
        
 
        /* 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;
                }
                        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;
                }
        } 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();
        }
 
                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 {
        do {
-               DOM_CRED clnt_creds;
                ZERO_STRUCT(info3);
                ZERO_STRUCT(info3);
-               ZERO_STRUCT(ret_creds);
                retry = False;
 
                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",
 
                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;
                }
 
                        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;
 
 
                attempts += 1;
 
@@ -712,19 +661,9 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
 
        } while ( (attempts < 2) && retry );
 
 
        } 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)) {
-               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));
                        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 */
                } 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;
                        }
                        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;
                        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) {
                }
                
                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) {
                }
                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:
                }
        }
 
 done:
+
        /* give us a more useful (more correct?) error code */
        /* 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);
        }
                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));
        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 */
        /* 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));
                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, 
        state->response.data.auth.pam_error = nt_status_to_pam(result);
 
        DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, 
index 74645564d48efff58295e395f60bd51ed8f9c83a..70275abf9224a91ddf1a7104acfd38a2b7719481 100644 (file)
@@ -84,6 +84,11 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
        pam_sm_setcred(). */
     ret_data = SMB_MALLOC_P(int);
 
        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 ) {
     /* 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 );
     }
 
         _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;
     if (!initialize_password_db(True)) {
         _log_err( LOG_ALERT, "Cannot access samba password database" );
         retval = PAM_AUTHINFO_UNAVAIL;
index 7c5a17b86f7e4451a0626fb9a4cc53bb280a306f..0a4f0556ae147acb11de5f37d4f23471c21ec581 100644 (file)
@@ -122,6 +122,7 @@ typedef struct
        char *szConfigFile;
        char *szSMBPasswdFile;
        char *szPrivateDir;
        char *szConfigFile;
        char *szSMBPasswdFile;
        char *szPrivateDir;
+        char *szCountersDir;
        char **szPassdbBackend;
        char **szPreloadModules;
        char *szPasswordServer;
        char **szPassdbBackend;
        char **szPreloadModules;
        char *szPasswordServer;
@@ -188,6 +189,7 @@ typedef struct
         char *szEventLogNumRecordsCommand;
         char *szEventLogOldestRecordCommand;
        char *szEventLogCloseCommand;
         char *szEventLogNumRecordsCommand;
         char *szEventLogOldestRecordCommand;
        char *szEventLogCloseCommand;
+        char *szEventLogControlCommand;
         char **szEventLogs;
        char *szGuestaccount;
        char *szManglingMethod;
         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}, 
        {"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}, 
        {"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}, 
        {"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}, 
 
 
        {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 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}, 
        {"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 */
 
        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;
        /* 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 */
 #else
        Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
 #endif /* WITH_LDAP_SAMCONFIG */
-
        string_set(&Globals.szLdapSuffix, "");
        string_set(&Globals.szLdapMachineSuffix, "");
        string_set(&Globals.szLdapUserSuffix, "");
        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.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;
 
        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;
           operations as root */
 
        Globals.bEnablePrivileges = False;
-       
+
        Globals.bASUSupport       = True;
        
        Globals.szServicesList = str_list_make( "Spooler NETLOGON", NULL );
        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_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)
 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_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)
 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_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)
 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:
                        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:
                        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() )
                   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();
        }
 
        set_server_role();
index 4cd9516dd199ebbad80f2757cf16748087e47f1d..6b58210919a0a9c77310cfe896f45dc762436f6f 100644 (file)
@@ -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;
 }
 
 /*****************************************************************
 }
 
 /*****************************************************************
index 283eb7f1c16cfbeffdd26ddf09fbe840f7dbcd4d..a7ff3a04f7e8939f755afc1ada7f19cce1601c17 100644 (file)
@@ -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. */
        }
 
        /* 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) {
        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;
        }
 
                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;
        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;
        }
 
                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;
        }
 
                return False;
        }
 
@@ -2334,8 +2334,8 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
                return True;
        }
 
                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;
        }
 
                return False;
        }
 
@@ -2383,9 +2383,9 @@ BOOL pdb_increment_bad_password_count(SAM_ACCOUNT *sampass)
                return False;
 
        /* Retrieve the account lockout policy */
                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)) {
                                &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;
        }
 
                return False;
        }
 
index 12e8bcc9cf947844f4ad8fcd7cac78564beb9d58..783e9e23fa306ecb696c33c2ff5e2e483a0d144e 100644 (file)
@@ -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 (!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;
            || (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;
        }
        
                        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;
            || (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;
        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. */
                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
 
                        if (current_history_len != pwHistLen) {
                                /* After closing and reopening SAM_ACCOUNT the history
index d4407492c215aa50cc892f9c678971dad9f3be5d..a9e41984c3d119eefaadac9276b32168f2b6eedd 100644 (file)
@@ -665,43 +665,46 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
                                                 rids, names, attrs);
 }
 
                                                 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"));
        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"));
        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"));
        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.
 /******************************************************************
   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;
 }
 
        *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
  *******************************************************************/
 /******************************************************************
   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_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;
        (*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);
 }
 
                                            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). 
 
 /***************************************************************
   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; */
 }
 
        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)
 {
 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)->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;
        (*methods)->search_users = pdb_default_search_users;
        (*methods)->search_groups = pdb_default_search_groups;
        (*methods)->search_aliases = pdb_default_search_aliases;
index 99f6670653b019f3a33f1eb3bd2aa75d420eb180..e44ccc3bf98ca3bcae474b75b376c53af08787ab 100644 (file)
@@ -178,6 +178,146 @@ static const char* get_objclass_filter( int schema_ver )
        return objclass_filter; 
 }
 
        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.
 ******************************************************************/
 /*******************************************************************
  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;
 
        if (ldap_state->is_nds_ldap) {
                char *user_dn;
-               int pwd_len;
+               size_t pwd_len;
                char clear_text_pw[512];
                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);
                /* 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));
                }
                } 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, 
 
        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);
                }
                                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;
        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;
 
                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' */
                        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;
                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));
 
                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;
 
 {
        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),
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
-               gid);
+               (unsigned long)gid);
 
        return ldapsam_getgroup(methods, filter, map);
 }
 
        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 };
 
        {
                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);
        }
                                    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;
 
 {
        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),
                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);
 }
 
        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() );
                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);
                
                             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;
 }
 
        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,
 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)->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);
        /* TODO: Setup private data and free */
 
        ldap_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct ldapsam_privates);
index 3e5f8d1b9309047b62c4ca1f08b76911f2ceb63a..599a198c5a4cf7d122671ecb4e265032581823f9 100644 (file)
@@ -550,7 +550,7 @@ static int nmasldap_get_password(
        LDAP     *ld,
        char     *objectDN,
        size_t   *pwdSize,      /* in bytes */
        LDAP     *ld,
        char     *objectDN,
        size_t   *pwdSize,      /* in bytes */
-       char     *pwd )
+       unsigned char     *pwd )
 {
        int err = 0;
 
 {
        int err = 0;
 
index edb578b1e7447bbeee1f900391cf5faccce5e176..6eb4305409a3a4b025720468afe430d4a1f03546 100644 (file)
@@ -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 *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;
        unsigned char *p;
        long uidval;
        size_t linebuf_len;
+       char *status;
 
        if(fp == NULL) {
                DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
 
        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.
         */
        /*
         * 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';
 
                linebuf[0] = '\0';
 
-               fgets(linebuf, 256, fp);
-               if (ferror(fp)) {
+               status = fgets(linebuf, 256, fp);
+               if (status == NULL && ferror(fp)) {
                        return NULL;
                }
 
                        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|", 
 
 #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) {
 #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;
 
        /* Static buffers we will return. */
        pstring user_name;
 
+       char *status;
        char linebuf[256];
        char readbuf[1024];
        char linebuf[256];
        char readbuf[1024];
-       unsigned char c;
+       int c;
        fstring ascii_p16;
        fstring encode_bits;
        unsigned char *p = NULL;
        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.
         */
        /*
         * 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';
 
                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;
                        pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);
                        fclose(fp);
                        return False;
index 6144037200ffabd607ba912c26478b3c9ca434bb..29437c35a872ba98dcf7f0518c836f8893a084d4 100644 (file)
@@ -30,6 +30,9 @@
 
 static TDB_CONTEXT *tdb;
 
 
 static TDB_CONTEXT *tdb;
 
+/* Urrrg. global.... */
+BOOL global_machine_password_needs_changing;
+
 /**
  * Use a TDB to store an incrementing random seed.
  *
 /**
  * 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;
        }
 
                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);
 
        memcpy(ret_pwd, pass->hash, 16);
        SAFE_FREE(pass);
 
-       if (channel) 
+       if (channel) {
                *channel = get_default_sec_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;
 }
 
        return True;
 }
@@ -454,11 +468,11 @@ BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32
        return ret;
 }
 
        return ret;
 }
 
-
 /************************************************************************
  Routine to fetch the plaintext machine account password for a realm
 /************************************************************************
  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)
 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;
 }
 
        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.
 
 /************************************************************************
  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));
 }
 
        return secrets_delete(trustdom_keystr(domain));
 }
 
-
 BOOL secrets_store_ldap_pw(const char* dn, char* pw)
 {
        char *key = NULL;
 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;
 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;
 }
 
        return True;
 }
 
-
 /**
  * Get trusted domains info from secrets.tdb.
  *
 /**
  * Get trusted domains info from secrets.tdb.
  *
index a9e1921e0d01757a0964f29ffad3f1744a732d77..42e4b6df967956c53195c859ede1a886f767de19 100644 (file)
@@ -30,15 +30,12 @@ typedef struct _known_sid_users {
        const char *known_user_name;
 } 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;
 {
        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" },
 
 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}};
 
        { 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.
 
 /**************************************************************************
  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);
 
        
        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));
 
        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++;
        }
 
                        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;
 }
 
 /**************************************************************************
 
        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;
                }
                        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;
 }
 
        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;
 
 {
        int i, j;
 
-       if (!sid_name_map_initialized)
-               init_sid_name_map();
-
        DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
 
        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) ) {
 
                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;
                                sid_append_rid(sid, users[j].rid);
                                *use = users[j].sid_name_use;
                                return True;
index e289eba1b6949a00b802aceaea1e34948d2e8449..e71d9e6f259020e22601284d09fe854bb9498bfb 100644 (file)
@@ -176,13 +176,15 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
                return;
 
        for (i = 0; i < num_pids; i++) {
                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;
                }
                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,
 
 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;
 
 {
        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->field = field;
        msg->id = id;
        msg->len = len;
-       msg->notify.data = buffer;
+       msg->notify.data = CONST_DISCARD(char *,buffer);
 
        send_spoolss_notify2_msg(msg);
 }
 
        send_spoolss_notify2_msg(msg);
 }
@@ -484,7 +486,7 @@ void notify_printer_location(int snum, char *location)
                snum, strlen(location) + 1, 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;
 {
        int snum = print_queue_snum(printername);
        int type = PRINTER_NOTIFY_TYPE;
index e6064564dc81589c68e4de7e47f573a9548aa7eb..8ae896fddf41013c9104bac2b401de609a457d03 100644 (file)
@@ -265,7 +265,7 @@ BOOL cups_cache_reload(void)
  * 'cups_job_delete()' - Delete a job.
  */
 
  * '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 */
 {
        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 */
 
 
        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...
 
        /*
         * Make sure we don't ask for passwords...
@@ -712,7 +712,7 @@ static int cups_queue_get(const char *sharename,
 
        *q = NULL;
 
 
        *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 
           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 
index 256654179e68141a37d5a3ab4e899a8058268a10..b2484d5b433245552af6f3d57f4f640dc4dd1252 100644 (file)
@@ -27,7 +27,8 @@ run a given print command
 a null terminated list of value/substitute pairs is provided
 for local substitution strings
 ****************************************************************************/
 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;
 {
 
        pstring syscmd;
@@ -68,14 +69,13 @@ static int print_run_command(int snum, const char* printername, BOOL do_sub, cha
 /****************************************************************************
 delete a print job
 ****************************************************************************/
 /****************************************************************************
 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);
 {
        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);
                   "%j", jobstr,
                   "%T", http_timestring(pjob->starttime),
                   NULL);
index 33bbcb256ab6010072d4348821f13f7fd56e0c5d..6193dbe2ca94cbc50f69428c6580789ec24bdece 100644 (file)
@@ -423,7 +423,7 @@ BOOL iprint_cache_reload(void)
  * 'iprint_job_delete()' - Delete a job.
  */
 
  * '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 */
 {
        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 */
 
 
        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...
 
        /*
        * 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);
 
        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);
 
 
        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...
        */
 
        * 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) {
 
        if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
                if (response->request.status.status_code >= IPP_OK_CONFLICT) {
index 61470f151002269327addb24823f9b0e74b3c328..6e74095f719b01f8a6d8c75d2dc9ee08f6e9c949 100644 (file)
@@ -691,6 +691,8 @@ struct traverse_struct {
        int qcount, snum, maxcount, total_jobs;
        const char *sharename;
        time_t lpq_time;
        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 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);
                        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++) {
        
        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;
                                break;
+                       }
                }
        }
        
                }
        }
        
@@ -779,9 +810,10 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                return 0;
        }
 
                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 */
           represents the SMB jobid      --jerry */
+
        ts->queue[i].job = jobid;               
        ts->queue[i].size = pjob.size;
        ts->queue[i].page_count = pjob.page_count;
        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);
 
        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;
                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.
 
 /****************************************************************************
  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)
 ****************************************************************************/
 
 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;
 
        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++) {
 
        /* 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,
                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++) {
         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,
                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)) 
        {
                || (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 " 
                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 
                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 ) 
                {
                        && 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,
 
 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;
 {
        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->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);
                pjob_store(sharename, jobid, pjob);
+
                check_job_changed(sharename, jcdata, jobid);
        }
 
                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.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);
 
 
        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,
 
 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;
 {
        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 */
        
 
        /* 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);
        
        /* 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
 ****************************************************************************/
 /****************************************************************************
 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;
 {
        fstring sharename;
-       pstring lpqcommand;
+       pstring lpqcommand, lprmcommand;
        int printing_type;
        size_t len;
 
        int printing_type;
        size_t len;
 
-       len = tdb_unpack( buf, msglen, "fdP",
+       len = tdb_unpack( buf, msglen, "fdPP",
                sharename,
                &printing_type,
                sharename,
                &printing_type,
-               lpqcommand );
+               lpqcommand,
+               lprmcommand );
 
        if ( len == -1 ) {
                DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
 
        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),
 
        print_queue_update_with_lock(sharename, 
                get_printer_fns_from_type(printing_type),
-               lpqcommand );
+               lpqcommand, lprmcommand );
 
        return;
 }
 
        return;
 }
@@ -1382,7 +1434,7 @@ static void print_queue_update(int snum, BOOL force)
 {
        fstring key;
        fstring sharename;
 {
        fstring key;
        fstring sharename;
-       pstring lpqcommand;
+       pstring lpqcommand, lprmcommand;
        char *buffer = NULL;
        size_t len = 0;
        size_t newlen;
        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) );
        
        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 
        /* 
         * 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 );
        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;
        }
 
                return;
        }
@@ -1415,23 +1471,26 @@ static void print_queue_update(int snum, BOOL force)
        
        /* get the length */
 
        
        /* get the length */
 
-       len = tdb_pack( buffer, len, "fdP",
+       len = tdb_pack( buffer, len, "fdPP",
                sharename,
                type,
                sharename,
                type,
-               lpqcommand );
+               lpqcommand, 
+               lprmcommand );
 
        buffer = SMB_XMALLOC_ARRAY( char, len );
 
        /* now pack the buffer */
 
        buffer = SMB_XMALLOC_ARRAY( char, len );
 
        /* now pack the buffer */
-       newlen = tdb_pack( buffer, len, "fdP",
+       newlen = tdb_pack( buffer, len, "fdPP",
                sharename,
                type,
                sharename,
                type,
-               lpqcommand );
+               lpqcommand,
+               lprmcommand );
 
        SMB_ASSERT( newlen == len );
 
        DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
 
        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
 
        /* 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();
        /* 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();
 
                 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 );
 
        int result = 0;
        struct printif *current_printif = get_printer_fns( snum );
 
-       pjob = print_job_find(sharename, jobid);
-
        if (!pjob)
                return False;
 
        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
                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));
 
        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);
 
        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);
 }
 
        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 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;
        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);
        
 
        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;
 
                *errcode = WERR_ACCESS_DENIED;
 
-       return deleted;
+       return (pjob == NULL );
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
index b9b4b3c6b04ab6249f440bc235d995dd1cba1bde..adea10dfa691b5277152a65f1e63ad1f5a5e3677 100644 (file)
@@ -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. */
 
 
                /* 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) {
 
                        /* Refcount == zero is a logic error and should never happen. */
                        if (IVAL(data.dptr, i + 4) == 0) {
index e6d34e68cda7fcf3201f0b94086aad92bfa46cf1..0cf8c8e15bffa40fc4a7fdd353eae84acecbf04f 100644 (file)
@@ -79,7 +79,8 @@ void profile_message(int msg_type, pid_t src, void *buf, size_t len)
 /****************************************************************************
 receive a request profile level message
 ****************************************************************************/
 /****************************************************************************
 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;
 
 {
         int level;
 
@@ -88,7 +89,8 @@ void reqprofile_message(int msg_type, pid_t src, void *buf, size_t len)
 #else
        level = 0;
 #endif
 #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);
 }
 
        message_send_pid(src, MSG_PROFILELEVEL, &level, sizeof(int), True);
 }
 
index afb5c613c802d2f224980b8e51c0ca8fa87faa54..ab8fc14d909cd04c7787551749980f04881df763 100644 (file)
@@ -92,18 +92,10 @@ static BOOL init_registry_data( void )
        fstring keyname, subkeyname;
        REGSUBKEY_CTR *subkeys;
        REGVAL_CTR *values;
        fstring keyname, subkeyname;
        REGSUBKEY_CTR *subkeys;
        REGVAL_CTR *values;
-       uint32 *ctx;
        int i;
        const char *p, *p2;
        UNISTR2 data;
        
        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++ ) {
        /* 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 */
                        
                           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;
                        }
                                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++ ) {
        /* 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;
                }
                        DEBUG(0,("talloc() failure!\n"));
                        return False;
                }
index 7f8f664ec6e196aee4bf9f1aab30328eb7350319..b1a2a307554ab1567baff624d06a3e8241c2d81f 100644 (file)
@@ -37,7 +37,7 @@ static int netlogon_params( REGVAL_CTR *regvals )
 {
        uint32 dwValue;
        
 {
        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,
                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 );
 }
 
        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 
 
 /***********************************************************************
  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/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 }
 };
 
        { NULL, NULL }
 };
 
index b20eb046db8034428140b31044b2458e92187c4d..bed9e1d59aec33ac8b4be8a801d29f81e8571a8c 100644 (file)
@@ -1,7 +1,8 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  Virtual Windows Registry Layer
 /* 
  *  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
  *  
  *  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
  
 #include "includes.h"
 
  
 #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 
 }
 
 /**********************************************************************
  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 */
        
        
        /* 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;
 }
 
 /**********************************************************************
        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 = {
 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
 };
        NULL
 };
index d6e02884616817f732368d0aee5725f38d4a3043..f41c5885bc4d7bdc8710793790ae8ab4e3336c93 100644 (file)
@@ -38,15 +38,70 @@ REGISTRY_HOOK reg_hooks[] = {
   { KEY_PRINTING,              &printing_ops },
   { KEY_PRINTING_2K,           &printing_ops },
   { KEY_PRINTING_PORTS,        &printing_ops },
   { KEY_PRINTING,              &printing_ops },
   { KEY_PRINTING_2K,           &printing_ops },
   { KEY_PRINTING_PORTS,        &printing_ops },
-#if 0
   { KEY_EVENTLOG,              &eventlog_ops }, 
   { KEY_EVENTLOG,              &eventlog_ops }, 
-#endif
   { KEY_SHARES,                &shares_reg_ops },
 #endif
   { NULL, NULL }
 };
 
 
   { 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
  ***********************************************************************/
 /***********************************************************************
  Open the registry database and initialize the REGISTRY_HOOK cache
  ***********************************************************************/
@@ -55,11 +110,12 @@ BOOL init_registry( void )
 {
        int i;
        
 {
        int i;
        
+       
        if ( !init_registry_db() ) {
                DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
                return False;
        }
        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();
        /* 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);
 
        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;
 }
 
        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 );
 }
 
        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;
+}
index 70410a674095b607a237cb5366bc5d09fabe98d7..05567d561c62589a48b7f8e240dc31beaf81fd1a 100644 (file)
@@ -236,7 +236,7 @@ uint32 regval_type( REGISTRY_VALUE *val )
 
 /***********************************************************************
  Retreive a pointer to a specific value.  Caller shoud dup the structure
 
 /***********************************************************************
  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 )
  **********************************************************************/
 
 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 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 (file)
index 0000000..609f86d
--- /dev/null
@@ -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;
+       }
+}    
index d0f7daa926dec814b135614bb756abd5426aecf9..b07c8e9644f56424f92901b78975f5df5e0760a6 100644 (file)
@@ -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 
  **********************************************************************/
 /***********************************************************************
  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 )
 {
 
 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 */
        
        
        /* 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 )
        /* 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
        else
-               subkeypath = remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
+               subkeypath = reg_remaining_path( key + strlen(KEY_CONTROL_PRINTERS) );
                
        return subkeypath;
 }
                
        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 */
        
        /* 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 */
                
 
        /* 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" ));
        
 
        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 */
        
        
        /* 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 */
        
 
        /* 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);
                return 0;
        
        pstrcpy( subkey, keystr);
index 165292cf2feb1c7ff948f3929b98beee738a804b..9f19db2646a12a61f2926b5e861accb5c15b180a 100644 (file)
@@ -97,3 +97,31 @@ void normalize_reg_path( pstring keyname )
        strupper_m( 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;
+}
+
index e7b8cdc8bb24e1aeb190ca1c9877d12dc72a066b..954f4ae7bd0b6916984c3e783a429ef1d1f07bb4 100644 (file)
@@ -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 ) {
        /* 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;
        }
                if ( hbin_contains_offset( hbin, offset ) )
                        return hbin;
        }
index 79335191183735e4d1549411d6e215ce8bcd2a88..78df220ac2a3ecdbf7ac1ac3a8303cb49ea462c2 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    RPC pipe client
    Copyright (C) Tim Potter                        2000-2001,
    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
    
    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 */
 
 
 /* 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;
                        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);
 
        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);
 
        /* 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 */
 
 
        /* Return result */
 
@@ -59,14 +51,10 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        result = NT_STATUS_OK;
 
 
        result = NT_STATUS_OK;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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)
 {
                      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);
 
        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);
 
        /* 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);
 
 
        /* Return result */
 
         result = werror_to_ntstatus(r.status);
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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)
 {
                         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);
 
        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);
 
        /* 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);
 
 
        /* Return result */
 
        result = werror_to_ntstatus(r.status);
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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)
                           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);
 
        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);
 
        /* 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;
        
 
        /* 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 */
 
        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;
                       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);
 
        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);
 
        /* 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;
 
        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);
 
 
        /* Return result */
 
        result = werror_to_ntstatus(r.status);
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
        return result;
 }
index 41063a5d7fb60f3ce623bf6b7cf63fe13b1e2690..8d1945f76988509dd8ad0e2006b5c19ee0c9580b 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    RPC pipe client
    Copyright (C) Gerald Carter                        2002,
    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
    
    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);
 
        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;
        
        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. */ 
        
        /* 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:
        }
        
 done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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
 ********************************************************************/
 /********************************************************************
  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);
 
        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 );
                
        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;
        
        
        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;
 }
        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);
-}
index cd7e21f918f2e0e7d3ae32455759c025234f4171..89de6cec9417ab393da474513ca2ef3919837bf6 100644 (file)
@@ -4,6 +4,7 @@
    RPC pipe client
 
    Copyright (C) Tim Potter 2003
    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
    
    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"
 
 
 #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;
                          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);
 
        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);
 
        /* 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;
 
 
        if (response)
                *response = r.response;
 
        result = True;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
        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;
                       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);
 
        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);
 
        /* 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;
 
 
        result = True;
 
@@ -109,14 +82,10 @@ NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                memcpy(*out_data, r.data, size);
        }
 
                memcpy(*out_data, r.data, size);
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
        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;
                            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);
 
        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);
 
        /* 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;
 
 
        result = True;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
        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;
                              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);
 
        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);
 
        /* 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;
 
 
        result = True;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
        return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
index 26f82cdfbe3e1ec885625373ae8e08aa37144160..d7dcda72e3f70ab728f4734ccfdd2eefe1abca04 100644 (file)
@@ -3,10 +3,8 @@
    RPC pipe client
    Copyright (C) Tim Potter                        2000-2001,
    Copyright (C) Andrew Tridgell              1992-1997,2000,
    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) 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
    
    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 "includes.h"
-#include "rpc_client.h"
 
 /** @defgroup lsa LSA - Local Security Architecture
  *  @ingroup rpc_client
 
 /** @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;
 
        LSA_SEC_QOS qos;
        NTSTATUS result;
 
-       SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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) {
        /* 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 */
 
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -97,20 +81,9 @@ NTSTATUS rpccli_lsa_open_policy(struct rpc_pipe_client *cli,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 
 /** 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;
        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);
 
 
        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);
        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 {
        } 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 */
 
 
        /* Return output parameters */
 
@@ -169,21 +126,9 @@ NTSTATUS rpccli_lsa_open_policy2(struct rpc_pipe_client *cli,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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, 
 /** 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;
 
        LSA_R_CLOSE r;
        NTSTATUS result;
 
-       SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        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 */
 
 
        /* Return output parameters */
 
@@ -230,19 +160,9 @@ NTSTATUS rpccli_lsa_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                *pol = r.pol;
        }
 
                *pol = r.pol;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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,
 /** 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;
        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);
 
        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);
 
        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;
 
        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 */
          
                /* An actual error occured */
+               result = r.status;
 
                goto done;
        }
 
                goto done;
        }
@@ -356,22 +262,10 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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,
 /** 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);
 
        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;
 
        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;
 
 
        result = r.status;
 
@@ -468,21 +349,10 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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 */
 /** 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;
 
        LSA_R_QUERY_INFO r;
        NTSTATUS result;
 
-       SMB_ASSERT(cli->pipe_idx == PI_LSARPC);
-
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        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;
 
        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:
        }
        
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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
 /** 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);
 
        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);
 
        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;
 
        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:
        }
        
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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
  *
 /**
  * Enumerate list of trusted domains
  *
@@ -720,7 +536,6 @@ NTSTATUS rpccli_lsa_enum_trust_dom(struct rpc_pipe_client *cli,
        int i;
        fstring tmp;
 
        int i;
        fstring tmp;
 
-
        ZERO_STRUCT(in);
        ZERO_STRUCT(out);
 
        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);
 
        
         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,
                    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;
 }
 
        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*/
 
 /** 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)
 {
                                 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);
 
        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);
 
        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;
 
        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:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /** Get privilege name */
 
 
        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)
                              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);
 
        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);
 
        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;
 
        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:
        *lang_id_desc = r.lang_id;
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /** Enumerate list of SIDs  */
 
 
        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)
 {
                                 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);
 
        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);
 
         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;
 
 
        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:
        *enum_ctx = r.enum_context;
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
        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)
 {
                              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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1046,10 +793,6 @@ NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                *user_pol = r.pol;
        }
 
                *user_pol = r.pol;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
  *
  * @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)
 {
                              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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1099,10 +829,6 @@ NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                *user_pol = r.pol;
        }
 
                *user_pol = r.pol;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
  *
  * @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;
                              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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1169,15 +882,13 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        *count=r.count;
  done:
 
        *count=r.count;
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /** Get a privilege value given its name */
 
 
        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;
                                 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);
 
        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);
 
        /* 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;
 
        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:
        (*luid).high=r.luid.high;
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /** Query LSA security object */
 
 
        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)
 {
                              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);
 
        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);
 
        /* 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;
 
        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:
                *psdb = r.buf;
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
        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.
 */
 
    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)
 {
                                     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);
 
        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);
 
        /* 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;
 
        if (!NT_STATUS_IS_OK(result = r.status)) {
                goto done;
@@ -1353,10 +1029,9 @@ done:
 
 /* add account rights to an account. */
 
 
 /* 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,
                                    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;
 {
        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);
        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);
 
 
        /* 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;
 
        if (!NT_STATUS_IS_OK(result = r.status)) {
                goto done;
@@ -1396,7 +1062,7 @@ done:
 
 /* remove account rights for an account. */
 
 
 /* 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)
 {
                                       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);
        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);
 
 
        /* 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;
 
        if (!NT_STATUS_IS_OK(result = r.status)) {
                goto done;
@@ -1539,7 +1196,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
 
 #endif
 
 
 #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)
 {
                                     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);
 
        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 */
 
        /* 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 */
        
 
        /* 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;
        }
 
                *trustdom_pol = r.handle;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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)
                                           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);
 
        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); 
 
        /* 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;
 
        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:
        *info = r.info;
                
 done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 
        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)
                                                  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);
 
        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); 
 
        /* 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;
 
        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:
        *info = r.info;
 
 done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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)
                                                   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);
 
        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); 
 
        /* 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;
 
        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:
        *info = r.info;
 
 done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
        
        return result;
 }
        
        return result;
 }
-
-/** @} **/
-
index fad60dbc20d9ce6c74e7830e415387b2b66cbb02..88b6c792ebfb7c393b76673ee0d2f70d7060da7b 100644 (file)
@@ -2,12 +2,9 @@
    Unix SMB/CIFS implementation.
    NT Domain Authentication SMB / MSRPC client
    Copyright (C) Andrew Tridgell 1992-2000
    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) 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
    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
 #include "includes.h"
 
 /* LSA Request Challenge. Sends our challenge to server, then gets
 #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
 
 /****************************************************************************
 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.
 ****************************************************************************/
 
 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)
 {
                       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;
 
         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
        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 */
 
 
         /* 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;
 
 
         result = r.status;
 
@@ -186,259 +124,257 @@ NTSTATUS cli_net_auth2(struct cli_state *cli,
                  */
 
                 zerotime.time = 0;
                  */
 
                 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 \
 
                         /*
                          * 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;
         }
 
                 }
                *neg_flags = r.srv_flgs.neg_flags;
         }
 
- done:
-        prs_mem_free(&qbuf);
-        prs_mem_free(&rbuf);
-        
         return result;
 }
         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_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,
         /* 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,
 
         /* 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 */
 
 
         /* 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)) {
 
         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;
 }
 
         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_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",
         /* 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 */
 
         /* 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 */
 
 
         /* 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)) {
 
         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;
 }
         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 */
 
 }
 
 /* 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;
                                   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);
 
 
        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 */
 
        /* 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 */
 
 
        /* 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;
 
        result = r.status;
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        return result;
 }
 
@@ -456,72 +392,29 @@ NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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 */
 
        /* 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);
                rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
+       }
 
        return result;
 }
 
 
        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 */
 
 /* 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)
                                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;
        NET_R_SAM_SYNC r;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
         DOM_CRED clnt_creds;
+        DOM_CRED ret_creds;
 
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
 
        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 */
 
 
        /* 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 */
 
 
         /* 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;
 
         *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 */
 
 
        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, 
                                  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);
 
        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 */
 
        /* 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 */
 
                               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 */
 
 
         /* 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;
 
         *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 */
 
 
        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;
                                 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;
         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(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 */
 
 
         /* Initialise input parameters */
 
-        gen_next_creds(cli, &clnt_creds);
+       creds_client_step(cli->dc, &clnt_creds);
 
         q.validation_level = validation_level;
 
 
         q.validation_level = validation_level;
 
-       if (ret_creds == NULL)
-               ret_creds = &dummy_rtn_creds;
-
         ctr.switch_value = logon_type;
 
         switch (logon_type) {
         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);
 
 
                 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? */
                               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;
                               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);
 
                 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? */
                               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));
                               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 */
 
                       &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;
 
         /* 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;
 }
 
         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,
 
 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,
                                           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;
 {
        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;
        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];
        static uint8 zeros[16];
+       DOM_CRED clnt_creds;
+       DOM_CRED ret_creds;
        int i;
        
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
        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;
 
 
        /* 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,
         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(),
                      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);
 
                       &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;
 
         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) {
        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) {
        } 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);
        }
        } 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;
         /* 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;
 }
 
 
         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.
 ****************************************************************************/
 
 /***************************************************************************
 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; 
                           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;
        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 */
        
         /* 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;
+}
index 230750817a95f75abd15857474290d385132ff3e..df34b1c3d958433ecd72f91e93a4b3bea15dc5dc 100644 (file)
@@ -1,11 +1,7 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
 /* 
  *  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
  *  
  *  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
 
 extern struct pipe_id_info pipe_names[];
 
 
 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.
 
 /*******************************************************************
  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;
 {
        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;
        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) {
 
        /*
         * 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;
                        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);
 
                                         (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)) {
                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;
                }
 
                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)); */
 
        /*
        /* && 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;
+
+       return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ schannel specific sign/seal.
+ ****************************************************************************/
 
 
-       char *dp = prs_data_p(rdata) + fragment_start + len -
-               RPC_HDR_AUTH_LEN - auth_len;
-       prs_struct auth_verf;
+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;
+       }
 
 
-       *pauth_padding_len = 0;
+       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;
+       }
 
 
-       if (auth_len == 0) {
-               if (cli->pipe_auth_flags == 0) {
-                       /* move along, nothing to see here */
-                       return True;
-               }
+       if (!schannel_auth) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
 
-               DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\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(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)));
+       data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
 
 
-       if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-               DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
-               return False;
+       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;
        }
 
        }
 
-       DEBUG(10,("rpc_auth_pipe: packet:\n"));
-       dump_data(100, dp, auth_len);
+       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;
+       }
 
 
-       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(!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;
+       }
 
 
-       {
-               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 (!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;
+       }
 
 
-               /* 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 */
+       /* The sequence number gets incremented on both send and receive. */
+       schannel_auth->seq_num++;
 
 
-               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;
-               }
+       /*
+        * 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;
+
+       return NT_STATUS_OK;
+}
 
 
-                       DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
-                       BOOL store_ok;
+/****************************************************************************
+ Do the authentication checks on an incoming pdu. Check sign and unseal etc.
+ ****************************************************************************/
 
 
-                       /* save the reply away, for use a little later */
-                       prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
+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;
 
 
-                       store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, 
-                                                                          ntlmssp_verf)));
+       /* Paranioa checks for auth_len. */
+       if (prhdr->auth_len) {
+               if (prhdr->auth_len > prhdr->frag_len) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
 
 
-                       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;
+               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(!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;
+                       }
 
 
-               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;
+                       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.
 
  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   |
  +------------+-----------------+-------------+---------------+-------------+
 
  | 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.
 
  ****************************************************************************/
 
  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];
        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;
        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;
        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. */
 
        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 */
 
        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 */
        {
                  &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. */
        }
 
        /* 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) {
        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;
-
-       /* This next call sets the endian bit correctly in rdata. */
+       prs_give_memory(&current_pdu, prdata, rdata_len, True);
 
 
-       if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
-               prs_mem_free(rdata);
-               return False;
-       }
+       /* Ensure we can mess with the return prs_struct. */
+       SMB_ASSERT(UNMARSHALLING(rbuf));
+       SMB_ASSERT(prs_data_size(rbuf) == 0);
 
 
-       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;
-               }
-       }
+       /* Make rbuf dynamic with no memory. */
+       prs_give_memory(rbuf, 0, 0, True);
 
 
-       if (rhdr.pkt_type == RPC_BINDNACK) {
-               DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->fnum));
-               prs_mem_free(rdata);
-               return False;
-       }
+       while(1) {
+               RPC_HDR rhdr;
+               char *ret_data;
+               uint32 ret_data_len;
 
 
-       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. */
+
+               ret = cli_pipe_validate_current_pdu(cli, &rhdr, &current_pdu, expected_pkt_type,
+                               &ret_data, &ret_data_len, rbuf);
 
 
-       DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
-                 (unsigned int)len, (unsigned int)rdata_len ));
+               DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n",
+                       prs_data_size(&current_pdu), current_rbuf_offset ));
 
 
-       /* 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 */
+               if (!NT_STATUS_IS_OK(ret)) {
+                       goto err;
+               }
 
 
-       if (len > 0) { 
-               /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+               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;
+                               }
+                       }
+               }
 
 
-               /* Read the remaining part of the first response fragment */
+               /* 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.
+ ********************************************************************/
+
+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);
 
 
-               fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+       /* We may change the pad length before marshalling. */
+       init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1);
 
 
-               /*
-                * Verify any authentication footer.
-                */
+       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(!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);
-               }
+       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);
 
 
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
+       /* 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;
+       }
 
 
- ********************************************************************/
+       DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
+       dump_data(5, (const char *)spnego_msg.data, spnego_msg.length);
 
 
-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)
+       data_blob_free(&spnego_msg);
+       return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Creates NTLMSSP auth bind.
+ ********************************************************************/
+
+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. */
        /* 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 */
 
        /* 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 */
 
        /* 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)) {
 
        /* 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)) {
                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;
        }
 
                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(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;
                }
        }
                        return NT_STATUS_NO_MEMORY;
                }
        }
-       prs_mem_free(&auth_info);
+
        return NT_STATUS_OK;
 }
 
 /*******************************************************************
        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_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;
+       }
+
+       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;
+       }
 
 
-       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;
+       /* 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;
                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);
+
+               if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) {
+                       prs_mem_free(&outgoing_pdu);
+                       return NT_STATUS_NO_MEMORY;
+               }
 
 
-                       data_and_padding_size = prs_offset(&sec_blob);
-                       auth_padding = data_and_padding_size - send_size;
+               /* 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;
+               }
 
 
-                       /* insert the auth header */
-                       
-                       if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) {
-                               prs_mem_free(&sec_blob);
-                               return False;
+               /* 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);
+               /* 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);
 
 
-               /*
-                * 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;
-               }
-
-               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.
 ****************************************************************************/
 /****************************************************************************
  Set the handle state.
 ****************************************************************************/
@@ -1174,56 +1633,10 @@ static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
 
        return state_set;
 }
 
        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)
 ****************************************************************************/
 
 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: "));    
        }
 
        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: "));
                  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 */
                  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)
 ****************************************************************************/
 
 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)"));
        }
 
                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) )
 # 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;
        }
 
                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));
        }
 
        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;
 }
 
        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;
+
+       /* 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;
+       }
 
 
-       prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ 
-                cli->cli->mem_ctx, MARSHALL);
+       /*
+               I'm puzzled about this - seems to violate the DCE RPC auth rules,
+               about padding - shouldn't this pad to length 8 ? JRA.
+       */
 
 
-       if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
-                                                 &rpc_out))) {
-               return False;
+       /* 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 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);
 
 
-       /******************* bind request on pipe *****************/
+       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;
+       }
 
 
-       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;
+       prs_mem_free(&rpc_out);
+
+       /* 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]);
+       /* Initialize the incoming data struct. */
+       prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL);
 
 
-       /* Server offered schannel, so try it. */
+       /* 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;
+       }
 
 
-       memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key,
-              sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key));
+       prs_mem_free(&rpc_out);
 
 
-       cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
-       cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
-       cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+       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;
+       }
 
 
-       return cli_nt_session_open(cli, PI_NETLOGON) ?
-               NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
+       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(!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;
+       }
 
 
-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;
+       cli->max_xmit_frag = hdr_ba.bba.max_tsize;
+       cli->max_recv_frag = hdr_ba.bba.max_rsize;
 
 
-       if (lp_client_schannel() == False) {
-               return NT_STATUS_OK;
-       }
+       /* For authenticated binds we may need to do 3 or 4 leg binds. */
+       switch(auth_type) {
 
 
-       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;
-       }
+               case PIPE_AUTH_TYPE_NONE:
+               case PIPE_AUTH_TYPE_SCHANNEL:
+                       /* Bind complete. */
+                       break;
 
 
-       neg_flags |= NETLOGON_NEG_SCHANNEL;
+               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;
 
 
-       result = cli_nt_setup_creds(cli, sec_chan, trust_password,
-                                   &neg_flags, 2);
+               case PIPE_AUTH_TYPE_KRB5:
+                       /* */
 
 
-       if (!(neg_flags & NETLOGON_NEG_SCHANNEL) 
-           && lp_client_schannel() == True) {
-               DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
-               result = NT_STATUS_UNSUCCESSFUL;
+               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;
        }
 
        }
 
-       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;
-       }
+       /* Pipe is bound - set up auth_type and auth_level data. */
 
 
-       memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key,
-              sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key));
-
-       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;
 }
 
        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;
 
 {
        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");
        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;
 
 
        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) {
 
        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",
                         "to machine %s.  Error was %s\n",
-                        &pipe_names[pipe_idx].client_pipe[5], cli->desthost,
+                        result->pipe_name, cli->desthost,
                         cli_errstr(cli)));
                         cli_errstr(cli)));
+               *perr = cli_get_nt_error(cli);
                talloc_destroy(result->mem_ctx);
                return NULL;
        }
                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->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;
 }
 
 
        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;
 
 {
        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;
        }
 
                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;
 }
 
        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;
 {
        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);
 
        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;
        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;
 
 {
        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;
        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;
        }
 
                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;
 }
 
        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);
+}
 
 
-       talloc_destroy(cli_pipe->mem_ctx);      
+/****************************************************************************
+ 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;
+       }
+
+       /* 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
index 97ae8b29e7d9e9faf8e5ceb4984b3d282b8e3cb9..87ab5dc9dad143402ad871a2281ab8fa67f72b94 100644 (file)
@@ -3,9 +3,7 @@
    RPC Pipe client
  
    Copyright (C) Andrew Tridgell              1992-2000,
    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
    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)
 *******************************************************************/
 
  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)
                                       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);
 
 
        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,
                    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)
 *******************************************************************/
 
  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;
                          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 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);
 }
 
                                      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)
 {
                           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);
 
 
        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,
                    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;
 {
        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);
 
        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,
                    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...
 ****************************************************************************/
 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;
                            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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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,
                            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 );
 
 
        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,
                    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);
 
 
                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,
                            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;
                             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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                            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);
 
        
        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,
                    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 
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                              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);
 
                
        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,
                    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 
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                              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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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;
                             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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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;
                             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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                             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,
        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;
        }
                                 
                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);
 
 
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                           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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                             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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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)
 {
                           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);
 
        
        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,
                    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);
 
 
                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,
                            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)
 {
                             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);
 
        
        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,
                    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;
                        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);
 
        
        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,
                    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
 ****************************************************************************/
 /****************************************************************************
 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;
                          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 );
 
        
        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,
                    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;
 }
 
        return True;
 }
-
-
index 01ec0bd51eb932ac5dd867dfb839e0c0abb6a6f5..d68c72e20c8b935d3d6440e87226d5c5f839014e 100644 (file)
@@ -3,10 +3,8 @@
    RPC pipe client
    Copyright (C) Tim Potter                        2000-2001,
    Copyright (C) Andrew Tridgell              1992-1997,2000,
    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) 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
    
    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);
 
        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);
 
        /* 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)) {
        /* 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
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
 /* 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;
                           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;
 
        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);
 
        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 */
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -122,10 +93,6 @@ NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -171,19 +131,9 @@ NTSTATUS rpccli_samr_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
                *connect_pol = r.pol;
        }
 
                *connect_pol = r.pol;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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,
 /* 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -228,26 +171,9 @@ NTSTATUS rpccli_samr_open_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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, 
 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -290,22 +209,9 @@ NTSTATUS rpccli_samr_open_user(struct rpc_pipe_client *cli,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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,
 /* 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -350,25 +249,12 @@ NTSTATUS rpccli_samr_open_group(struct rpc_pipe_client *cli,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
 /* 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)
                                   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);
 
        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);
 
        /* 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 */
 
 
        /* 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;
 
        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 */
 
        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;
                               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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Delete a domain group member */
 
        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;
                               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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        return result;
 }
 
@@ -520,47 +373,28 @@ NTSTATUS rpccli_samr_query_userinfo(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
        *ctr = r.ctr;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
 /* 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;
                                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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Query group info */
 
        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)
 {
                                   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);
 
        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);
 
        /* 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;
 
 
        *ctr = r.ctr;
 
@@ -642,10 +458,6 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        result = r.status;
 
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        return result;
 }
 
@@ -667,23 +479,16 @@ NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -692,24 +497,12 @@ NTSTATUS rpccli_samr_query_usergroups(struct rpc_pipe_client *cli,
                *gid = r.gid;
        }
 
                *gid = r.gid;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
 /* 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;
                                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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        return result;
 }
 
@@ -771,11 +553,6 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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;
        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);
 
 
        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 */
 
 
        /* Return output parameters */
 
@@ -803,25 +578,9 @@ NTSTATUS rpccli_samr_query_useraliases(struct rpc_pipe_client *cli,
                *als_rids = r.rid;
        }
 
                *als_rids = r.rid;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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,
 /* 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -865,22 +617,9 @@ NTSTATUS rpccli_samr_query_groupmem(struct rpc_pipe_client *cli,
                *attr = r.attr;
        }
 
                *attr = r.attr;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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
  *
 /**
  * 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
  **/
  * 
  * @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)
                                  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;
        
        /* 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);
        
        /* 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) &&
        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:
        }
        
 done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-       
        return result;
 }
 
        return result;
 }
 
@@ -996,23 +725,16 @@ NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1051,22 +773,9 @@ NTSTATUS rpccli_samr_enum_dom_groups(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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,
 /* 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1144,27 +844,15 @@ NTSTATUS rpccli_samr_enum_als_groups(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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 */
 
 /* 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;
 {
        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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1221,17 +900,15 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Open handle on an alias */
 
        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;
 {
        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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1274,16 +940,12 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 #endif
        }
 
 #endif
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Create an alias */
 
        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)
 {
                                   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);
 
        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);
 
        /* 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 */
 
 
        /* 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;
        }
 
                *alias_pol = r.alias_pol;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Add an alias member */
 
        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;
                               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);
 
        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);
 
        /* 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;
 
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Delete an alias member */
 
        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;
                               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);
 
        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);
 
        /* 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;
 
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Query alias info */
 
        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)
 {
                                   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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1468,9 +1076,7 @@ NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        *ctr = *r.ctr;
 
 
        *ctr = *r.ctr;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
+  done:
 
        return result;
 }
 
        return result;
 }
@@ -1493,27 +1099,18 @@ NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
        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);
 
        /* 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;
 
        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 */
 
 
        /* Return output parameters */
 
@@ -1522,20 +1119,10 @@ NTSTATUS rpccli_samr_query_dom_info(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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,
 /* 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];
 
        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);
 
        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);
 
        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 */
 
        /* 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);
 
                                   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 */
 
 
        /* Return output parameters */
 
@@ -1621,21 +1201,10 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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 
 /* 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;
 
 
        *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);
 
        /* 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;
 
        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 */
 
 
        /* 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:
        *start_idx += r.num_entries;  /* No next_idx in this structure! */
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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. */
 
 /* 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1815,26 +1352,13 @@ NTSTATUS rpccli_samr_lookup_rids(struct rpc_pipe_client *cli,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 
        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 */
 
 /* 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,
                                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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -1893,15 +1408,13 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /* Create a domain user */
 
 
        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)
                                   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);
 
        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);
 
        /* 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 */
 
 
        /* 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:
                *rid = r.user_rid;
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /* Set userinfo */
 
 
        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)
 {
                                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 */
 
 
        /* 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 */
        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);
 
        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 */
 
 
        /* Return output parameters */
 
@@ -2006,15 +1504,13 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /* Set userinfo2 */
 
 
        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)
 {
                                 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);
 
        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);
 
        /* 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 */
 
 
        /* Return output parameters */
 
@@ -2060,15 +1547,13 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        }
 
  done:
        }
 
  done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
 
        return result;
 }
 
 /* Delete domain group */
 
 
        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;
                                   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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Delete domain alias */
 
        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;
                                   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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Delete domain user */
 
        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;
                                   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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Remove foreign SID */
 
        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)
                                            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);
 
        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);
 
        /* 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;
 
 
        /* Return output parameters */
 
        result = r.status;
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Query user security object */
 
        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)
 {
                                  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);
 
        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);
 
        /* 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);
 
 
        /* 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 */
 
        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;
                                 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);
 
        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 */
 
        /* 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 */
 
 
        /* 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;
        }
 
                        *unk_1 = r.unk_1;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
 /* Lookup Domain Name */
 
        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)
 {
                                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);
 
        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);
 
        /* 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 */
 
 
        /* 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);
 
        if (NT_STATUS_IS_OK(result))
                sid_copy(sid, &r.dom_sid.sid);
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
        return result;
 }
index c342f255a9fec0e829f6445adbdc29e73c8e16a4..c06586e98abc15acc9a9061b67c4a1fba056c4de 100644 (file)
@@ -3,10 +3,7 @@
    RPC Pipe client
  
    Copyright (C) Andrew Tridgell              1992-1998,
    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
    Copyright (C) Jim McDonough (jmcd@us.ibm.com)   2003.
    
    This program is free software; you can redistribute it and/or modify
 
 /* Shutdown a server */
 
 
 /* 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; 
                           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;
 
        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 */
 
 
        /* 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 */
 
        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; 
                           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;
 
        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 */
 
 
        /* 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 */
 
        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; 
 {
        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;
 
        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 */
 
        /* 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);
 }
        return werror_to_ntstatus(result);
 }
index 271382b71fea51689e0d6240d723570c4d7e9d26..4322bacfc8752739dafa243321b2a740ae8375d4 100644 (file)
@@ -5,8 +5,8 @@
    Copyright (C) Gerald Carter                2001-2005,
    Copyright (C) Tim Potter                   2000-2002,
    Copyright (C) Andrew Tridgell              1994-2000,
    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) 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
 
    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)
 {
                                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 );
 
         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,
                    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;
                                 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 );
 
 
         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,
                    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)
 {
                                 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 );
 
        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,
                    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 );
 
                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,
                            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;
                              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);
 
        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 );
        
         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,
                    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 );
 
                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,
                            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)
 {
                              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 );
        
        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,
                    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 );
 
                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,
                            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)
 {
                              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 );
 
 
        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,
                    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)
                                    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);
 
        ZERO_STRUCT(in);
        ZERO_STRUCT(out);
 
-       fstrcpy(server, cli->desthost);
+       fstrcpy(server, cli->cli->desthost);
        strupper_m(server);
 
        offered = 0;
        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);
 
        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,
                    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);
 
                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,
                            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,
                                       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);
 
        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;
         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);
        
        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,
                    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);
        
                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,
                            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)
                                        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);
 
        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;
         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 );
 
        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,
                    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 );
 
                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,
                            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)
 {
                                     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);
        
        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 );
 
         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,
                    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;
                                 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);
        
        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);
        
         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);
 
        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,
                    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)
 {
                                          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);
 
        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 );
 
        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,
                    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)
 {
                                        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);
 
        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 );
 
         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,
                    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)
                                              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 );
 
        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,
                    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 );
 
                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,
                            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;
                           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 );
        
 
         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,
                    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)
 {
                           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 );
        
 
         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,
                    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)
 {
                           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 );
        
        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,
                    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 );
        
                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,
                            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;
                              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 );
        
 
         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,
                    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)
 {
                             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 );
 
        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,
                    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 );
 
                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,
                            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)
 {
                            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 );
 
        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,
                    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 );
 
                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,
                            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)
 {
                          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 );
 
 
         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,
                    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)
 {
                          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 );
 
        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,
                    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 );
 
                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,
                            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;
                                    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 );
 
 
         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,
                    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;
                                  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 );
 
 
         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,
                    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)
                                   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 );
 
         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,
                    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;
                                  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 );
 
 
         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,
                    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)
 {
                                  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 );
 
        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,
                    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 );
 
                
                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,
                            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)
                                    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 );
 
 
        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,
                    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 );
 
                
                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,
                            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;
                                  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);
 
         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,
                    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)
 {
                                    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);
 
         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,
                    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,
                                   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 );
 
 
         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,
                    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)
 {
                                     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 );
 
        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,
                    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 );
 
                
                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,
                            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)
 {
                                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 );
 
 
         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,
                    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;
                                     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 );
 
 
         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,
                    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)
 {
                                       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 );
 
 
         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,
                    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)
 {
                                  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 );
 
 
        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,
                    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 );
 
                
                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,
                            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;
                                    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 );
 
 
         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,
                    in, out, 
                    qbuf, rbuf,
                    spoolss_io_q_deleteprinterkey,
index d6bcc8ba9c0cecc6de8acbf0493fb2c543f1e0d2..f8098943dbf58b223fa13e7e70beebce2381dde6 100644 (file)
@@ -5,8 +5,8 @@
    Copyright (C) Gerald Carter                2001-2002,
    Copyright (C) Tim Potter                   2000-2002,
    Copyright (C) Andrew Tridgell              1994-2000,
    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) 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
 
    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. */
 
    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)
 {
                                      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 */
 
        
        /* 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 */
 
        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;
 
        /* 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 */
 
        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;
                                       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 */
 
 
        /* 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 */
 
        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;
        /* Return result */
 
        result = r.status;
-       
-done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        return result;
 }
 
@@ -121,7 +102,7 @@ done:
  Also see cli_spolss_reply_rrpcn()
  *********************************************************************/
  
  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;
                                      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 */
 
 
        /* 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 */
 
        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;
 
        /* Return output parameters */
 
        result = r.status;
-
-done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;  
 }
 
        return result;  
 }
 
@@ -165,7 +136,7 @@ done:
  Also see cli_spoolss_routereplyprinter()
  *********************************************************************/
 
  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)
                         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);
 
        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 */
        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 */
 
 
        /* 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"));
 
        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;
                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;
 }
 
 /*********************************************************************
  *********************************************************************/
  
        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)
                            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);
 
        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(
        /* 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 */
 
 
        /* 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;
 
        result = r.status;
-
-done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
        return result;
 }
index b2449a79038e9f1e7a1716ea9f88d4b1ca73bc66..2c71d6b18eaca96ab12b179dc10733862866d5c9 100644 (file)
@@ -2,10 +2,10 @@
    Unix SMB/CIFS implementation.
    NT Domain Authentication SMB / MSRPC client
    Copyright (C) Andrew Tridgell 1994-2000
    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) 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
    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"
 
 
 #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)
 {
                                   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);
        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);
 
 
        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 */
 
        /* 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;
 
        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;
 }
 
        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)
 {
                                 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);
        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);
 
        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 */
 
        /* 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;
 
 
        result = r.status;
 
@@ -215,14 +202,13 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                }
                break;
        }
                }
                break;
        }
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
+
+  done:
 
        return result;
 }
 
 
        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,
                                     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);
        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);
 
 
        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 */
 
        /* 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;
 
 
        result = r.status;
 
@@ -363,14 +345,12 @@ WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
                break;
        }
 
                break;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
+  done:
 
        return result;
 }
 
 
        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,
                                     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);
        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);
 
 
        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 */
 
        /* 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;
 
        result = r.status;
-
-       if (!W_ERROR_IS_OK(result))
-               goto done;
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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);
                                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);
 
 
        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 */
 
        /* 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;
 
        result = r.status;
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;
 }
 
        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, 
                                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);
        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);
 
 
        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 */
 
                                 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;
 
        result = r.status;
-
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
        return result;  
 }
 
        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);
                                 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);
 
 
        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 */
 
        /* 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;
 
        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;  
 }
 
        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)
                                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);
        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);
 
        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 */
 
        /* 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 */
 
                                 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;
 
 
        result = r.status;
 
@@ -625,47 +562,38 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                break;
        }
 
                break;
        }
 
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
-
+  done:
        return result;
 }
 
        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);
                                 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);
 
 
        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 */
 
        /* 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;
 
        result = r.status;
- done:
-       prs_mem_free(&qbuf);
-       prs_mem_free(&rbuf);
        return result;
 }
        return result;
 }
index 9f80bb79a399cfc59bf87af54db6f76b31dad6e8..2df27c2da5b51d2e822ea8739b8fd5e91c2b96e6 100644 (file)
@@ -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;
                               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;
 
        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;
        
        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,
                    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 )
 {
                                 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;
        
        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,
                    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;
 {
        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) );
        
        
        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,
                    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  )
 {
                                       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;
 
        /* 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,
                    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;
 
        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,
                            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;
                                 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) );
        
        
        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,
                    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;
                                 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;
        
        
        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,
                    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;
 
        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,
                            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 );
        
        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;
 }
        
        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 )
 {
                                  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;
        
        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,
                    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 )
 {
                                    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;
        
        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,
                    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;
                                 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;
        
        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,
                    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;
 
        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,
                            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;
 }
        
        return out.status;
 }
-
index aea474439887d78190271fe8cc73771509568b82..d8e97beb6493e9cbb00332d83eaa98293cce5f33 100644 (file)
@@ -2,10 +2,10 @@
    Unix SMB/CIFS implementation.
    NT Domain Authentication SMB / MSRPC client
    Copyright (C) Andrew Tridgell 1994-2000
    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) 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
    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
  * @return NTSTATUS of rpc call
  */
  
  * @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)
 {
                            WKS_INFO_100 *wks100)
 {
-       prs_struct buf;
+       prs_struct qbuf;
        prs_struct rbuf;
        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;
 
 
        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 */
        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 */
        /* check returnet status code */
-       if (NT_STATUS_IS_ERR(r_o.status)) {
+       if (NT_STATUS_IS_ERR(r.status)) {
                /* report the error */
                /* 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;
 }
        return NT_STATUS_OK;
 }
-
index ff2a7cc2f6e456e5c6cc038f89a4b2cbb805bb59..36d8eda8474685bc4d3b8f75ff86842f47c9a0f0 100644 (file)
@@ -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 */
 
 
        /* 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;
 
        if ( !prs_uint32("ptr", ps, depth, &data_p ))
                return False;
index 3f7b2a4cd59f279f0d976addfa369f500a4d6659..f102e950042be73287d1299458561c45bf33d873 100644 (file)
@@ -22,8 +22,6 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-#include "nterr.h"
-#include "rpc_parse.h"   
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
index 9155419ae438848b59ab9fb0e9ef844719f2a3fe..c6131452226bb433a58fb7c90f753ec72d6b11a0 100644 (file)
 /************************************************************************
 ************************************************************************/
 
 /************************************************************************
 ************************************************************************/
 
-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;
        
 {
        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);
                p = *basic = PRS_ALLOC_MEM(ps, DSROLE_PRIMARY_DOMAIN_INFO_BASIC, 1);
+       }
                
        if ( !p )
                return False;
                
        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++;
 {
        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++;
 {
        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:
                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:
                                        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
 ************************************************************************/
 
  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;
        
 {
        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++;
 {
        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;
 
 {
        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++ ) {
           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;
        }
 
                        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
 ************************************************************************/
 
  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++;
 {
        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++;
 {
        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 ) {
                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;
        }
                
                        return False;
        }
                
@@ -298,5 +298,3 @@ BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS
                
        return True;
 }
                
        return True;
 }
-
-
index b4aa8de24ab9a78c2168e1473efb179f57bf23e9..48dda7b17152b8504eea79e10c5237d674696d27 100644 (file)
@@ -21,8 +21,6 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-#include "nterr.h"
-#include "rpc_parse.h"   
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
index 734f52fffb37f8ac0552417ce2f04f718b2f5c3b..1b57272ca4c85c8f75bed6d00bf163865d5310d3 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
 #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)
 
 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;
     
        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;
 
        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;
 
                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;
                return False;
-       if(!prs_uint32("sourcename_ptr", ps, depth, &q_u->sourcename_ptr))
+       if ( !prs_align(ps) )
                return False;
                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;
                return False;
-       if(!prs_align(ps))
+       if ( !prs_align(ps) )
                return False;
 
                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;
                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;
                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;
                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;
                return False;
 
        return True;
index 921e366f11a9dcf3f7bc8cc6bf8528a0ce8b2bd0..8bbb97f226db7119a1c0bcf81f2b3c3d40127a32 100644 (file)
@@ -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 */
 
 
        /* 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;
 
        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 */
 
 
        /* 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;
 
        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) */
 
        /* 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 )
 ********************************************************************/
 
 BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
index 3a050148c9f7ed2ad200ef67c5e19423e3d82542..35533e360a1ed5fe3defd36cec672b59f246a289 100644 (file)
@@ -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,
 
 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__));
 
 {
        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,
 
 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__));
 
 {
        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, 
 ********************************************************************/
 
 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;
 
 {
        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 */
        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;
 
 
                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;
                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(!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;
 
        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 */
                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) {
                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
                        return False;
        }
 #endif
@@ -2139,9 +2158,8 @@ BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 /*******************************************************************
 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;
 {
        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 (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, 
                                         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 (!ps->io)
                        {
                                /* writing */
-                                if (!prs_hash1(ps, old_offset, sess_key, len))
+                                if (!prs_hash1(ps, old_offset, len))
                                         return False;
                        }
                }
                                         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.
 ********************************************************************/
 /*******************************************************************
 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)
 {
                                 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:
                        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;
 
                                 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.
 ********************************************************************/
 /*******************************************************************
 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;
                       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(
                        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));
                                         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.
 ********************************************************************/
 /*******************************************************************
 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;
                          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(
                        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))
                                         &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 (file)
index 0000000..f2e4456
--- /dev/null
@@ -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;
+}
+
+
+
+
index 709a5d39af6c3f78178c45baebd0a5727adfe662..d174bad444d7714e181088ecd3e29aae812880bf 100644 (file)
@@ -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);
 }
 
        prs_dump_region(name, v, ps, ps->data_offset, ps->buffer_size);
 }
 
-
 /**
  * Dump from the start of the prs to the current location.
  **/
 /**
  * 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);
 }
 
        prs_dump_region(name, v, ps, 0, ps->data_offset);
 }
 
-
 /**
  * Dump everything from the start of the prs up to the current location.
  **/
 /**
  * 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;
 {
        int fd, i;
        pstring fname;
+       ssize_t sz;
        if (DEBUGLEVEL < 50) return;
        for (i=1;i<100;i++) {
                if (v != -1) {
        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) {
                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));
 }
 
 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.
  *
 /**
  * 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.
  **/
  *
  * @return False if allocation fails, otherwise True.
  **/
+
 BOOL prs_init(prs_struct *ps, uint32 size, TALLOC_CTX *ctx, BOOL io)
 {
        ZERO_STRUCTP(ps);
 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. */
                }
                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;
        }
 
        return True;
@@ -254,7 +259,7 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space)
                 * is greater.
                 */
 
                 * 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));
 
                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.
  ********************************************************************/
 
  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;
 {
        if (len == 0)
                return True;
@@ -564,6 +569,15 @@ void prs_force_dynamic(prs_struct *ps)
        ps->is_dynamic=True;
 }
 
        ps->is_dynamic=True;
 }
 
+/*******************************************************************
+ 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.
  ********************************************************************/
 /*******************************************************************
  Stream a uint8.
  ********************************************************************/
@@ -596,9 +610,9 @@ BOOL prs_pointer( const char *name, prs_struct *ps, int depth,
 {
        uint32 data_p;
 
 {
        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;
 
        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.
  ********************************************************************/
 
  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;
 
 {
        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"));
 
 #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
        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);
 
 #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.
  ********************************************************************/
 
  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]) 
 {
                          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));
           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);
                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 
  ********************************************************************/
 
  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];
                                   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)
  ********************************************************************/
 
  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];
 {
        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])
                              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.
  ********************************************************************/
 
  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];
                   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];
 
        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 */
        }
 
        /* 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));
 
 
        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) */
                                 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));
 
        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 */
                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));
 
                /* 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... */
        /* 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;
 }
 
 /*******************************************************************
 
        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
  ********************************************************************/
 
  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];
 
 {
        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];
 
 
        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 */
        }
 
        /* Create the expected sequence number for comparison */
@@ -1630,7 +1644,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
                break;
        }
 
                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));
        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... */
        /* 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 */
 
        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
                */
                   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));
                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;
        }
 
                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 */
                /* 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*)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;
        }
 
                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 */
                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, 
 
                /* 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 */
        }
 
        /* 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));
 
        dump_data_pw("Calculated digest:\n", digest_final, 
                     sizeof(digest_final));
index be452033fe2c3a8792bc9982024477e6c1c41e8c..295fead103566195d23948c4c840c97d6b3bf191 100644 (file)
@@ -33,7 +33,7 @@
  Fill in a REGVAL_BUFFER for the data given a REGISTRY_VALUE
  *******************************************************************/
 
  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;
        
 {
        uint32          real_size = 0;
        
index ce081b92e834464c2261d96eef1bdc1b2afc6b17..ea4ec2c8639d33526a67cfa83e0ef0cdbae89343 100644 (file)
@@ -191,6 +191,26 @@ interface/version dce/rpc pipe identification
        }, 0x00                             \
 }
 
        }, 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.
 /*
  * 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_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  }
 };
 
        { 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.
 ********************************************************************/
 /*******************************************************************
  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)
 {
                                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;
        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_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;
                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;
                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;
 }
 
        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.
 ********************************************************************/
 /*******************************************************************
  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;
 
 {
        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)))
        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;
                              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_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))
        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_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)) )
        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 ( !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;
        }
                if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) )
                        return False;
        }
index 6b0193c6e46e58a402c000b58b8541c1185e09e6..1aaebf71e39cefb8cc2d9dedbd653db00cfc1e18 100644 (file)
@@ -25,8 +25,6 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-#include "rpc_parse.h"
-#include "nterr.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
 #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,
 
 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 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"));
                                const uchar lm_oldhash[16])
 {
        DEBUG(5, ("init_samr_q_chgpasswd_user\n"));
index b86ca23df158a4290234abad05bf1ef01f1205c5..e1a7ad84273a33709c0f189eb3f6aaf90fbf22d5 100644 (file)
@@ -100,40 +100,48 @@ static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config,
 
        return True;
 }
 
        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++;
        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;
 
                return False;
 
+       if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) )
+               return False;
+       
        return True;
 }
 
        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_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++;
        depth++;
-       
-       if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) )
+
+       if ( !svcctl_io_service_status("status", &status->status, ps, depth) )
                return False;
                return False;
-       if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) )
+       if(!prs_align(ps))
                return False;
 
                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;
                return False;
-       
+       if(!prs_uint32("service_flags", ps, depth, &status->service_flags))
+               return False;
+
        return True;
 }
 
        return True;
 }
 
@@ -151,6 +159,45 @@ uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status )
        return size;
 }
 
        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(!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))
                return False;
 
        if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
@@ -705,36 +752,145 @@ 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;
+}
+
+
 /*******************************************************************
 ********************************************************************/
 
 /*******************************************************************
 ********************************************************************/
 
@@ -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(!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))
                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");
                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;
 
        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;
 
 {
        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;
 
        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;
 
                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))
                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_
 }
 
 
 }
 
 
+
+
index 65b10e8fe40dcc93b89222614139ef4f1ca2aa67..ae15d43f4bab2d108d751b98eafd40c7b8c68a99 100644 (file)
@@ -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;
 {
        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;
 
        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;
 {
        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;
 
        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;
 {
        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;
 
        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;
 {
        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;
 
        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;
 {
        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;
 
        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;
 {
        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;
 
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
 
index a9b0c9bed80fca291d7bf5e1077d532748d31bdb..414c99d28e2bcc0ec292845d6cbf3f245819d3af 100644 (file)
@@ -1,7 +1,8 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
 /* 
  *  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
  *  
  *  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
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
 #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)
 {
 
 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
  * 
 /**
  * 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.
  */
  *     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
  * 
 /**
  * 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.
  */
  *     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
  * 
 /**
  * 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
  */
  *             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
  * 
 /**
  * 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.
  */
  *     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;
-    }
-    return True;
 }
 }
+
+/********************************************************************
+********************************************************************/
+
 /**
  * Callout to read entries from the specified event log
  *
 /**
  * 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 
  */
  *               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);*/
 
 /*    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)
 {
                                                    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
  *
 /**
  * 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
  */
  *             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].",
        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;
+}
+
index 68072b528aaac439872014e4fd31796e59e34b40..7da87d5b93d028e6429d6cba07519f187055449f 100644 (file)
@@ -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 */
                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;
                        return True;
+               }
 
                if (!user) {
                        DEBUG(3, ("invalid vuid %d\n", p->vuid));
                        return False;
                }
 
 
                if (!user) {
                        DEBUG(3, ("invalid vuid %d\n", p->vuid));
                        return False;
                }
 
-               if (user->guest)
+               if (user->guest) {
                        return False;
                        return False;
+               }
        }
 
        return True;
        }
 
        return True;
index 021f1dc8e0f286e250c15c6e84ca0a3496c43389..15d420538ef11d8f957f44b5c2864d96e03da523 100644 (file)
@@ -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;
        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 */
 
        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;
                
        if ( enum_context >= num_privs )
                return NT_STATUS_NO_MORE_ENTRIES;
                
index 15827a8b55e4eec0e2eda6a8b2b83a93e4f9b6a8..5aefe3ca3c977d717d1615afed370b29925178ce 100644 (file)
@@ -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
 **************************************************************************/
 /****************************************************************************
 Send a message to smbd to do a sam synchronisation
 **************************************************************************/
+
 static void send_sync_message(void)
 {
         TDB_CONTEXT *tdb;
 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 _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 */
        /* 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 _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 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 */
        /* 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;
 }
 
        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 _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;
        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. */
 
        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) {
        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 */
        }
 
        /* 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;
 }
 
        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;
 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;
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret = False;
        unsigned char pwd[16];
        int i;
        uint32 acct_ctrl;
+       DOM_CRED cred_out;
        const uchar *old_pw;
 
        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;
                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(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();
        
        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. */
        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;
        }
 
                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++)
 
        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 */
        } 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;
                }
                
                        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;
                }
                
                        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; 
                        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();
        }
                ret = pdb_update_sam_account (sampass);
                unbecome_root();
        }
-       if (ret)
+       if (ret) {
                status = NT_STATUS_OK;
                status = NT_STATUS_OK;
+       }
 
        /* set up the LSA Server Password Set response */
 
        /* 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;
 }
 
 
        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)
 {
 /*************************************************************************
  _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;
 
        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;
                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 */
        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;
 }
 
        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;
        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;
        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->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 (!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. */
                /* '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 */
                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 */
     
 
        /* 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, 
                                                         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;
                        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);
                }
 
                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));
                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 (file)
index 0000000..48910db
--- /dev/null
@@ -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 (file)
index 0000000..0bb9154
--- /dev/null
@@ -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;
+}
+
index 63e8d2f5cdaed21fe409372ae03a5de0cd6fbce7..ba6d9704e808375ef8c62fb685390bcabd548cf0 100644 (file)
@@ -1,11 +1,7 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
 /* 
  *  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
  *  
  *  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
  *  and DCE/RPC, while minimising the amount of mallocs, unnecessary
  *  data copies, and network traffic.
  *
  *  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"
  */
 
 #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.
 **************************************************************/
  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;
 
 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. 
 }
 
 /*******************************************************************
  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;
 {
        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 ss_padding_len = 0;
-       uint32 data_len;
        uint32 data_space_available;
        uint32 data_len_left;
        uint32 data_space_available;
        uint32 data_len_left;
+       uint32 data_len;
        prs_struct outgoing_pdu;
        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
 
        /*
         * 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.
         */
 
         * 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;
 
        /*
        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) {
         */
 
        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;
        }
 
                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);
 
        /*
        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(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);
                        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 ));
                }
        }
                                ss_padding_len ));
                }
        }
@@ -173,20 +145,11 @@ BOOL create_next_pdu(pipes_struct *p)
         * Set up the header lengths.
         */
 
         * Set up the header lengths.
         */
 
-       if (p->ntlmssp_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 +
                        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 +
-                       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
 
        /*
         * Init the parse struct to point at the outgoing
@@ -198,127 +161,105 @@ 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)) {
 
        /* 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)) {
                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;
        }
 
                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)) {
        /* 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) {
                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)) {
                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;
                }
        }
 
                        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;
                        }
                                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;
                        }
                                prs_mem_free(&outgoing_pdu);
                                return False;
                        }
-                       NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
-               }
-       } else if (p->netsec_auth_validated) {
-               /*
-                * Schannel processing. Mutually exclusive with NTLMSSP.
-                */
-               int auth_type, auth_level;
-               char *data;
-               RPC_HDR_AUTH auth_info;
-
-               RPC_AUTH_NETSEC_CHK verf;
-               prs_struct rverf;
-               prs_struct rauth;
-
-               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);
-
-               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"));
+                       break;
+               default:
                        prs_mem_free(&outgoing_pdu);
                        return False;
                        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,
-                             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);
+       }
 
 
-               p->netsec_auth.seq_num++;
+       /* 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.
         */
        /*
         * Setup the counts for this PDU.
         */
@@ -332,292 +273,501 @@ 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. 
+ Return an schannel authenticated fragment.
+ ********************************************************************/
 
 
-static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
+static BOOL create_next_pdu_schannel(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 ss_padding_len = 0;
+       uint32 data_len;
+       uint32 data_space_available;
+       uint32 data_len_left;
+       prs_struct outgoing_pdu;
+       uint32 data_pos;
 
 
-       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_schannel: 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 -
+                                       RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_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);
-
-       memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
-       memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);
+       /*
+        * The amount we send is the minimum of the available
+        * space and the amount left to send.
+        */
 
 
-#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
+       data_len = MIN(data_len_left, data_space_available);
 
        /*
 
        /*
-        * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
+        * Set up the alloc hint. This should be the data left to
+        * send.
         */
 
         */
 
-       if (*user_name) {
-
-               /* 
-                * Do the length checking only if user is not NULL.
-                */
+       hdr_resp.alloc_hint = data_len_left;
 
 
-               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;
+       /*
+        * 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 ));
+               }
        }
        }
-       
-       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"));
-               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);
-               return False;
-       }
+       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;
 
        /*
 
        /*
-        * Set up the sign/seal data.
+        * Init the parse struct to point at the outgoing
+        * data.
         */
 
         */
 
-       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;
-
-                       unsigned char k2[8];
+       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);
 
 
-                       memcpy(k2, p24, 5);
-                       k2[5] = 0xe5;
-                       k2[6] = 0x38;
-                       k2[7] = 0xb0;
+       /* 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;
+       }
 
 
-                       for (ind = 0; ind < 256; ind++)
-                               p->ntlmssp_hash[ind] = (unsigned char)ind;
+       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;
+       }
 
 
-                       for( ind = 0; ind < 256; ind++) {
-                               unsigned char tc;
+       /* Store the current offset. */
+       data_pos = prs_offset(&outgoing_pdu);
 
 
-                               j += (p->ntlmssp_hash[ind] + k2[ind%8]);
+       /* Copy the data into the PDU. */
 
 
-                               tc = p->ntlmssp_hash[ind];
-                               p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
-                               p->ntlmssp_hash[j] = tc;
-                       }
+       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;
+       }
 
 
-                       p->ntlmssp_hash[256] = 0;
-                       p->ntlmssp_hash[257] = 0;
+       /* 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;
                }
                }
+       }
 
 
-               dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash, 
-                            sizeof(p->ntlmssp_hash));
-
-/*             NTLMSSPhash(p->ntlmssp_hash, p24); */
-               p->ntlmssp_seq_num = 0;
+       {
+               /*
+                * Schannel processing.
+                */
+               char *data;
+               RPC_HDR_AUTH auth_info;
+               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 */
 
 
-       fstrcpy(p->user_name, user_name);
-       fstrcpy(p->pipe_user_name, server_info->unix_name);
-       fstrcpy(p->domain, domain);
-       fstrcpy(p->wks, wks);
+               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);
 
 
-       /*
-        * Store the UNIX credential data (uid/gid pair) in the pipe structure.
-        */
+               if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
+                       DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_AUTH.\n"));
+                       prs_mem_free(&outgoing_pdu);
+                       return False;
+               }
 
 
-       if (p->session_key.data) {
-               data_blob_free(&p->session_key);
-       }
-       p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length);
+               schannel_encode(p->auth.a_u.schannel_auth, 
+                             p->auth.auth_level,
+                             SENDER_IS_ACCEPTOR,
+                             &verf, data, data_len + ss_padding_len);
 
 
-       p->pipe_user.uid = server_info->uid;
-       p->pipe_user.gid = server_info->gid;
-       
-       p->pipe_user.ngroups = 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))) {
-                       DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
-                       free_server_info(&server_info);
+               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;
                }
                        return False;
                }
-       }
 
 
-       if (server_info->ptok)
-               p->pipe_user.nt_user_token = dup_nt_token(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->auth.a_u.schannel_auth->seq_num++;
        }
 
        }
 
-       p->ntlmssp_auth_validated = True;
+       /*
+        * 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;
 
 
-       free_server_info(&server_info);
+       prs_mem_free(&outgoing_pdu);
        return True;
 }
 
 /*******************************************************************
        return True;
 }
 
 /*******************************************************************
- The switch table for the pipe names and the functions to handle them.
- *******************************************************************/
+ Generate the next PDU to be returned from the data in p->rdata. 
+ No authentication done.
+********************************************************************/
 
 
-struct rpc_table
+static BOOL create_next_pdu_noauth(pipes_struct *p)
 {
 {
-  struct
-  {
-    const char *clnt;
-    const char *srv;
-  } pipe;
-  struct api_struct *cmds;
-  int n_cmds;
-};
+       RPC_HDR_RESP hdr_resp;
+       uint32 data_len;
+       uint32 data_space_available;
+       uint32 data_len_left;
+       prs_struct outgoing_pdu;
 
 
-static struct rpc_table *rpc_lookup;
-static int rpc_lookup_size;
+       /*
+        * If we're in the fault state, keep returning fault PDU's until
+        * the pipe gets closed. JRA.
+        */
 
 
-/*******************************************************************
- This is the client reply to our challenge for an authenticated 
- bind request. The challenge we sent is in p->challenge.
-*******************************************************************/
+       if(p->fault_state) {
+               setup_fault_pdu(p, NT_STATUS(0x1c010002));
+               return True;
+       }
 
 
-BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
-{
-       RPC_HDR_AUTHA autha_info;
-       RPC_AUTH_VERIFIER auth_verifier;
-       RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+       memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
 
 
-       DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+       /* Change the incoming request header to a response. */
+       p->hdr.pkt_type = RPC_RESPONSE;
 
 
-       if (p->hdr.auth_len == 0) {
-               DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
-               return False;
+       /* Set up rpc header flags. */
+       if (p->out_data.data_sent_length == 0) {
+               p->hdr.flags = RPC_FLG_FIRST;
+       } else {
+               p->hdr.flags = 0;
        }
 
        /*
        }
 
        /*
-        * Decode the authentication verifier response.
+        * 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_noath: no data left to send !\n"));
+               return False;
+       }
+
+       data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_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(!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"));
+       if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
+               p->hdr.flags |= RPC_FLG_LAST;
+       }
+
+       /*
+        * Set up the header lengths.
+        */
+
+       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;
        }
 
                return False;
        }
 
-       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(!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;
        }
 
                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"));
+       /* 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;
        }
 
        /*
                return False;
        }
 
        /*
-        * Ensure this is a NTLMSSP_AUTH packet type.
+        * Setup the counts for this PDU.
         */
 
         */
 
-       if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
-               DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
+       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. 
+********************************************************************/
+
+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;
+                       }
+       }
+
+       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;
+}
+
+/*******************************************************************
+ 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.
+*******************************************************************/
+
+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;
+
+       DEBUG(5,("pipe_ntlmssp_verify_final: checking user details\n"));
+
+       ZERO_STRUCT(reply);
+
+       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;
        }
 
                return False;
        }
 
-       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"));
+       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.
+        */
+
+       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;
        }
 
                return False;
        }
 
+       p->pipe_user.ngroups = a->server_info->n_groups;
+       if (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"));
+                       return False;
+               }
+       }
+
+       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;
+               return False;
+       }
+
+       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;
+};
+
+static struct rpc_table *rpc_lookup;
+static int rpc_lookup_size;
+
+/*******************************************************************
+ This is the "stage3" NTLMSSP response after a bind request and reply.
+*******************************************************************/
+
+BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p)
+{
+       RPC_HDR_AUTH auth_info;
+       uint32 pad;
+       DATA_BLOB blob;
+
+       ZERO_STRUCT(blob);
+
+       DEBUG(5,("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
+
+       if (p->hdr.auth_len == 0) {
+               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_auth("", &auth_info, rpc_in_p, 0)) {
+               DEBUG(0,("api_pipe_bind_auth3: unmarshall of RPC_HDR_AUTH failed.\n"));
+               goto err;
+       }
+
+       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;
+       }
+
+       blob = data_blob(NULL,p->hdr.auth_len);
+
+       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;
+       }
+
        /*
         * The following call actually checks the challenge/response data.
         * for correctness against the given DOMAIN\user name.
         */
        
        /*
         * The following call actually checks the challenge/response data.
         * 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;
        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);
 
        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,
        /*
         * 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.
 
        /*
         * 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;
 
        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;
        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 */
                
 
        /* 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)
                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;
                        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 False;
+       }
 
        return True;
 }
 
        return True;
 }
@@ -809,6 +962,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
 /*******************************************************************
  Register commands to an RPC pipe
 *******************************************************************/
 /*******************************************************************
  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;
 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;
@@ -856,6 +1010,365 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s
         return NT_STATUS_OK;
 }
 
         return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ 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.
 *******************************************************************/
 /*******************************************************************
  Respond to a pipe bind request.
 *******************************************************************/
@@ -872,162 +1385,280 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
        prs_struct outgoing_rpc;
        int i = 0;
        int auth_len = 0;
        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);
+       }
 
 
-       p->ntlmssp_auth_requested = False;
-       p->netsec_auth_validated = False;
+       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);
+
+       /*
+        * 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__));
 
        /*
 
        DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
 
        /*
-        * Try and find the correct pipe name to ensure
-        * that this is a pipe name we support.
+        * Try and find the correct pipe name to ensure
+        * that this is a pipe name we support.
+        */
+
+
+       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;
+               }
+       }
+
+       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 ));
+                       prs_mem_free(&outgoing_rpc);
+                       prs_mem_free(&out_hdr_ba);
+                       prs_mem_free(&out_auth);
+
+                       return setup_bind_nak(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;
+                       }
+                }
+
+               if (i == rpc_lookup_size) {
+                       DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
+                       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"));
+               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 bind request.
+        */
+
+       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"));
+                       goto err_exit;
+               }
+
+               auth_type = auth_info.auth_type;
+
+               /* 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);
+       }
+
+       assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
+
+       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;
+
+               case RPC_SCHANNEL_AUTH_TYPE:
+                       if (!pipe_schannel_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) {
+                               goto err_exit;
+                       }
+                       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 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;
+
+               default:
+                       DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type ));
+                       goto err_exit;
+       }
+
+       /*
+        * Create the bind response struct.
+        */
+
+       /* 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 */
+
+       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;
+       }
+
+       /*
+        * and marshall it.
         */
 
         */
 
-
-       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;
-                }
+       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;
        }
 
        }
 
-       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 ));
-                       return setup_bind_nak(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;
-                       }
-                }
+       /*
+        * Create the header, now we know the length.
+        */
 
 
-               if (i == rpc_lookup_size) {
-                       DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
-                       return False;
-               }
+       if (prs_offset(&out_auth)) {
+               auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
        }
 
        }
 
-       /* 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);
-       }
+       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);
 
        /*
 
        /*
-        * Check if this is an authenticated request.
+        * Marshall the header into the outgoing PDU.
         */
 
         */
 
-       if (p->hdr.auth_len != 0) {
-               RPC_AUTH_VERIFIER auth_verifier;
-               RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
-
-               /* 
-                * 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);
-               }
-
-               switch(auth_info.auth_type) {
-                       case NTLMSSP_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);
-                               }
-
-                               if(!strequal(auth_verifier.signature, "NTLMSSP")) {
-                                       DEBUG(0,("api_pipe_bind_req: "
-                                                "auth_verifier.signature != NTLMSSP\n"));
-                                       return setup_bind_nak(p);
-                               }
-
-                               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);
-                               }
+       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;
+       }
 
 
-                               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);
-                               }
+       /*
+        * Now add the RPC_HDR_BA and any auth needed.
+        */
 
 
-                               p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
-                               p->ntlmssp_auth_requested = True;
-                               break;
+       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;
+       }
 
 
-                       case NETSEC_AUTH_TYPE:
-                       {
-                               RPC_AUTH_NETSEC_NEG neg;
-                               struct netsec_auth_struct *a = &(p->netsec_auth);
+       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;
+       }
 
 
-                               if (!server_auth2_negotiated) {
-                                       DEBUG(0, ("Attempt to bind using schannel "
-                                                 "without successful serverauth2\n"));
-                                       return setup_bind_nak(p);
-                               }
+       /*
+        * Setup the lengths for the initial reply.
+        */
 
 
-                               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);
-                               }
+       p->out_data.data_sent_length = 0;
+       p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
+       p->out_data.current_pdu_sent = 0;
 
 
-                               p->netsec_auth_validated = True;
+       prs_mem_free(&out_hdr_ba);
+       prs_mem_free(&out_auth);
 
 
-                               memset(a->sess_key, 0, sizeof(a->sess_key));
-                               memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
+       return True;
 
 
-                               a->seq_num = 0;
+  err_exit:
 
 
-                               DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
-                                         neg.domain, neg.myname));
-                               break;
-                       }
+       prs_mem_free(&outgoing_rpc);
+       prs_mem_free(&out_hdr_ba);
+       prs_mem_free(&out_auth);
+       return setup_bind_nak(p);
+}
 
 
-                       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);
-               }
-       }
+/****************************************************************************
+ Deal with an alter context call. Can be third part of 3 leg auth request for
+ SPNEGO calls.
+****************************************************************************/
 
 
-       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;
-       }
+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;
 
 
-       DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
+       prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
 
        /* 
         * Marshall directly into the outgoing PDU space. We
 
        /* 
         * 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.
         */
 
         * 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);
 
        /*
        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)) {
         */
 
        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)) {
                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;
        }
 
                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.
 
        /*
         * 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,
        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,
                        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 */
                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);
                                        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)) {
         */
 
        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;
        }
 
        /*
                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;
        }
 
                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);
                        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)) {
         */
 
        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;
        }
 
                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)) {
         */
 
        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;
        }
 
                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;
        }
 
                goto err_exit;
        }
 
-       if(!p->ntlmssp_auth_requested)
-               p->pipe_bound = True;
-
        /*
         * Setup the lengths for the initial reply.
         */
        /*
         * 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);
        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;
        }
 
        /*
                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 False;
-               }
        }
 
        /*
         * Return the current pointer to the data offset.
         */
 
        }
 
        /*
         * 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",
                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;
        }
 
                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.
 ****************************************************************************/
        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_HDR_AUTH auth_info;
-       RPC_AUTH_NETSEC_CHK netsec_chk;
-
+       RPC_AUTH_SCHANNEL_CHK schannel_chk;
 
        auth_len = p->hdr.auth_len;
 
 
        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;
        }
 
                return False;
        }
 
@@ -1364,16 +1974,21 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
         * preceeding the auth_data.
         */
 
         * 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));
 
        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",
                DEBUG(0,("cannot move offset to %u.\n",
-                        (unsigned int)old_offset + data_len ));
+                        (unsigned int)RPC_HDR_REQ_LEN + data_len ));
                return False;
        }
 
                return False;
        }
 
@@ -1382,34 +1997,22 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
                return False;
        }
 
                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;
        }
 
                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;
        }
 
                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,
                           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;
        }
                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.
         */
 
         * 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",
                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. */
                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;
 }
 
        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)
 {
 
 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));
                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 )
 ****************************************************************************/
 
 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 api_pipe_request(pipes_struct *p)
 {
        BOOL ret = False;
+       BOOL changed_user = False;
        PIPE_RPC_FNS *pipe_fns;
        
        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;
                }
                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));
        }
 
        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));
        }
 
                        p->hdr_req.context_id, p->name));
        }
 
-       if(p->ntlmssp_auth_validated)
+       if (changed_user) {
                unbecome_authenticated_pipe_user();
                unbecome_authenticated_pipe_user();
+       }
 
        return ret;
 }
 
        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_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 );
 #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;
 }
 
        return;
 }
-
-
index 83b78f8d2f6de89665466a30a33324aa59c9eee4..205223190b442191c854874d0ccf1c814b7d781b 100644 (file)
@@ -2,8 +2,8 @@
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1998,
  *  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
  *  
  *  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)
 {
 
 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);
 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");
                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.
         */     
         * 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;
        }
                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));
 
        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;
                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",
  
        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 */
        /* 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;
                next_pipe = (sys_getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
+       }
 
        i = bitmap_find(bmap, next_pipe);
 
 
        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;
 
 
        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));  
                DEBUG(5,("open_rpc_pipe_p: name %s pnum=%x\n", p->name, p->pnum));  
+       }
 
        p = SMB_MALLOC_P(smb_np_struct);
        if (!p) {
 
        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 */ 
        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));  
                DEBUG(5,("open pipes: name %s pnum=%x\n", p_it->name, p_it->pnum));  
+       }
 
        return chain_p;
 }
 
        return chain_p;
 }
@@ -297,9 +304,17 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
                return NULL;
        }
 
                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);
        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;
        }
                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.
         */
 
         * 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"));
                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;
        }
 
                return NULL;
        }
 
@@ -325,12 +342,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
 
        p->vuid  = vuid;
 
 
        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);
        p->endian = RPC_LITTLE_ENDIAN;
 
        ZERO_STRUCT(p->pipe_user);
@@ -344,21 +355,6 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
                p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token);
        }
 
                p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token);
        }
 
-       /*
-        * 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.
         */     
        /*
         * Initialize the outgoing RPC data buffer with no memory.
         */     
@@ -504,7 +500,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
         * Ensure that the pdu length is sane.
         */
 
         * 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);
                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 ));
 
        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;
 
        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. */
        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 "
 {
        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);
                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;
                        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)
 {
 
 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 -
        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"));
 
        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;
        }
 
                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.
                 */
 
                 * 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;
                        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);
 
 
                free_pipe_context(p);
 
-               if(pipe_init_outgoing_data(p))
+               if(pipe_init_outgoing_data(p)) {
                        ret = api_pipe_request(p);
                        ret = api_pipe_request(p);
+               }
 
                free_pipe_context(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.
 ****************************************************************************/
 
  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;
 {
        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) {
        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));
                        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);
        }
 
        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:
 
        switch (p->hdr.pkt_type) {
                case RPC_BIND:
-               case RPC_ALTCONT:
                        /*
                         * We assume that a pipe bind is only in one pdu.
                         */
                        /*
                         * 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);
                                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;
                        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);
                        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);
        }
 
        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)
 {
 
 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,
 
        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.
         */
 
         * 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);
                return unmarshall_rpc_header(p);
+       }
 
        /*
         * Ok - at this point we have a valid RPC_HEADER in p->hdr.
 
        /*
         * 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.
 
        /*
         * 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;
         */
 
        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 ?
 
        /*
         * 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;
 
        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 ));
 
 
                DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
 
-               if(data_used < 0)
+               if(data_used < 0) {
                        return -1;
                        return -1;
+               }
 
                data_left -= data_used;
                data += data_used;
 
                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.
         */
 
         * 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 \
                 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)
 {
 
 BOOL wait_rpc_pipe_hnd_state(smb_np_struct *p, uint16 priority)
 {
-       if (p == NULL)
+       if (p == NULL) {
                return False;
                return False;
+       }
 
        if (p->open) {
                DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
 
        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)
 {
 
 BOOL set_rpc_pipe_hnd_state(smb_np_struct *p, uint16 device_state)
 {
-       if (p == NULL)
+       if (p == NULL) {
                return False;
                return False;
+       }
 
        if (p->open) {
                DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
 
        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);
 
        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);
                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. */
        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);
 
 {
        int pnum = SVAL(buf,where);
 
-       if (chain_p)
+       if (chain_p) {
                return chain_p;
                return chain_p;
+       }
 
        return get_rpc_pipe(pnum);
 }
 
        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));
 
 
        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));  
                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) {
 
        for (p=Pipes;p;p=p->next) {
                if (p->pnum == pnum) {
index 871b1a9f121c01ce9e5aaee68efb4860429f8ed8..17725240387f3d7c394c91ed9b272f06da078368 100644 (file)
@@ -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;
 
        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))
        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)
 {
 
 static BOOL api_reg_save_key(pipes_struct *p)
 {
@@ -416,6 +416,57 @@ static BOOL api_reg_save_key(pipes_struct *p)
        return True;
 }
 
        return True;
 }
 
+/*******************************************************************
+ 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;
+}
+
 /*******************************************************************
  ******************************************************************/
 
 /*******************************************************************
  ******************************************************************/
 
@@ -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_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       },
       { "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       },
index a405948864b8eae8b1794d1fbd4798ef0e069332..4db5ed0ed6227df9fb0d64bb3f6b005f9acade0f 100644 (file)
 #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())
 
 #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
 
 /******************************************************************
  free() function for REGISTRY_KEY
@@ -96,9 +43,7 @@ SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
  
 static void free_regkey_info(void *ptr)
 {
  
 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>\...
  *******************************************************************/
  
  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;
        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; 
                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;
 }
 
        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)
 {
 
 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)
 {
 
 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);
 {
        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;
 
        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? */
 
        
        /* 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;
        
                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));
                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);
 
        
        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;
        
 
        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));
                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 );
                }
                
                free_registry_value( val );
+           }
        }
 
        init_reg_r_query_value(q_u->ptr_buf, r_u, val, status);
        }
 
        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;
 }
 
        return status;
 }
 
-
 /*****************************************************************************
  Implementation of REG_QUERY_KEY
  ****************************************************************************/
 /*****************************************************************************
  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;
        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 */
 
 
        /* 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);
 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;
        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;
        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. 
                
                /* (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';
 
                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;
                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) */
 
 
                /* 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 */
        }
        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 */
        
                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;
        }       
                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 */
        
 
        /* (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 */
        
        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 );
 
        
        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 
                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 */
        
 
 done:
        /* close any intermediate key handles */
        
-       if ( newparent != parent )
+       if ( newparentinfo != parent )
                close_registry_key( p, &newparent_handle );
                
        return result;
                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);
 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;
        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;
 
        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 );
                
                
        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;
        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( 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;
                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 */
        }
        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;
        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 */
        
        
        /* 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 */
        
        
        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 );
 
        
        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 */
        
 done:
        /* close any intermediate key handles */
        
-       if ( newparent != parent )
+       if ( newparentinfo != parent )
                close_registry_key( p, &newparent_handle );
 
        return result;
                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;
 }
                
        return WERR_ACCESS_DENIED;
 }
-
-
index 656241a73f9aadd8022647501e5e9479993529b0..b69f03a3a283cf0ac569d4029eb4dfa4a9e66709 100644 (file)
@@ -6,7 +6,7 @@
  *  Copyright (C) Paul Ashton                       1997,
  *  Copyright (C) Marc Jacobsen                            1999,
  *  Copyright (C) Jeremy Allison                    2001-2002,
  *  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.
  *  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 */
        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);
        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 */
        /* 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);
        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 ) {
        /* 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 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);
        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 */
        /* create the security descriptor */
-       
+
        if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
                return NT_STATUS_NO_MEMORY;
 
        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;
        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;
        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;
 }
 
        return r_u->status;
 }
 
-
 /*******************************************************************
  _samr_set_sec_obj
  ********************************************************************/
 /*******************************************************************
  _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;
 
        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;
                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;
                return NT_STATUS_ACCESS_DENIED;
+       }
 
        /*
         * Do *NOT* do become_root()/unbecome_root() here ! JRA.
 
        /*
         * 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_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 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;
        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:
                        
        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;
 
                        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;
 
                        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;
 
                        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;
 
                        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);
                        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();
 
                        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);
 
                        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;
 
                        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:
                                       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);
                        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_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:
                        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;
 
                        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;
 
                        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);
                        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);
 
        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();
        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);
        }
 
        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 
        /*********************************************************************
         * 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)
         *********************************************************************/
         * 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 */
        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 );
                        /* 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 **********/
        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 ( can_add_account )
                become_root();
-                               
+
        if ( !pw ) {
                if (*add_script) {
        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();
        /* 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;
        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__));
 
 
        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;
        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__));
 
 
        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;
        }
        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) {
        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 );
        }
                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"));
 
        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 );
        }
                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"));
 
        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 */
        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 );
                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;
        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)
        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:
 
        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;
 
                        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;
 
                        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;
 
                        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;
 
                        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);
                        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);
 
 
                        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);
 
                        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;
 
                        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:
                                       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);
                        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;
                        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_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:
                        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;
 
                        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;
 
                        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);
                        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);
                        
                        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);
                        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;
                        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;
                        
 
                        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;
                        break;
                default:
                        return NT_STATUS_INVALID_INFO_CLASS;
index 24869d5d2bd07a07665055fa66e3871ce059f379..1d9a8ecd1dbe63f35208ccbbd740bf95870baab7 100644 (file)
@@ -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) {
                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 {
                            || 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) {
                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 {
                            || expire == (uint32)-1) {
                                new_time = get_time_t_max();
                        } else {
index cda3f26137ce23907cc766d6eb588e0f9675bd99..5233d6c252df040734f2a77bea58473b1bee2d53 100644 (file)
@@ -75,7 +75,7 @@ typedef struct _counter_printer_0 {
 
 static counter_printer_0 *counter_list;
 
 
 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;
 
 
 static uint32 smb_connections=0;
 
 
@@ -166,7 +166,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
                return;
        }
 
                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",
        
        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) {
 
        /* 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
                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;
        }
 
                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;
        }
                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 ) {
                }
 
                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 );
                }
        }
                                        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
  ********************************************************************/
 
  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;
 {
        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));
                
        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;
 }
 
        return True;
 }
@@ -1186,7 +1187,7 @@ static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
  over all printers, upgrading ones as necessary 
  **********************************************************************/
  
  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;
 {
        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));
                
        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;
 }
 
        return True;
 }
@@ -1282,7 +1284,8 @@ static BOOL srv_spoolss_reset_printerdata(char* drivername)
  over all printers, resetting printer data as neessary 
  **********************************************************************/
  
  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;
 {
        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) )
                
                        /* this should not have failed---if it did, report to client */
                        if ( !W_ERROR_IS_OK(status_win2k) )
+                       {
+                               status = status_win2k;
                                goto done;
                                goto done;
+                       }
                }
        }
        
                }
        }
        
@@ -2479,9 +2485,10 @@ done:
  Connect to the client machine.
 **********************************************************/
 
  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)
 {
                        struct in_addr *client_ip, const char *remote_machine)
 {
+       NTSTATUS ret;
        ZERO_STRUCTP(the_cli);
        
        if(cli_initialise(the_cli) == NULL) {
        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 :-).
         */
 
         * 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;
        } 
                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) {
         * 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);
 
                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);
                        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++;
 
 
        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))
                        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)) )
        {
                        || !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;
                }
                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); 
        }
        
        /*
        }
        
        /*
index e9dd015421ca974c1e44fff566be8f65c4b6d75e..9643b2a72498711c33ae7a868057c372e78eea70 100644 (file)
@@ -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.
  ********************************************************************/
 
  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);
 {
        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();
                        }
 
                                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) 
                                r_u->status = WERR_OK;
 
                        if (not_root) 
index 6ba26414d363a0cae3cab341e65a2cb9d828f6ad..31d8bbe9b3d91c497a529918134dadb5b5f512e5 100644 (file)
@@ -309,24 +309,76 @@ static BOOL api_svcctl_query_service_config2(pipes_struct *p)
        return True;
 }
 
        return True;
 }
 
+/*******************************************************************
+ ********************************************************************/
+
+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[] =
 {
 /*******************************************************************
  \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 }
 };
 
 
 };
 
 
index 538b97a2b17f2e2c131eb9ec82a8da674e775648..e8df2acb22fec61ea99995e048343afcd4c875c5 100644 (file)
@@ -1,8 +1,11 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
 /* 
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
- *  Copyright (C) Gerald (Jerry) Carter             2005,
+ *
  *  Copyright (C) Marcin Krzysztof Porwit           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
  *  
  *  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
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
  *  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
 
 #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;
        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() ) {
 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 );
        }
        
        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;
        size_t i = 0;
        SEC_DESC *sd;
        SEC_ACL *acl;
-       uint32 sd_size;
+       size_t sd_size;
 
        /* basic access for Everyone */
        
 
        /* basic access for Everyone */
        
@@ -105,51 +154,13 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx )
        return sd;
 }
 
        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)
 {
 /******************************************************************
  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;
                                           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;
 
                return WERR_NOMEM;
 
-       ZERO_STRUCTP( info );
-               
        /* the Service Manager has a NULL name */
        
        /* 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;
                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 */
 
                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;
                }
                        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;
                }
                        result = WERR_NOMEM;
                        goto done;
                }
+               break;
+
+       default:
+               result = WERR_NO_SUCH_SERVICE;
+               goto done;
        }
 
        info->access_granted = access_granted;  
        }
 
        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;
                
        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 );
                
        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;
                        
        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;
                
                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 );
        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;
 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 */
        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);
                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;
 }
 
        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 */
 
                
        /* 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;
 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 );
        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 */
 
        
        /* 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;
 
        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;
 
                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 ) {
                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) ) {
                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;
                        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;
 
        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;
                
        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 */
        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 ( !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 )
 {
 
 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 );
        SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+       uint32 buffer_size;
        
        /* perform access checks */
 
        
        /* 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 
                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;
 }
 
        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 )
 {
 
 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 );
        SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+       uint32 buffer_size;
+       WERROR wresult;
        
        /* perform access checks */
 
        
        /* 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;
           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;
 }
 
        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 )
 {
 
 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 );
        SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+       uint32 buffer_size;
        
        /* perform access checks */
 
        
        /* 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 */
 
        /* 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;
 }
 }
index 44e97f9881e7bba20d4b6ed5cd2aca5422b6b52f..956dbfa402702fd0b1f2074d0ef7eca0943cb86f 100644 (file)
@@ -24,7 +24,7 @@
 
 /* Check DFS is supported by the remote server */
 
 
 /* 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;
                               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;
        }
 
                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 ");
 
        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;
 }
 
        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;
                             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];
 
        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;
 }
 
                             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;
                                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];
 
        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;
                                sharename);
 
        return result;
@@ -168,7 +168,7 @@ static void display_dfs_info_ctr(DFS_INFO_CTR *ctr)
 
 /* Enumerate dfs shares */
 
 
 /* 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;
                              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]);
 
        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);
 
        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;
 }
 
        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;
                                 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]);
 
        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))
                                  sharename, info_level, &ctr);
 
        if (NT_STATUS_IS_OK(result))
@@ -227,11 +227,11 @@ struct cmd_set dfs_commands[] = {
 
        { "DFS" },
 
 
        { "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 }
 };
 
        { NULL }
 };
index 0a1fd7e012ba19515e846ed9a3946134cc540906..951d18a710e3c3497c4b653b05dcd31a2db2ec56 100644 (file)
 
 /* Look up domain related information on a remote host */
 
 
 /* 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;
        
                                     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);
        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;
 }
 
        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) 
 {
                                     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;
        
        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 );
                &trusts, &num_domains );
        
        printf( "%d domains returned\n", num_domains );
@@ -74,8 +74,8 @@ struct cmd_set ds_commands[] = {
 
        { "LSARPC-DS" },
 
 
        { "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 }
 };
 };
index fce8e4c7b8f9a3257c84b6fbde86fea1508f4cc0..6d608ebaf10ab8c4059de38039111f15947d9eaf 100644 (file)
@@ -22,7 +22,7 @@
 #include "includes.h"
 #include "rpcclient.h"
 
 #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;
                                 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]);
 
        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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -47,7 +47,7 @@ done:
        return result;
 }
 
        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;
                              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;
 
        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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -84,7 +84,7 @@ done:
        return result;
 }
 
        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)
 {
                                     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]);
 
 
        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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -116,7 +116,7 @@ done:
        return result;
 }
 
        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;
                                   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;
 
        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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -151,9 +151,9 @@ struct cmd_set echo_commands[] = {
 
        { "ECHO" },
 
 
        { "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 }
 };
        { NULL }
 };
index b01f63924774b878e582a744440db8d54c7585c0..00ed515245bcbf22a6096534f20ebaddcb653335 100644 (file)
@@ -26,7 +26,7 @@
 
 /* useful function to allow entering a name instead of a SID and
  * looking it up automatically */
 
 /* 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)
 {
                            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;
        }
 
                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;
 
                                     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;
 
        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];
 
 
        *sid = sids[0];
 
@@ -62,7 +62,7 @@ done:
 
 /* Look up domain related information on a remote host */
 
 
 /* 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) 
 {
                                           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:
        /* 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;
                                             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:
                                                    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;
                                     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);
        }
                                                   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);
        }
                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 */
 
  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)
 {
                                      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;
        }
 
                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;
 
                                     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) != 
                                      (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]);
        }
 
                       sid_type_lookup(types[i]), types[i]);
        }
 
-       cli_lsa_close(cli, mem_ctx, &pol);
+       rpccli_lsa_close(cli, mem_ctx, &pol);
 
  done:
        return result;
 
  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 */
 
 
 /* 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;
                                     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;
        }
 
                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);
 
                                     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 */
 
 
        /* 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) != 
                                     &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]);
        }
 
                       names[i] ? names[i] : "*unknown*", types[i]);
        }
 
-       cli_lsa_close(cli, mem_ctx, &pol);
+       rpccli_lsa_close(cli, mem_ctx, &pol);
 
  done:
        return result;
 
  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 */
 
 
 /* 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)
 {
                                        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]);
        }       
 
                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);
 
                                     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 */
 
 
                /* 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) &&
                                                &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 */
 
  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) 
 {
                                       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]);
 
        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;
 
                                     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))
                                        &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]);
        }
 
                       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 */
 
  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) 
 {
                                      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;
        }
 
                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;
 
                                     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;
 
        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);
 
        /* 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 */
 
  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) 
 {
                                  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]);
 
        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;
 
                                     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))
                                        &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);
        }
 
                printf("%s\n", sid_str);
        }
 
+       rpccli_lsa_close(cli, mem_ctx, &pol);
  done:
        return result;
 }
 
 /* Create a new account */
 
  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) 
 {
                                            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;      
 
        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;
 
                                     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;
 
        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;
 
        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;
 }
  done:
        return result;
 }
@@ -499,7 +507,7 @@ static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
 
 /* Enumerate the privileges of an SID */
 
 
 /* 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) 
 {
                                            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;      
 
        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;
 
                                     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;
 
 
        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;
 
        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);
        }
 
                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;
 }
  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 */
 
 
 /* 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) 
 {
                                         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;      
 
        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;
 
                                     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;
 
        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]);
        }
 
                printf("\t%s\n", rights[i]);
        }
 
+       rpccli_lsa_close(cli, mem_ctx, &dom_pol);
  done:
        return result;
 }
  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 */
 
 
 /* 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) 
 {
                                        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;      
 
        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;
 
                                     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;
 
                                            argc-2, argv+2);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
+       rpccli_lsa_close(cli, mem_ctx, &dom_pol);
  done:
        return result;
 }
  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 */
 
 
 /* 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) 
 {
                                        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;      
 
        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;
 
                                     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;
 
                                               False, argc-2, argv+2);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
+       rpccli_lsa_close(cli, mem_ctx, &dom_pol);
+
  done:
        return result;
 }
  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 */
 
 
 /* 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) 
 {
                                        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;
        }
 
                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;
 
                                     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;
 
        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);
 
 
        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 */
 
  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) 
 {
                                     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;
        }
 
                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;
 
                                      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;
 
        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);
 
 
        display_sec_desc(sdb->sec);
 
+       rpccli_lsa_close(cli, mem_ctx, &pol);
  done:
        return result;
 }
  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) 
 {
                                                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]);
 
        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;
 
 
        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))
                                                          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)
 
  done:
        if (&pol)
-               cli_lsa_close(cli, mem_ctx, &pol);
+               rpccli_lsa_close(cli, mem_ctx, &pol);
 
        return result;
 }
 
 
        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) 
 {
                                                 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]);
 
        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;
 
 
        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))
                                                           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)
 
  done:
        if (&pol)
-               cli_lsa_close(cli, mem_ctx, &pol);
+               rpccli_lsa_close(cli, mem_ctx, &pol);
 
        return result;
 }
 
 
        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) 
 {
                                           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]);
 
        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;
        
 
        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;
 
                                             &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))
                                                   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)
 
  done:
        if (&pol)
-               cli_lsa_close(cli, mem_ctx, &pol);
+               rpccli_lsa_close(cli, mem_ctx, &pol);
 
        return result;
 }
 
        return result;
 }
@@ -938,27 +953,27 @@ struct cmd_set lsarpc_commands[] = {
 
        { "LSARPC" },
 
 
        { "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
 #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 }
 };
 
        { NULL }
 };
index b55306ddc8805f8c9c5c7d3616756e3c57c6122b..153daa5cf2d51e3c8fa3fdb006a7c710dc5a982b 100644 (file)
@@ -22,7 +22,7 @@
 #include "includes.h"
 #include "rpcclient.h"
 
 #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)
 {
                                          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;
        }
 
                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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -45,7 +45,7 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct cli_state *cli,
        return result;
 }
 
        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)
 {
                                       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;
        }
 
                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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -70,7 +70,7 @@ static NTSTATUS cmd_netlogon_getdcname(struct cli_state *cli,
        return result;
 }
 
        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)
 {
                                         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 */
 
 
 /* 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)
 {
                                       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;
         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]);
 
         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]);
 
         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 */
 
         /* 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))
                                       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 */
 
 
 /* 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)
 {
                                         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;
 
         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);
 
                                         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 */
 
 
 /* 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)
 {
                                        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;
         const char *username, *password;
        uint32 neg_flags = 0x000001ff;
        int auth_level = 2;
-       DOM_CRED ret_creds;
 
         /* Check arguments */
 
 
         /* Check arguments */
 
@@ -277,12 +272,8 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
 
         /* Perform the sam logon */
 
 
         /* 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;
 
        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 */
 
 
 /* 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;
                                             TALLOC_CTX *mem_ctx, int argc,
                                             const char **argv)
 {
         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-       DOM_CRED ret_creds;
 
         /* Check arguments */
 
 
         /* Check arguments */
 
@@ -308,13 +298,9 @@ static NTSTATUS cmd_netlogon_change_trust_pw(struct cli_state *cli,
 
         /* Perform the sam logon */
 
 
         /* Perform the sam logon */
 
-       ZERO_STRUCT(ret_creds);
-
        result = trust_pw_find_change_and_store_it(cli, mem_ctx,
                                                   lp_workgroup());
 
        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;
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
@@ -329,13 +315,13 @@ struct cmd_set netlogon_commands[] = {
 
        { "NETLOGON" },
 
 
        { "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 }
 };
 
        { NULL }
 };
index acb392710507b5c26293e8f03a132a9a8d3b2b41..a05c2c8a0b06d79b099faf9fc8eea5d6d9e6fa07 100644 (file)
@@ -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
  ****************************************************************************/
 /****************************************************************************
  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;
        
                                  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)) {
        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;
                                          connect_pol);
        }
        return result;
@@ -316,7 +316,7 @@ static NTSTATUS try_samr_connects(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 /**********************************************************************
  * Query user information 
  */
 /**********************************************************************
  * 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) 
 {
                                     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);
        
 
                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,
        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;
 
        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;
 
                                      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);
 
                                    access_mask,
                                    user_rid, &user_pol);
 
@@ -367,7 +367,7 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
 
        ZERO_STRUCT(user_ctr);
 
 
        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))
                                         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;
        }
 
                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;
 }
 done:
        return result;
 }
@@ -435,7 +439,7 @@ static void display_group_info_ctr(GROUP_INFO_CTR *ctr)
 /***********************************************************************
  * Query group information 
  */
 /***********************************************************************
  * 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) 
 {
                                      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);
 
        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,
        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;
 
        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;
 
                                      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;
 
                                     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;
                                          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);
 
 
        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 */
 
 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) 
 {
                                           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);
 
        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,
        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;
 
        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;
 
                                      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;
 
                                    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))
                                           &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);
        }
 
                       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 */
 
  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) 
 {
                                           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;
        }
 
                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,
        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)
                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)
                                              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);
                                              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;
 
        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);
 
                                            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]);
        }
 
                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 */
 
  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) 
 {
                                         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);
 
        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,
        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;
 
        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;
 
                                      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;
 
                                     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);
 
                                         &num_members, &group_rids,
                                         &group_attrs);
 
@@ -701,13 +713,16 @@ static NTSTATUS cmd_samr_query_groupmem(struct cli_state *cli,
                       group_attrs[i]);
        }
 
                       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 */
 
  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) 
 {
                                        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 */
 
 
        /* 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);
 
                                      access_mask,
                                      &domain_sid, &domain_pol);
 
@@ -758,7 +773,7 @@ static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
        size = 0xffff;
 
        do {
        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);
 
                        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)
 
  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)
 
        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 */
 
 
        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) 
 {
                                          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 */
 
 
        /* 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);
 
                                      access_mask,
                                      &domain_sid, &domain_pol);
 
@@ -830,7 +845,7 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct cli_state *cli,
        size = 0xffff;
 
        do {
        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);
 
                        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)
 
  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)
 
        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 */
 
 
        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) 
 {
                                          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)
        /* 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)
                                              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
                                              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 {
        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);
 
                        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)
 
  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)
        
        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 */
 
        
        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) 
 {
                                         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)
        /* 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)
                                              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
                                              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 */
 
 
        /* 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;
 
                                     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))
                                         &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);
        }
 
                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 */
 
  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) 
 {
                                         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 */
 
 
        /* 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);
 
                                      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);
                
                        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);
                                                 &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));
 
                }
        } 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 */
 
  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) 
 {
                                        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 */
 
 
        /* 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);
 
                                      access_mask,
                                      &domain_sid, &domain_pol);
 
@@ -1181,7 +1201,7 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
 
        /* Query domain info */
 
 
        /* 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))
                                         switch_level, &ctr);
 
        if (!NT_STATUS_IS_OK(result))
@@ -1213,14 +1233,14 @@ static NTSTATUS cmd_samr_query_dominfo(struct cli_state *cli,
 
  done:
  
 
  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 */
 
        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) 
 {
                                          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 */
 
 
        /* 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);
 
                                      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? */
 
        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;
 
                                          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;
 
        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;
 
        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:
        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 */
 
 
 /* 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) 
 {
                                           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 */
 
 
        /* 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);
 
                                      access_mask,
                                      &domain_sid, &domain_pol);
 
@@ -1323,20 +1343,20 @@ static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
 
        /* Create domain user */
 
 
        /* 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;
 
                                           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;
 
        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;
 
        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:
        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 */
 
 
 /* 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) 
 {
                                       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)
                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)
                                              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
                                              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];
 
        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);
 
                                       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]);
 
                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 */
 
  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) 
 {
                                      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;
 
        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);
 
                                      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]);
 
        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) &&
                                      &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]);
 
        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 */
 
  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) 
 {
                                          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;
 
        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);
 
                                      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 */
 
                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);
                                               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;
 
                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);
 
                                            access_mask,
                                            user_rids[0], &user_pol);
 
@@ -1523,13 +1547,17 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
 
        /* Delete user */
 
 
        /* 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 */
 
 
        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;
 }
  done:
        return result;
 }
@@ -1537,7 +1565,7 @@ static NTSTATUS cmd_samr_delete_dom_user(struct cli_state *cli,
 /**********************************************************************
  * Query user security object 
  */
 /**********************************************************************
  * 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) 
 {
                                     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);
        }
        
                        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);
        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)
                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);
 
                                              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)
                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);
 
                                            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 */
 
 
        /* 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))
                                        &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);
        
 
        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;
 }
 
 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) 
 {
                                        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;
        }
 
                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);
        
        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 */
 
 
 /* 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) 
 {
                                       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;
 
        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;
        
                                      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);
                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);
 
                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;
 }
 done:
        return result;
 }
@@ -1686,26 +1719,26 @@ struct cmd_set samr_commands[] = {
 
        { "SAMR" },
 
 
        { "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 }
 };
        { NULL }
 };
index 1b3d3b7e0c41af782d1816399df9acc1c02db892..0ae16e8f1ae2d9b42110af5d78dc2013dbee8e5d 100644 (file)
@@ -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)
 {
                                             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;
 
        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 */
 
        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);
                                             "", 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", 
 
                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)
 {
                                           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 {
        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);
 
                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)) {
                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)
 {
                                       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);
 
 
        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;
 
        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)
 {
                                        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]);
        }
 
                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 */
        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);
                                
                                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 */
        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;
 
         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;
 
        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)
        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;
 }
 
        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)
 {
                                        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]);
        }
 
                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 */
        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);
                                
                                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 */
        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;
 
         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;
 
        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)
        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;
 }
 
        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)
 {
                                        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]);
        }
 
                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 */
 
        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);
 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
                                             servername, user, &pol);
 
@@ -638,7 +638,7 @@ static WERROR cmd_spoolss_getprinter(struct cli_state *cli,
 
        /* Get printer info */
 
 
        /* 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;
 
        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) 
 
  done: 
        if (opened_hnd) 
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
 
        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)
 {
                                           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 */
 
 
        /* 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);
        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 */
 
        
        /* 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);
 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
                                             servername, user, &pol);
 
@@ -773,7 +773,7 @@ static WERROR cmd_spoolss_getprinterdata(struct cli_state *cli,
 
        /* Get printer info */
 
 
        /* 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;
 
        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) 
 
  done: 
        if (opened_hnd) 
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
 
        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)
 {
                                             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 */
 
 
        /* 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);
        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 */
 
        
        /* 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);
 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
                                             servername, user, &pol);
 
@@ -840,7 +840,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct cli_state *cli,
 
        /* Get printer info */
 
 
        /* 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))
                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) 
 
  done: 
        if (opened_hnd) 
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
 
        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)
 {
                                       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 */
        }
 
        /* 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]);
        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 */
 
 
        /* 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);
 
                                             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++) {
 
 
        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);
 
                        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)
        /* 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;
        
        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)
 {
                                          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;
 
                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);
 
                        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)
 {
                                          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 */
 
 
        /* 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);
 
        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)
 {
                                              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;
 
 
        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, 
 
        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)
 {
                                          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;
         }
        
                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 */
         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;
        */
 
        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]);
 
        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)
 {
                                       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;
         }
 
                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 */
 
        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);
 
                                             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;
 
        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");
 
        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]);
 
 
        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");
 
        if (!W_ERROR_IS_OK(result)) {
                printf("SetPrinter call failed!\n");
@@ -1484,7 +1484,7 @@ done:
        /* Cleanup */
 
        if (opened_hnd)
        /* Cleanup */
 
        if (opened_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
 
        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)
 {
                                          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 */
                        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) ) 
                        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)
 {
                                          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;
         }
 
                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 */
        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) ) {
                        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)
 {
                                            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;
         }
 
                return WERR_OK;
         }
 
-       if (asprintf(&servername, "\\\\%s", cli->desthost) < 0)
+       if (asprintf(&servername, "\\\\%s", cli->cli->desthost) < 0)
                return WERR_NOMEM;
        strupper_m(servername);
 
                return WERR_NOMEM;
        strupper_m(servername);
 
@@ -1620,7 +1620,7 @@ static WERROR cmd_spoolss_getprintprocdir(struct cli_state *cli,
                return WERR_NOMEM;
        }
 
                return WERR_NOMEM;
        }
 
-       result = cli_spoolss_getprintprocessordirectory(
+       result = rpccli_spoolss_getprintprocessordirectory(
                cli, mem_ctx, servername, environment, procdir);
 
        if (W_ERROR_IS_OK(result))
                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;
                                    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 */
 
        
        /* 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]);
 
        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);
 
                                             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 */
 
 
        /* 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)
 
  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);
 
        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;
                                    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 */
 
        
        /* 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]);
 
        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);
 
                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 */
 
 
        /* 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)
 
  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);
 
        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;
                                    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 */
 
        
        /* 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]);
 
        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);
 
                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 */
 
 
        /* 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;
 
        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)
 
  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);
 
        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)
 {
                                       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 */
 
        
        /* 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]);
 
        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);
 
                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 */
 
 
        /* 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)
 
  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);
 
        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)
 {
                                       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 */
 
        
        /* 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]);
 
        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);
 
                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;
        /* 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;
 
        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)
 
  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);
 
        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)
 {
                                            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;
        }
 
                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);
        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 */
        }
 
        /* 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))
                                             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;
 
 
        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;
 
         if (!W_ERROR_IS_OK(result))
                 goto done;
@@ -2082,7 +2082,7 @@ static WERROR cmd_spoolss_setprinterdata(struct cli_state *cli,
                goto done;
        }
 
                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]);
                
        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]);
        
        }
        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;
 
         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)
 done:
        /* cleanup */
        if (opened_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
 
        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)
 {
                                      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 */
 
 
        /* 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);
        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]);
 
        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);
 
                                             "", 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;
        /* 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))
                &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)
        
 done:
        if (got_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
 
        return result;
 }
 
        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)
 {
                                       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 */
 
        
        /* 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);
        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]);
 
        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);
 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
                                             servername, user, &hnd);
 
@@ -2258,12 +2258,12 @@ static WERROR cmd_spoolss_enum_data( struct cli_state *cli,
 
        /* Enumerate data */
 
 
        /* 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;
                                             &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))
                        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)
 
 done:
        if (got_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
 
        return result;
 }
 
        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)
 {
                                          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 */
 
 
        /* 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);
        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]);
 
        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);
 
                                             "", 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;
 
        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;
 
        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)
 
 done:
        if (got_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
 
        return result;
 }
 
        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)
 {
                                             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 */
 
 
        /* 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);
        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]);
 
        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);
 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
                                             servername, user, &hnd);
 
@@ -2388,7 +2388,7 @@ static WERROR cmd_spoolss_enum_printerkey( struct cli_state *cli,
 
        /* Enumerate subkeys */
 
 
        /* 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;
 
        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)
 
 done:
        if (got_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
 
        return result;
 }
 
        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)
 {
                                     TALLOC_CTX *mem_ctx, int argc, 
                                     const char **argv)
 {
@@ -2432,14 +2432,14 @@ static WERROR cmd_spoolss_rffpcnex(struct cli_state *cli,
 
        /* Open printer */
 
 
        /* Open printer */
 
-       slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->desthost);
+       slprintf(servername, sizeof(servername) - 1, "\\\\%s", cli->cli->desthost);
        strupper_m(servername);
 
        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);
 
                 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);
 
                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);
 
        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)) {
                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)
 
 done:          
        if (got_hnd)
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(cli, mem_ctx, &hnd);
 
        return result;
 }
 
 
        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"  },
 
 /* 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 }
 };
 
        { NULL }
 };
index 1d173ffdff13cab97aa73753be0935f2d43b1e6d..da81a82c8d55ce7363759d3c78f7b13113a42ca2 100644 (file)
@@ -179,7 +179,7 @@ static void display_srv_info_102(SRV_INFO_102 *sv102)
 }
 
 /* Server query info */
 }
 
 /* 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)
 {
                                           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]);
 
        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)) {
                                             &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)
 {
                                           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);
 
 
        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)
                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;
 }
 
        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)
 {
                                            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]);
 
        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;
 
        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;
 }
 
        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)
 {
                                            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 */
        }
 
        /* 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;
 
        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 */
        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 */
 
        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;
 
        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;
 }
 
        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;
                                           TALLOC_CTX *mem_ctx,
                                           int argc, const char **argv)
 {
        TIME_OF_DAY_INFO tod;
+       fstring srv_name_slash;
        WERROR result;
 
        if (argc > 1) {
        WERROR result;
 
        if (argc > 1) {
@@ -413,8 +414,9 @@ static WERROR cmd_srvsvc_net_remote_tod(struct cli_state *cli,
                return WERR_OK;
        }
 
                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;
 
        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;
 }
 
        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)
 {
                                         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);
 
 
        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))
                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" },
 
 
        { "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 }
 };
 
        { NULL }
 };
diff --git a/source3/rpcclient/cmd_test.c b/source3/rpcclient/cmd_test.c
new file mode 100644 (file)
index 0000000..94545dc
--- /dev/null
@@ -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 }
+};
index 137ff3bdae93d09545bd23a43f1fff004c1e84a0..a65cd1f799f9d9678c7b133ea17fdb1d58f5e2aa 100644 (file)
@@ -19,6 +19,8 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+THIS IS NO LONGER USED - NEEDS REMOVAL.
+
 #include "includes.h"
 
 #define DEBUG_TESTING
 #include "includes.h"
 
 #define DEBUG_TESTING
index 34e81cafe68d4e44d945cd9bdf8af3cd2184d4dd..630add0e9bd12e925531f028cd3d568d37bc3309 100644 (file)
@@ -25,6 +25,8 @@
 
 DOM_SID domain_sid;
 
 
 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.
  *
 
 /* 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;
        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 (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;
        }
 
                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;
        }
        
                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;
        }
 
                                     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;
                                           &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 );
 
        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:
        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)) {
        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 */
 
 
 /* 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;
                                 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 */
 
 
 /* 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;
                          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 */
 
 
 /* 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) {
                                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;
 }
 
        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 */
 }
 
                          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)
 {
                          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;
                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) {
        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");
                             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");
                             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" },
 
 
        { "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[] = {
 
        { NULL }
 };
 
 static struct cmd_set separator_command[] = {
-       { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   -1,     "----------------------" },
+       { "---------------", MAX_RPC_RETURN_TYPE, NULL, NULL,   -1, NULL, "----------------------" },
        { 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 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,
 
 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,
        reg_commands,
        echo_commands,
        shutdown_commands,
+       test_commands,
        NULL
 };
 
        NULL
 };
 
@@ -492,7 +504,6 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 {
        NTSTATUS ntresult;
        WERROR wresult;
 {
        NTSTATUS ntresult;
        WERROR wresult;
-       uchar trust_password[16];
        
        TALLOC_CTX *mem_ctx;
 
        
        TALLOC_CTX *mem_ctx;
 
@@ -505,57 +516,93 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 
        /* Open pipe */
 
 
        /* 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 */
 
 
        /* Cleanup */
 
@@ -736,7 +783,9 @@ out_free:
                return 1;
        }
 
                return 1;
        }
 
+#if 0  /* COMMENT OUT FOR TESTING */
        memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
        memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
+#endif
 
        /* Load command lists */
 
 
        /* Load command lists */
 
index e1e61dc43d555223002d70b1038524fd48c1f61c..3c86c0be62eecd8a8bd249a653ef28db552c5d1b 100644 (file)
@@ -30,11 +30,12 @@ typedef enum {
 
 struct cmd_set {
        const char *name;
 
 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;
 };
        const char *description;
        const char *usage;
 };
index 0ba97946965ce65d01554d22cfba56f7449f08bc..4a1ae141b106ae8ac87851382d4729065de2a10b 100644 (file)
@@ -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;
 {
        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;
        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 */
        }       
 
        /* 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 */
                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;
        }
 
        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;
        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"));
 
        /* 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) &&
 
        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:
        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);
 
        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 (file)
index 0000000..b1aae2b
--- /dev/null
@@ -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);
+}
index 9cd91008392aaf9c0becbedb6183872fec99e871..5564ac02318e276d4d52ae0450c4f18537673028 100755 (executable)
@@ -13,7 +13,7 @@ if [ $# -ge 4 ] ; then
   GROFF=$4                    # sh cmd line, including options 
 fi
 
   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
        echo "No manpages present.  SVN development version maybe?"
        exit 0
 fi
index 2b99b9c57f1a4092dc09aa7df5da0ea0f2408d39..cba3a294f871a51cd586f8ecb7e78749126c26e1 100755 (executable)
@@ -3,7 +3,7 @@
 
 SWATDIR=`echo $1 | sed 's/\/\//\//g'`
 SRCDIR=$2/
 
 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
 
 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 \
 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
     if [ ! -d $d ]; then
        mkdir -p $d
        if [ ! -d $d ]; then
@@ -28,7 +28,7 @@ done
 # Install images
 for ln in $LANGS; do
 
 # 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
       if [ ! -f $f ] ; then
        continue
       fi
@@ -59,7 +59,7 @@ for ln in $LANGS; do
 
   # Install "server-side" includes
 
 
   # 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
       if [ ! -f $f ] ; then
        continue
       fi
@@ -69,13 +69,25 @@ for ln in $LANGS; do
       chmod 0644 $FNAME
   done
 
       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
 
 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
     do 
     
       if [ ! -d $SRCDIR../docs/$dir ]; then
index 3940c34700a2bf0b2762b6eab6fbcf130aa7cfb8..73a1c2b3f0a0f487aef2e20c163c7ce504109940 100644 (file)
@@ -128,7 +128,7 @@ END {
     gotstart = 1;
   }
 
     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;
   }
 
     gotstart = 1;
   }
 
index 0981d9e29e149770853ac3060b22576a6cb29ff5..40e185e153f76bbaab89ccc5caa812d0df97c16d 100644 (file)
@@ -2,16 +2,13 @@
 ## library file for test functions
 ##
 
 ## 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
 ##
 ## 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()
 }
 
 start_smbd()
@@ -22,7 +19,7 @@ start_smbd()
 
        sleep 1
 
 
        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()
 }
 
 stop_smbd()
@@ -33,7 +30,7 @@ stop_smbd()
        ## belt and braces; first kill and then send a shutdown message
 
        kill -TERM $smbd_pid
        ## 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
 
        ## check to see if smbd is already running
        check_smbd_running
@@ -43,23 +40,14 @@ stop_smbd()
        fi
 }
 
        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
 ##
 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()
 }
 
 start_nmbd()
index 7db2abe226e8d20218d73ee7195c796b86fd595e..6d54d0e4895a70e2b23b282c98660a57e180c4fb 100644 (file)
@@ -22,27 +22,9 @@ chmod 1777 $PREFIX_ABS/tmp
 
 start_smbd || exit $?
 
 
 start_smbd || exit $?
 
-## share enumeration
-
 smbclient $CONFIGURATION -L localhost -N -p 139
 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
 
 stop_smbd
-exit 0
 
 
+exit $ret
index 29c5a9f6e6969ec3e1d236ef779fa552483e6e6d..b59cd5330e5acae3e40761e47a397f700486cfd0 100644 (file)
@@ -1,8 +1,10 @@
 /* 
  *  Unix SMB/CIFS implementation.
  *  Service Control API Implementation
 /* 
  *  Unix SMB/CIFS implementation.
  *  Service Control API Implementation
- *  Copyright (C) Gerald Carter                   2005.
+ * 
  *  Copyright (C) Marcin Krzysztof Porwit         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
  *  
  *  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
 
 #include "includes.h"
 
 
 #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
        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 (file)
index 0000000..2aa5a31
--- /dev/null
@@ -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
+};
index c856ae2a9955bead87b836cd99123e5088590970..5801d076c496ebc22d6b6affedeee68d7b3b53ce 100644 (file)
@@ -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;
 }
 
        return WERR_OK;
 }
 
index 5f8fa73ced4ab16c67cb6cf33358b8dfac6337c8..13a1dbb1bdf697307d5fd79b8e7490d6de554161 100644 (file)
@@ -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 );
        
 {
        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 */
        
 {
        /* 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;
        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 (file)
index 0000000..1bccee2
--- /dev/null
@@ -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
+};
index 72d021d4e64b2f53f0289a488535c5cd6a740681..805e45f6ea33f2d870e3905d88dd615b297eb882 100644 (file)
@@ -80,7 +80,8 @@ static BOOL in_chained_smb(void)
        return (chain_size != 0);
 }
 
        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.
 
 /****************************************************************************
  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,
 
        /* 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)) {
                        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);
        
        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;
        
        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,
 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);
                                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,
 
                        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);
                }
                                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.
 *****************************************************************************/
 
   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));
 {
        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,
                                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);
                                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,
                        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);
                                        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,
                        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);
                                        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,
                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);
                                        blr->offset, blr->count, True, NULL, NULL);
 
                        free_blocking_lock_record(blr);
index 1178400e4db25fe481915727930d61e2ec312a01..738d12151db5252a33972a60878ff3d5d82d28d5 100644 (file)
@@ -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;
        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));
 
        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 :-).
         */
 
         * 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", 
                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);
                cli_shutdown(cli);
-               nt_status = NT_STATUS_UNSUCCESSFUL;
                goto failed;
        }
 
                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:
        cli_shutdown(cli);
        
 failed:
index 374c57a083ae582d76f393c140c212e655e1f619..c1168583ae7e2a9969fc45832167b8986c61a117 100644 (file)
@@ -946,7 +946,7 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext)
        int i;
        uint32 pwHisLen, curr_pwHisLen;
 
        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;
        }
        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;
        }
 
                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));
                DEBUG(1, ("user %s cannot change password - password too short\n", 
                          username));
                DEBUGADD(1, (" account policy min password len = %d\n", min_len));
index afc645ca0627bd1bb7470d4d69d9e8f495b946e8..becca003b64df3241a1f37acf86eef2efafc217e 100644 (file)
@@ -110,31 +110,30 @@ static int close_filestruct(files_struct *fsp)
  If any deferred opens are waiting on this close, notify them.
 ****************************************************************************/
 
  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)
 {
 
 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;
        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);
 
 
        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.
         */
 
         * 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 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
 
        /*
         * 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);
        }
 
                process_pending_change_notify_queue((time_t)0);
        }
 
-       unlock_share_entry_fsp(fsp);
+       talloc_free(lck);
 
        if(fsp->oplock_type)
                release_file_oplock(fsp);
 
        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 &&
         */
 
        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" ));
                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" ));
index b69868ecec10af5cd073d8e03fb34509569cef40..bb000bac30ec86ee39045e3b3410911f51c48f66 100644 (file)
@@ -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
 ****************************************************************************/
 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;
 {
        connection_struct *conn, *next;
        fstring sharename;
index 32e2f058fc23fea73b8c42dde24969a709aa1447..07d3181144f7dfd53c70fdbacdf3cd35c22c21ab 100644 (file)
@@ -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);
 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
        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)) {
        /* 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;
                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;
        /* 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;
        crec.cnum = conn?conn->cnum:-1;
        if (conn) {
                crec.uid = conn->uid;
index 090a2f6d813c93621d6822db91d61c5cfc81ebc9..3cdcae5c7f5f8525d11b94b994a1601b90193965 100644 (file)
@@ -41,23 +41,22 @@ void set_saved_error_triple(int eclass, int ecode, NTSTATUS status)
        override_ERR_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.
 ****************************************************************************/
 
 /****************************************************************************
  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;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
index 65986e96127bc90be36ecd6b0e8270b9ef37ab11..181e17b11fb445fcc1a9238cc21045c37c578e77 100644 (file)
@@ -65,7 +65,7 @@ files_struct *file_new(connection_struct *conn)
 {
        int i;
        static int first_file;
 {
        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
 
        /* 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;
        }
 
                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) {
        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"));
                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) {
                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;
        }
 
                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);
        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;
        }
 
                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. */
                                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,
                                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,
index 613dda9a16bd3d1374d5d39d1989b6033e1bbd09..335ba8e2ef9315e21e1f4240c7a47d14c85b2e27 100644 (file)
@@ -212,7 +212,7 @@ static BOOL is_mangled_component(const char *name, size_t len)
 {
        unsigned int i;
 
 {
        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)
 
        /* 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;
 }
 
        return True;
 }
index 5af7d3e451e01ac1beea324ed3d30bf80f6a7670..e975da3e1530e16bde6b588fd11de64f121eb160 100644 (file)
@@ -43,6 +43,7 @@ static void msg_deliver(void)
   int fd;
   char *msg;
   int len;
   int fd;
   char *msg;
   int len;
+  ssize_t sz;
 
   if (! (*lp_msg_command()))
     {
 
   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;
       }
       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;
       }
     }
   } 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);
   }
     }
     SAFE_FREE(msg);
   }
index f9b70de0ace3d3e17237cf73f0d64fa63b1bf078..3db55bad14d275da0adb908071a51daaa6069c80 100644 (file)
@@ -24,7 +24,6 @@
 extern int max_send;
 extern enum protocol_types Protocol;
 extern int smb_read_error;
 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[] = {
 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",
        "\\rpcecho",
         "\\svcctl",
        "\\eventlog",
+       "\\unixinfo",
        NULL
 };
 
        NULL
 };
 
@@ -861,7 +861,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
                } else {
                        SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
                }
                } 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);
                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) {
                        &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;
                }
                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;
        }
 
                return status;
        }
 
@@ -1684,11 +1684,11 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                        &info);
 
        if (!fsp2) {
                        &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;
                }
                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;
        }
                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));
        }
 
                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);
 
 
        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);
 
        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);
        if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
                END_PROFILE(SMBnttrans);
                return ERROR_DOS(ERRSRV,ERRaccess);
index ed847826d5205495075ee13694432ab473a0f9f4..56d31c69409c4971feb9ac23d2b345986efef110 100644 (file)
 
 extern struct current_user current_user;
 extern userdom_struct current_user_info;
 
 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;
 
 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;
 };
        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;
        BOOL file_existed = VALID_STAT(*psbuf);
 
        fsp->fh->fd = -1;
-       fsp->oplock_type = NO_OPLOCK;
        errno = EPERM;
 
        /* Check permissions */
        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))  {
                /* 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;
                }
 
                        return False;
                }
 
@@ -354,7 +352,6 @@ static BOOL open_file(files_struct *fsp,
        }
        fsp->print_file = False;
        fsp->modified = False;
        }
        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;
        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.
 ****************************************************************************/
 
  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)
 {
                           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) )); \
                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
                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) )); \
                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
                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,
 
 #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;
 
 {
        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;
        }
 
                return;
        }
 
@@ -497,7 +504,26 @@ static void validate_my_share_entries(int num,
                          "share entry with an open file\n");
        }
 
                          "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) {
        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) ));
                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
 
 }
 #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).
 ****************************************************************************/
 
  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 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. */
                /* 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 */
 
        }
 
        /* 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.
         */
        
        }
 
        /*
         * 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)
 #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
 
 #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.
 ****************************************************************************/
 
 }
 
 /****************************************************************************
  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();
 {
        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 "
        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.
 
        /*
         * 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);
         */
 
        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;
        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;
        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;
        int info;
        uint32 existing_dos_attributes = 0;
        struct pending_message_list *pml = NULL;
-       uint16 port = 0;
        uint16 mid = get_current_mid();
        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) {
                /* 
 
        if (conn->printer) {
                /* 
@@ -1241,9 +1108,11 @@ files_struct *open_file_ntcreate(connection_struct *conn,
        }
 
        if ((pml = get_open_deferred_message(mid)) != NULL) {
        }
 
        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
 
                /* 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. */
 
                   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. */
                /* 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)) {
        }
 
        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 */
        }
 
        /* 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;
        }
 
                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 ));
                                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;
                        }
                                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 ));
                                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;
                        }
                                errno = ENOENT;
                                return NULL;
                        }
@@ -1369,8 +1233,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                        break;
 
                default:
                        break;
 
                default:
-                       set_saved_error_triple(ERRDOS, ERRinvalidparam,
-                                              NT_STATUS_INVALID_PARAMETER);
+                       set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);
                        return NULL;
        }
 
                        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" ));
                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;
        }
                errno = EACCES;
                return NULL;
        }
@@ -1458,45 +1320,96 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                return NULL;
        }
 
                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;
 
        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. */
 
                        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.
                         */
 
                         * 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
                                 */
                        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;
                        }
                        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)) &&
        /*
         * 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",
                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.
         */
 
 
        /*
         * 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)) {
                /*
 
        if (!fsp_open && (flags2 & O_EXCL) && (errno == EEXIST)) {
                /*
@@ -1602,22 +1524,23 @@ files_struct *open_file_ntcreate(connection_struct *conn,
        }
 
        if (!fsp_open) {
        }
 
        if (!fsp_open) {
-               if(file_existed) {
-                       unlock_share_entry(conn, dev, inode);
+               if (lck != NULL) {
+                       talloc_free(lck);
                }
                file_free(fsp);
                return NULL;
        }
 
                }
                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) { 
 
        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
                /*
                 * Now the file exists and fsp is successfully opened,
                 * fsp->dev and fsp->inode are valid and should replace the
@@ -1628,70 +1551,41 @@ files_struct *open_file_ntcreate(connection_struct *conn,
                dev = fsp->dev;
                inode = fsp->inode;
 
                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);
                        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;
                }
 
                        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
        /* 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)) {
                 */
                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;
                        fd_close(conn,fsp);
                        file_free(fsp);
                        return NULL;
@@ -1761,20 +1657,14 @@ files_struct *open_file_ntcreate(connection_struct *conn,
         * file structs.
         */
 
         * 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;
 
        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)) {
                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. */
                        /* 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);
                        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;
                }
                        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 ||
        }
        
        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. */
 
        /* 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++;
 
 
        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 ));
 
        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 ));
                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;
        }
 
                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 ));
                                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;
                                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);
                                 "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;
        }
 
                        return NULL;
        }
 
index c0c9e989a9970abe5938e7c5bdc482adc7ec8077..385f998b1ce31ac46a8cc19c056c984175b0b3c8 100644 (file)
@@ -3,6 +3,7 @@
    oplock processing
    Copyright (C) Andrew Tridgell 1992-1998
    Copyright (C) Jeremy Allison 1998 - 2001
    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
    
    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
 
 #include "includes.h"
 
 
 #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;
 /* 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 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;
 
 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.
 ****************************************************************************/
 /****************************************************************************
  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 (koplocks && koplocks->msg_waiting(fds))
                return True;
 
-       if (FD_ISSET(oplock_sock, fds))
-               return True;
-
        return False;
 }
 
        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;
        fd_set fds;
-       int selrtn = -1;
 
        FD_ZERO(&fds);
        smb_read_error = 0;
 
        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.
         */
 
         * 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)
 {
 
 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);
                koplocks->release_oplock(fsp);
+       }
 
        if (fsp->oplock_type == LEVEL_II_OPLOCK)
                level_II_oplocks_open--;
 
        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--;
                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;
        
        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.
 ****************************************************************************/
 
  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;
 {
        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. */
 
        /* 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;
        }
                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;
 }
 
        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 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);
 
        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;
 }
 
        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;
        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);
 
 
        /* 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);
 
                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
 }
 
 /****************************************************************************
  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)
 {
 ****************************************************************************/
 
 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;
        int i;
-       BOOL dummy;
+       struct share_mode_lock *lck;
 
        /*
         * If this file is level II oplocked then we need
 
        /*
         * 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 (!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", 
        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;
                        continue;
+               }
 
                /* Paranoia .... */
                if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
 
                /* 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();
                }
 
                        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)
 {
 
 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"));
 
        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
 
        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
        }
 
 #endif
        }
 
-       DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n", 
-                (int)sys_getpid(), global_oplock_port));
-
        return True;
 }
        return True;
 }
index f4405a021e103bcdb03e0ee6dcb699cf6e96c0cb..f49aa297e45618011020017e09d55db18a9b3246 100644 (file)
@@ -86,7 +86,7 @@ Disabling kernel oplock support.\n", strerror(errno) ));
  * oplock break protocol.
 ****************************************************************************/
 
  * 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;
 {
        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;
                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 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 ));
      
        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;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -214,30 +198,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.
 ****************************************************************************/
 /****************************************************************************
  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.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;
 
        koplocks.msg_waiting = irix_oplock_msg_waiting;
        koplocks.notification_fd = oplock_pipe_read;
 
index 477832c6e8eaff4281ca35d3a3ff1c8e699b1dc6..ab0c08f7fcc524b3b74eccde5ea1646889617992 100644 (file)
@@ -128,10 +128,10 @@ static int linux_setlease(int fd, int leasetype)
  * oplock break protocol.
 ****************************************************************************/
 
  * 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;
 {
        int fd;
-       struct files_struct *fsp;
+       files_struct *fsp;
 
        BlockSignals(True, RT_SIGNAL_LEASE);
        fd = fd_pending_array[0];
 
        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);
 
        /* 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;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -223,30 +198,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.
 ****************************************************************************/
 /****************************************************************************
  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.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;
 
        koplocks.msg_waiting = linux_oplock_msg_waiting;
        koplocks.notification_fd = -1;
 
index 8f9cc5288217e16b08a1eaa395ead8118a1d64d3..0b7b94cce21152193c438178802701bfbff0995e 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    process incoming packets - main loop
    Copyright (C) Andrew Tridgell 1992-1998
    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
    
    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;
 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;
 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;
 
 /****************************************************************************
 extern int max_send;
 
 /****************************************************************************
@@ -66,106 +66,72 @@ uint16 get_current_mid(void)
  for processing.
 ****************************************************************************/
 
  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.
 ****************************************************************************/
 
 
 /****************************************************************************
  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 *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;
        }
 
 
        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"));
        if(msg->buf.data == NULL) {
                DEBUG(0,("push_message: malloc fail (2)\n"));
-               SAFE_FREE(msg);
+               talloc_free(msg);
                return False;
        }
 
                return False;
        }
 
-       if (ptv) {
-               msg->msg_time = *ptv;
-       }
+       msg->request_time = request_time;
+       msg->end_time = end_time;
 
        if (private_data) {
 
        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"));
                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;
                }
        }
 
                        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;
 }
 
 
        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.
 ****************************************************************************/
 
 /****************************************************************************
  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;
 
 {
        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)) {
                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;
                }
        }
                        return;
                }
        }
@@ -176,30 +142,26 @@ void remove_sharing_violation_open_smb_message(uint16 mid)
  schedule it for immediate processing.
 ****************************************************************************/
 
  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;
 
 {
        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);
                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) {
                        (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 ));
                                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;
                }
        }
 
                        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 ));
 }
 
                mid ));
 }
 
@@ -211,13 +173,9 @@ BOOL open_was_deferred(uint16 mid)
 {
        struct pending_message_list *pml;
 
 {
        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) {
                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;
                }
        }
                        return True;
                }
        }
@@ -232,11 +190,7 @@ struct pending_message_list *get_open_deferred_message(uint16 mid)
 {
        struct pending_message_list *pml;
 
 {
        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;
                }
                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();
 
 {
        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) {
        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;
 {
        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:
 
        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
 
        /*
         * Note that this call must be before processing any SMB
@@ -358,38 +471,22 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
         */
        message_dispatch();
 
         */
        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.
         */
        /*
         * 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;
                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);
                        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;
                        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;
                                /* 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",
                                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"));
 
        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
                /*
                 * 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;
        }
                 */
                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);
 
        
        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) {
 
        /* 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
                /*
                 * 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)) {
         */
 
        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
                /*
                 * 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)
 {
 
 void respond_to_all_remaining_local_messages(void)
 {
-       char buffer[1024];
-
        /*
         * Assert we have no exclusive open oplocks.
         */
        /*
         * Assert we have no exclusive open oplocks.
         */
@@ -530,15 +632,7 @@ void respond_to_all_remaining_local_messages(void)
                return;
        }
 
                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;
 }
 
        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 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
 
 /* 
    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},
 
 /* 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},
 /* 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},
 /* 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},
 /* 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},
 /* 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},
 /* 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 },
 /* 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 },
 /* 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 },
 /* 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 },
 /* 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 },
 /* 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 },
 /* 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},
 /* 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;
                pid = sys_getpid();
 
        errno = 0;
-       set_saved_error_triple(0, 0, NT_STATUS_OK);
+       set_saved_ntstatus(NT_STATUS_OK);
 
        last_message = type;
 
 
        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);
                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);
 
                /* 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();
        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);
 
        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.
 ****************************************************************************/
 
  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;
 {
        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. */
                }
 
                        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
 #if defined(DEVELOPER)
                clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
 #endif
index 5572f47e427854ff511439466a4bf84125fb0cc2..ba22a56cfb4b9a2cdeded05518bec76ffc1a9f60 100644 (file)
@@ -30,7 +30,6 @@
 extern enum protocol_types Protocol;
 extern int max_send;
 extern int max_recv;
 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;
 
 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... */
        }
 
        /* 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,
 
        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) {
                                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;
                }
                        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);
                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... */
                   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,
 
                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) {
                                        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;
                        }
                                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);
                        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.
         */
 
         * 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) {
        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
   
                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);
 
   
        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);
        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);
        }
 
        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.
 ****************************************************************************/
 
  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);
 {
        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;
        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;
        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);
        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;
                        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)
                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;
                                         (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);
                }
 
                        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)) {
                
                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);
                }
                
                        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, 
                
                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)) {
                        /*
                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.
                                 */
                                /*
                                 * 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;
                                }
                                        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);
                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);
                         */
                        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);
        
 
        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);
        
        END_PROFILE(SMBlockingX);
        return chain_reply(inbuf,outbuf,length,bufsize);
index 1ff03174fe15b3dad287dee0dab4fff29f0677ea..8310b408d07d74a5a466b4afca49a1968b136924 100644 (file)
@@ -96,7 +96,7 @@ static void  killkids(void)
  somewhere else.
 ****************************************************************************/
 
  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"));
                         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.
 ****************************************************************************/
 
  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;
 
 {
         uint32 low_serial;
 
@@ -140,7 +141,8 @@ static BOOL open_sockets_inetd(void)
        return True;
 }
 
        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");
 }
 {
        exit_server("Got a SHUTDOWN message");
 }
@@ -621,9 +623,6 @@ void exit_server(const char *reason)
 
        print_notify_send_messages(3); /* 3 second timeout. */
 
 
        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,"");
 
        /* delete our entry in the connections database. */
        yield_connection(NULL,"");
 
index bf7287aab9ca1ac40fbab5a40dc1e8b926a6a274..fc2d8b4abb47952e528bbd4726935c75b1d63289 100644 (file)
@@ -139,6 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
                                 int length, int bufsize,
                                 DATA_BLOB *secblob)
 {
                                 int length, int bufsize,
                                 DATA_BLOB *secblob)
 {
+       TALLOC_CTX *mem_ctx;
        DATA_BLOB ticket;
        char *client, *p, *domain;
        fstring netbios_domain_name;
        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;
        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);
        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;
        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(ticket);
-       ZERO_STRUCT(auth_data);
+       ZERO_STRUCT(pac_data);
        ZERO_STRUCT(ap_rep);
        ZERO_STRUCT(ap_rep_wrapped);
        ZERO_STRUCT(response);
 
        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);
        }
 
        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);
 
 
        data_blob_free(&ticket);
 
@@ -174,7 +181,18 @@ static int reply_spnego_kerberos(connection_struct *conn,
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }
 
                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));
 
 
        DEBUG(3,("Ticket name is [%s]\n", client));
 
@@ -203,7 +221,14 @@ static int reply_spnego_kerberos(connection_struct *conn,
 
        domain = p+1;
 
 
        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
                /* 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;
 
                                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"));
                } 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);
        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);
        } 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);
                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);
                }
                        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.
 
        /* 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);
        data_blob_free(&ap_rep);
        data_blob_free(&ap_rep_wrapped);
        data_blob_free(&response);
+       talloc_destroy(mem_ctx);
 
        return -1; /* already replied */
 }
 
        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
  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,
 ***************************************************************************/
 
 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)) {
           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);
                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;
        }
 
                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) {
                DATA_BLOB chal;
                NTSTATUS nt_status;
                if (!vuser->auth_ntlmssp_state) {
index 38363bf66ae05b3882e5a216784149a37ca1cbf8..f0b7812a1e04dd8d50afe2aac48c95ec27390738 100644 (file)
@@ -27,7 +27,6 @@
 extern int max_send;
 extern enum protocol_types Protocol;
 extern int smb_read_error;
 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;
 
 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,
 
                        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.
                } 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,
                        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 {
                        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,
                }
 
                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);
                }
                if (delete_pending) {
                        return ERROR_NT(NT_STATUS_DELETE_PENDING);
                }
@@ -3454,91 +3456,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        return(-1);
 }
 
        return(-1);
 }
 
-/****************************************************************************
- 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.
 /****************************************************************************
  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 (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,
                                        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. */
                        }
 
                        /* 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);
                        }
 
                        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 (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,
                        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);
 
        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);
        if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
             && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
                END_PROFILE(SMBtrans2);
index 17ae536bc4a81875fee44cd6563e34b7da7611f9..3efb29e44c1bd2089b9f83f3e05bf43f429f88f6 100644 (file)
@@ -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");
 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");
        print_data(key);
        printf("\"\n");
-       printf("data(%d) = \"",dbuf.dsize);
+       printf("data(%d) = \"", (int)dbuf.dsize);
        print_data(dbuf);
        printf("\"\n");
        printf("}\n");
        print_data(dbuf);
        printf("\"\n");
        printf("}\n");
index d9e7b9315a05e7c7073494a0a3f603febb1e03ca..8aa57af7ab7ce69dfde836c99e0e5c6bf3cd857a 100644 (file)
@@ -331,7 +331,7 @@ static void move_rec(char *keyname, size_t keylen, char* tdbname)
 
 static int print_conn_key(TDB_DATA key)
 {
 
 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);
        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)
 {
 
 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);
        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)
 {
 
 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);
        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)
 {
        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;
        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)
 {
 
 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;
        print_data(key.dptr, key.dsize);
        printf("\n");
        return 0;
index 47f1bb2dc24d5df46d737dc1004d925063336a9a..e27880e5ea051ab71090e425466bfa3d3dce66c9 100644 (file)
@@ -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 = 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 *);
                        break;
                case 'P':
                        s = va_arg(ap,char *);
index d0b502c74e722f71f5027026840e07197fcee79a..fc180bfafe22513d35e6f096967c68dc10051031 100644 (file)
@@ -133,12 +133,12 @@ static BOOL try_unlock(struct cli_state *c, int fstype,
        return False;
 }      
 
        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", 
                      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);
 
               lock_type==READ_LOCK?"R":"W",
               (double)start, (double)start+size-1,(double)size);
 
index df0855d93d71e8784568dc63dd63323efc71f025..9ce6afa038f3d5b6e24957cd6b754e73329a4b9c 100644 (file)
@@ -98,7 +98,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
        } else {
                TDB_DATA namedata;
                /* store it for later */
        } 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);
        }
                namedata.dsize = strlen(name)+1;
                tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
        }
index ac55d703276f9a812238b5042a58889a6ca55f15..d691ab32f1db7e7574ca645a0f27f1e6f3b702ef 100644 (file)
@@ -28,7 +28,7 @@ static int pong_count;
 /****************************************************************************
 a useful function for testing the message system
 ****************************************************************************/
 /****************************************************************************
 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++;
 }
 {
        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_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) {
        }
 
        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++) {
        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++) {
        }
 
        for (i=0;i<n;i++) {
diff --git a/source3/torture/t_asn1.c b/source3/torture/t_asn1.c
new file mode 100644 (file)
index 0000000..98ee7ba
--- /dev/null
@@ -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 (file)
index 0000000..becc691
--- /dev/null
@@ -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;
+}
index 11cea53188f628013445863c0150a3540d8c8970..8ad567f17781c79682298d1317346afe43c2b3a7 100644 (file)
@@ -698,7 +698,6 @@ static BOOL run_netbench(int client)
 {
        struct cli_state *cli;
        int i;
 {
        struct cli_state *cli;
        int i;
-       fstring fname;
        pstring line;
        char cname[20];
        FILE *f;
        pstring line;
        char cname[20];
        FILE *f;
index 69acd01c1a42be54bc6e4fdfcf7f839fba847b37..b5ccf930bc6a7c758387d0cb0aca5b9db98b81ee 100644 (file)
@@ -38,7 +38,7 @@ extern pstring user_socket_options;
 /****************************************************************************
 handle completion of commands for readline
 ****************************************************************************/
 /****************************************************************************
 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;
 {
 #define MAX_COMPLETIONS 100
        char **matches;
index d07dc2a2115dd86cd0dce72509323a9e3fe202b2..24412cbe85e23d353d633925e0cb5754d3a127ee 100644 (file)
@@ -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;
 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 */
        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);
                }
                        }
                        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;
                }
                        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;
        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
        int in_packet = 0;
        struct poptOption long_options[] = {
                POPT_AUTOHELP
index e9332f58f7b9bcdea8dfa4504e6678fdac453228..4d9dec4b85b81cd046a2ea161bc98d9608327238 100644 (file)
@@ -219,36 +219,39 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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;
 {
        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 (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;
                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);
                DEBUG(0, ("couldn't not initialize pipe\n"));
                cli_shutdown(cli_tmp);
-               return NT_STATUS_UNSUCCESSFUL;
+               return nt_status;
        }
 
        *cli_dst = cli_tmp;
        }
 
        *cli_dst = cli_tmp;
-       *got_pipe = True;
+       *pp_pipe_hnd = pipe_hnd;
 
        return nt_status;
 }
 
 
        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;
 int net_use_machine_password(void) 
 {
        char *user_name = NULL;
index a2df6596b470b1d07cd948e23a4007eb84d48478..2df13cfb8f1248d85e0ded24ba8ac10148d23f83 100644 (file)
  * include
  */
 
  * 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;
 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 */
 
 
 /* INCLUDE FILES */
 
index 6a58fa9fac4934e4c268dee1a800bfe96573ac5d..49a7f1cc2ddf7f4ad49af9bd556b5f72fa1223cd 100644 (file)
@@ -969,7 +969,8 @@ static int net_ads_printer_info(int argc, const char **argv)
        return 0;
 }
 
        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;
 }
 {
        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;
         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");
        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);
 
 
        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)) {
 
         rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
         if (!ADS_ERR_OK(rc)) {
index e80e8e6f5c05b1c9360a503967c70539ed3e1968..f1522ef158297b248923fa0e800a810f0d08979c 100644 (file)
@@ -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) 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
 
    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)
 {
 
 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;
        
        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;
        }
        
                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;
        }
 
                                     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:
                                           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);
        }
 
                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;
 }
 
        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)
  */
 
  * @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 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 */
        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);
                cli = net_make_ipc_connection(conn_flags);
-       else
+       } else {
                cli = cli_arg;
                cli = cli_arg;
+       }
 
        if (!cli) {
                return -1;
 
        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)) {
        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)));
        
        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 (!(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 */
        }
 
        /* close the connection only if it was opened here */
-       if (!cli_arg)
+       if (!cli_arg) {
                cli_shutdown(cli);
                cli_shutdown(cli);
+       }
        
        talloc_destroy(mem_ctx);
        
        talloc_destroy(mem_ctx);
-
        return (!NT_STATUS_IS_OK(nt_status));
 }
 
        return (!NT_STATUS_IS_OK(nt_status));
 }
 
-
-/****************************************************************************/
-
-
 /** 
  * Force a change of the trust acccount password.
  *
 /** 
  * 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.
  **/
 
  * @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);
 }
 
                               argc, argv);
 }
 
-
-/****************************************************************************/
-
-
 /** 
  * Join a domain, the old way.
  *
 /** 
  * Join a domain, the old way.
  *
@@ -226,16 +251,29 @@ int net_rpc_changetrustpw(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
  * @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;
 
        
        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.
        /* 
           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);
 
 
        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);
 
                                              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, 
 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);
 }
                               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);
 }
 
        return net_rpc_join_newstyle(argc, argv);
 }
 
-
-
 /** 
  * display info about a rpc domain
  *
 /** 
  * display info about a rpc domain
  *
@@ -374,10 +410,13 @@ int net_rpc_join(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
  * @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;
 {
        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 */     
        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 */
                                  &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)) {
                                      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);
        }
 
        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");
                                         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;
 }
 
        return result;
 }
 
-
 /** 
  * 'net rpc info' entrypoint.
  * @param argc  Standard main() style argc
  * @param argc  Standard main() style argv.  Initial components are already
  *              stripped
  **/
 /** 
  * '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, 
 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);
 }
 
                               argc, argv);
 }
 
-
 /** 
  * Fetch domain SID into the local secrets.tdb
  *
 /** 
  * 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.
  **/
 
  * @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;
 
 {
        fstring sid_str;
 
@@ -469,13 +510,13 @@ rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name,
        return NT_STATUS_OK;
 }
 
        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
  **/
 /** 
  * '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, 
 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);
 }
 
                               argc, argv);
 }
 
-
 /****************************************************************************/
 
 /**
 /****************************************************************************/
 
 /**
@@ -514,9 +554,13 @@ static int rpc_user_usage(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
  * @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;
        
        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 */
        
 
        /* 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;
                                  &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 */
        
        
        /* 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)) {
                                      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? */
 
        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)) {
                                          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, 
  **/
 
 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;
 {
        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 */
 
        }
        /* 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;
        }
 
                                  &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);
 
                                      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 */
 
                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);
                                               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;
                }
 
                        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);
 
                                            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 */
 
 
        /* 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)) {
                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));
                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;
 
  done:
        return result;
-
-}      
+}
 
 /** 
  * Rename a user on a remote RPC server
 
 /** 
  * 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.
  **/
 
  * @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;
        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 */
        
 
        /* 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;
                                  &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 */
        
        
        /* 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)) {
                                      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;
 
        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)) {
                                       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 */
        }
 
        /* 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)) {
                                    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 */
        }
 
        /* 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)) {
                                         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 */
        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)) {
                                       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;
 }
 
        return result;
 }
 
-
 /** 
  * Rename a user on a remote RPC server
  *
 /** 
  * 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, 
  **/
 
 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;
 {
        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 */
 
 
        /* 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;
        }
 
                                  &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);
 
                                      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 */
 
                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);
                                               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;
                }
 
                        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);
 
                                            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;
 
        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)) {
                                       &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.
  **/
 
  * @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,
                        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;
 {
        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 */
        
        }
        /* 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 */
        
                                  &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 */
 
                                      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;
 
                                       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;
 
                                    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;
                                           &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;
 
                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);
 
                                              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.
  **/
 
  * @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;
 {
        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 */
        
 
        /* 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;
                                  &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 */
        
        
        /* 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)) {
                                      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);
 
                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++;
                                                 &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);
 }
 
        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,
  **/
                                                                                                              
 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;
 {
        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? */
        }
 
                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)) {
                                   &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;
         }
         
                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);
         
                                       MAXIMUM_ALLOWED_ACCESS,
                                       domain_sid, &domain_pol);
         
@@ -1236,7 +1293,7 @@ static NTSTATUS rpc_group_delete_internals(const DOM_SID *domain_sid,
                goto done;
         }
        
                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);
                                       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:
        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)) {
                                             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];
                 
                 
                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);
                
                                  &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++)
                {
                /* 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);
        
                                                    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);
 
        
                        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)) {
                                                         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;
                         }
 
                                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) {
                }
                 
                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]);
                {
                        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)
 
                        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:
 
                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);
 
                                             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;
                }
                
                        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",
                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);
 }
 
                                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;
 {
        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 */
        
 
        /* 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 */
        
                                  &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 */
 
                                      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;
                                           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);
 
        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:
        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;
 }
 
        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;
 {
        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 */
        
 
        /* 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 */
        
                                  &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 */
 
                                      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;
 
                                           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);
 
        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:
        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);
 }
 
                               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;
        DOM_SID *sids = NULL;
        uint32 *types = NULL;
+       struct rpc_pipe_client *pipe_hnd;
        POLICY_HND lsa_pol;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 
        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);
 
                                     SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
 
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                goto done;
                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)) {
                                      &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];
        }
 
                *type = types[0];
        }
 
-       cli_lsa_close(cli, mem_ctx, &lsa_pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
 
  done:
 
  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)) {
        }
 
        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;
 }
 
        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;
 {
        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);
 
 
        sid_copy(&sid, group_sid);
 
-       if (!sid_split_rid(&sid, &group_rid))
+       if (!sid_split_rid(&sid, &group_rid)) {
                return NT_STATUS_UNSUCCESSFUL;
                return NT_STATUS_UNSUCCESSFUL;
+       }
 
        /* Get sam policy handle */     
 
        /* 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);
                                  &connect_pol);
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                return result;
                return result;
+       }
        
        /* Get domain policy handle */
        
        /* 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);
                                      MAXIMUM_ALLOWED_ACCESS,
                                      &sid, &domain_pol);
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                return 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);
 
                                       1, &member,
                                       &num_rids, &rids, &rid_types);
 
@@ -1593,23 +1656,25 @@ rpc_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                goto done;
        }
 
                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);
 
                                     MAXIMUM_ALLOWED_ACCESS,
                                     group_rid, &group_pol);
 
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                goto done;
                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:
 
  done:
-       cli_samr_close(cli, mem_ctx, &connect_pol);
+       rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
        return result;
 }
 
        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;
 {
        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);
 
 
        sid_copy(&sid, alias_sid);
 
-       if (!sid_split_rid(&sid, &alias_rid))
+       if (!sid_split_rid(&sid, &alias_rid)) {
                return NT_STATUS_UNSUCCESSFUL;
                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)) {
                                   &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 */     
        }
 
        /* 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 */
                                  &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;
        }
 
                                      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);
 
                                     MAXIMUM_ALLOWED_ACCESS,
                                     alias_rid, &alias_pol);
 
-       if (!NT_STATUS_IS_OK(result))
+       if (!NT_STATUS_IS_OK(result)) {
                return 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;
                return result;
+       }
 
  done:
 
  done:
-       cli_samr_close(cli, mem_ctx, &connect_pol);
+       rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
        return result;
 }
 
        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;
 {
        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) {
        }
 
        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)) {
                                                   &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) {
        }
 
        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)) {
                                                   &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);
 }
 
                               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;
 {
        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 */     
                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 */
                                  &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;
 
                                      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);
 
                                       1, &member,
                                       &num_rids, &rids, &rid_types);
 
@@ -1762,23 +1834,24 @@ rpc_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                goto done;
        }
 
                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;
 
                                     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:
 
  done:
-       cli_samr_close(cli, mem_ctx, &connect_pol);
+       rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
        return result;
 }
 
        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;
 {
        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;
 
        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)) {
                                   &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 */     
        }
 
        /* 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 */
                                  &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;
        }
 
                                      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;
 
                                     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:
 
        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;
 }
 
        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;
 {
        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) {
        }
 
        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)) {
                                                   &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) {
        }
 
        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)) {
                                                   &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.
  **/
 
  * @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;
 {
        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 */
        
 
        /* 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;
                                  &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 */
        
        
        /* 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)) {
                                      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);
 
                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);
 
                                                 &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 */
 
                 * 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);
 
                                                  &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;
 
                                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))) &&
                                                                         &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))) &&
                                                                               &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);
                                                                    &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));
                        }
                }
        } 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 */
        
        /* 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)) {
                                      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;
 
        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);
                                                 
                                                  &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;
 
                                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))) &&
                                                                         &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))) &&
                                                                               &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);
                                                                    &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);
 }
 
                               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;
 {
        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);
 
        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;
 
                                     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);
 
                                         &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;
 
                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);
 
                                              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;
 }
 
        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;
 {
        NTSTATUS result;
+       struct rpc_pipe_client *lsa_pipe;
        POLICY_HND alias_pol, lsa_pol;
        uint32 num_members;
        DOM_SID *alias_sids;
        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;
 
        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;
 
                                     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)) {
                                         &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;
        }
 
                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;
        }
 
                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");
                                     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;
        }
 
                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");
                                     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;
        }
 
                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;
 }
  
        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;
 {
        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 */
        
 
        /* 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))
                                  &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 */
        
        
        /* 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;
 
                                      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)) {
                                       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;
 
 
                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");                
 
 
                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);
 
                                              MAXIMUM_ALLOWED_ACCESS,
                                              &sid_Builtin, &domain_pol);
 
@@ -2299,7 +2387,7 @@ rpc_group_members_internals(const DOM_SID *domain_sid,
                        return 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);
 
                                               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) {
        }
 
        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) {
                                              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]);
        }
 
                                              rids[0]);
        }
 
@@ -2339,11 +2427,13 @@ static int rpc_group_members(int argc, const char **argv)
                               argc, 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;
 {
        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 */
        
 
        /* 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))
                                  &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 */
        
        
        /* 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;
 
                                      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) {
                                       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;
        }
 
                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);
 
                                     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]);
 
        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;
 
        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.
  **/
  *
  * @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]);
 {
        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';
 
                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);
                                          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.
  **/
  *
  * @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;
 
 {
        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;
 }
 
        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;
 {
        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);
 
 
                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 */
                                                 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;
 
        if (!W_ERROR_IS_OK(result))
                goto done;
@@ -2720,16 +2817,19 @@ done:
  * @return Normal NTSTATUS return.
  **/
 
  * @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;
 
 {
        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;
 
        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.
  **/
  *
  * @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;
 {
        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;
        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 */
 
        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 */
        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;
 
         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);
 
                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,
                                                  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:
        nt_status = NT_STATUS_OK;
 
 done:
-       if (got_dst_srvsvc_pipe) {
-               cli_nt_session_close(cli_dst);
+       if (cli_dst) {
                cli_shutdown(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)
 {
 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:
 
        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;
 }
 
        return True;
 }
 
-
 /** 
  * Sync all files inside a remote share to another share (over smb)
  *
 /** 
  * 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.
  **/
  *
  * @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;
 {
        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");
 
 
        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;
 
        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.
  **/
  *
  * @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;
 {
        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 */
 
        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 */
 
        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;
 
         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 */
                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));
        
                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:
        nt_status = NT_STATUS_OK;
 
 done:
-       if (got_dst_srvsvc_pipe) {
-               cli_nt_session_close(cli_dst);
+       if (cli_dst) {
                cli_shutdown(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.
  */
  * 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;
 {
        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 */
        
 
        /* 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))
                                      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 {
        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);
 
                                                  &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;
 
                        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;
 
                                                     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;
 
                                                         &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;
 
                        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:
        result = NT_STATUS_OK;
 
  done:
-       cli_samr_close(cli, mem_ctx, &domain_pol);
+       rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
 
        return result;
 }
 
        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.
  */
 /*
  * 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;
 
 {
        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))
                                     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];
 
 
                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))
                                             &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;
                }
 
                        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);
                                             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"));
        }
 
                DEBUG(1, ("\n"));
        }
 
-       cli_lsa_close(cli, mem_ctx, &lsa_pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
 
        return NT_STATUS_OK;
 }
 
        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.
  */
  * 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;
 
 {
        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;
        
                                  &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;
        
                                          &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);
 
                                          domain_sid);
 
-       cli_samr_close(cli, mem_ctx, &connect_pol);
+       rpccli_samr_close(pipe_hnd, mem_ctx, &connect_pol);
  done:
        return result;
 }
  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;
 {
        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
  **/
 /**
  * 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;
 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
  */
 
  * 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;
 {
        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;
 
        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)) {
                                               502, &info);
 
        if (!W_ERROR_IS_OK(result)) {
@@ -4005,12 +4126,13 @@ static void rpc_share_userlist_usage(void)
  * @return Normal NTSTATUS return.
  **/
 
  * @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;
 {
        int ret;
        BOOL r;
@@ -4073,7 +4195,7 @@ rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
 
                d_printf("%s\n", netname);
 
 
                d_printf("%s\n", netname);
 
-               show_userlist(cli, mem_ctx, netname,
+               show_userlist(pipe_hnd, mem_ctx, netname,
                              num_tokens, tokens);
        }
  done:
                              num_tokens, tokens);
        }
  done:
@@ -4086,8 +4208,7 @@ rpc_share_allowedusers_internals(const DOM_SID *domain_sid,
        return NT_STATUS_OK;
 }
 
        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;
 
 {
        int result;
 
@@ -4192,13 +4313,16 @@ static int rpc_file_usage(int argc, const char **argv)
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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;
 {
        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;
 }
 
        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.
  **/
 
  * @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;
 {
        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]);
                
        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;
 
        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;
 }
 
        return W_ERROR_IS_OK(result) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
 }
 
-
 /** 
  * List files for a user on a remote RPC server
  *
 /** 
  * 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)
  **/
  *
  * @return A shell status integer (0 for success)
  **/
+
 static int rpc_file_user(int argc, const char **argv)
 {
        if (argc < 1) {
 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);
 }
 
                               argc, argv);
 }
 
-
 /** 
  * 'net rpc file' entrypoint.
  * @param argc  Standard main() style argc
 /** 
  * '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);
 }
 
        return net_run_function(argc, argv, func, rpc_file_usage);
 }
 
-/****************************************************************************/
-
-
-
 /** 
  * ABORT the shutdown of a remote RPC Server over, initshutdown pipe
  *
 /** 
  * 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, 
  **/
 
 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;
        
 {
        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");
        
        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;
 }
 
        return result;
 }
 
-
 /** 
  * ABORT the shutdown of a remote RPC Server,  over winreg pipe
  *
 /** 
  * 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, 
  **/
 
 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;
        
 {
        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");
        
        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, 
  **/
 
 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";
 {
        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;
 
        if (opt_comment) {
                msg = opt_comment;
-       } else {
-               msg = "";
        }
        }
-
        if (opt_timeout) {
                timeout = opt_timeout;
        }
 
        /* create an entry */
        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)) {
                                   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, 
  **/
 
 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";
 {
        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 */
        }
 
        /* 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");
 
        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, 
  */
 
 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;
        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 */
        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 */
                                  &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)) {
                                      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 */
 
        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)) {
                                          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;
 
                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)) {
                                               &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, 
  */
 
 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;
        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 */
 
 
        /* 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 */
                                  &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;
        }
 
                                      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);
        
                                       names, &num_rids,
                                       &user_rids, &name_types);
        
@@ -4794,7 +4926,7 @@ static NTSTATUS rpc_trustdom_del_internals(const DOM_SID *domain_sid,
                goto done;
        }
 
                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);
 
                                    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 */
 
 
        /* 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)) {
                                                    &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 */
 
 
        /* 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;
 
        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)
 {
 
 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 in_addr server_ip;
+       struct rpc_pipe_client *pipe_hnd = NULL;
        POLICY_HND connect_hnd;
        TALLOC_CTX *mem_ctx;
        NTSTATUS nt_status;
        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
         */
         
         * 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;
        }
 
                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)));
                                         &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 */
        
                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)));
                                              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));
                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;
        }
 
                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"));
                                                   opt_password,
                                                   *domain_sid)) {
                DEBUG(0, ("Storing password for trusted domain failed.\n"));
+               cli_shutdown(cli);
                return -1;
        }
        
                return -1;
        }
        
@@ -5005,16 +5143,14 @@ static int rpc_trustdom_establish(int argc, const char **argv)
         * Close the pipes and clean up
         */
         
         * 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)));
        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;
        }
 
                return -1;
        }
 
-       if (cli->pipes[cli->pipe_idx].fnum)
-               cli_nt_session_close(cli);
-
        cli_shutdown(cli);
         
        talloc_destroy(mem_ctx);
        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, 
 
 
 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);
 {
        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);
 }
 
        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, 
                                      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;
 
        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",
        
        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;
                                
        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"));
 
        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;
 {
        /* 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;
        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;
        };
 
                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;
        };
 
                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)));
                                        &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 */
                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)));
                &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;
        }
 
                return -1;
        }
 
@@ -5236,13 +5381,14 @@ static int rpc_trustdom_vampire(int argc, const char **argv)
        d_printf("Vampire trusted domains:\n\n");
 
        do {
        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)));
                                                   &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;
                };
                
                        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]);
 
 
                        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]);
                                                           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;
                                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 */
        } 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)));
        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$ */
                return -1;
        };
 
        /* close lsarpc pipe and connection to IPC$ */
-       cli_nt_session_close(cli);
        cli_shutdown(cli);
 
        talloc_destroy(mem_ctx);         
        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;
 {
        /* 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;
        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;
        };
 
                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;
        };
 
                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",
                                        &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 */
        };
        
        /* 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)) {
                &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 {
        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);
                
                                                   &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 */
        } 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;
        };
        
        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)
 
        /*
         * 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
         */
        /*
         * 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 */
                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",
                                                                 &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*/
        
        /* 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)) {
                                         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 {
                        
        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);
                                                    &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 */
        } 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));
        };
        
        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$ */
        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);         
        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) {
 
 /* 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);
 }
 
                               argc, argv);
 }
 
index 8d19ad888fc4e4ce7a1102f0f2d97edab88bcd7d..6b762563b3b2ae8e4fc247d296af7e34e1196b9d 100644 (file)
@@ -35,7 +35,6 @@
                 goto done; \
         }
 
                 goto done; \
         }
 
-
 /**
  * confirm that a domain join is still valid
  *
 /**
  * confirm that a domain join is still valid
  *
  **/
 static int net_rpc_join_ok(const char *domain)
 {
  **/
 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;
        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;
        }
 
 
        /* 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;
        }
                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:
        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);
 
        cli_shutdown(cli);
-
        return retval;
 }
 
        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;
        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;
        uint32 sec_channel_type;
+       struct rpc_pipe_client *pipe_hnd = NULL;
+       struct rpc_pipe_client *netlogon_schannel_pipe = NULL;
 
        /* rpc variables */
 
 
        /* rpc variables */
 
@@ -151,7 +139,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
 #endif
        }
 
 #endif
        }
 
-       /* Connect to remote machine */
+       /* Make authenticated connection to remote machine */
 
        if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) 
                return 1;
 
        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 */
 
 
        /* 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;
        }
 
 
                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");
 
                                          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");
 
                                                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 */
 
        /* 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;
        }
 
                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");
 
        
                                       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");
                                           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;
 
        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);
                                          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... */
 
 
        /* 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,
                                                  &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(
        /* 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",
                                   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;
 
        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");
 
                                            &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. */
 
        /* 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);
 
                                        &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 */
        /* 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;
        }
 
                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)) {
 
        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) &&
                          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;
        }
 
                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);
        /* 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:
        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 */
 
 
        /* Display success or failure */
 
@@ -364,7 +381,6 @@ done:
        return retval;
 }
 
        return retval;
 }
 
-
 /**
  * check that a join is OK
  *
 /**
  * check that a join is OK
  *
index e82db46b9f4210cd984b827a5b2172dc301cffe8..d8f3099dec86a53ccd6f129c1ea56da330392d23 100644 (file)
@@ -49,9 +49,11 @@ static const struct table_node archi_table[]= {
  * possibly be removed later on
  *
  **/
  * 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="";
 char *get_sec_mask_str(uint32 type)
 {
        static fstring typestr="";
@@ -86,10 +88,10 @@ char *get_sec_mask_str(uint32 type)
        return typestr;
 }
 
        return typestr;
 }
 
-
 /****************************************************************************
 /****************************************************************************
- display sec_ace structure
+ Display sec_ace structure.
  ****************************************************************************/
  ****************************************************************************/
+
 void display_sec_ace(SEC_ACE *ace)
 {
        fstring sid_str;
 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);
 }
 
        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;
 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;
 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 = "";
 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; 
 }
 
        return; 
 }
 
-
 static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
 {
        pstring text;
 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 
 /**
  * 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.
  **/ 
  *
  * @return Normal NTSTATUS return.
  **/ 
+
 NTSTATUS net_copy_fileattr(TALLOC_CTX *mem_ctx,
                  struct cli_state *cli_share_src,
                  struct cli_state *cli_share_dst, 
 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;
 
        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", 
        /* open file/dir on the originating server */
 
        DEBUGADD(3,("opening %s %s on originating server\n", 
@@ -429,7 +431,6 @@ out:
        return nt_status;
 }
 
        return nt_status;
 }
 
-
 /**
  * Copy a file or directory from a connected share to another connected share 
  *
 /**
  * Copy a file or directory from a connected share to another connected share 
  *
@@ -445,6 +446,7 @@ out:
  *
  * @return Normal NTSTATUS return.
  **/ 
  *
  * @return Normal NTSTATUS return.
  **/ 
+
 NTSTATUS net_copy_file(TALLOC_CTX *mem_ctx,
                       struct cli_state *cli_share_src,
                       struct cli_state *cli_share_dst, 
 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;
 }
 
        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 
 /**
  * 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.
  **/ 
  *
  * @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, 
 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;
 }
 
        return nt_status;
 }
 
-
 /**
  * Check for existing Architecture directory on a given server
  *
 /**
  * Check for existing Architecture directory on a given server
  *
@@ -682,8 +683,8 @@ out:
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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;
 {
 
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -715,7 +716,6 @@ out:
        return nt_status;
 }
 
        return nt_status;
 }
 
-
 /**
  * Copy a print-driver (level 3) from one connected print$-share to another 
  * connected print$-share
 /**
  * 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.
  **/
  *
  * @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)
                    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;
 }
 
        return NT_STATUS_OK;
 }
 
-
 /**
  * net_spoolss-functions
  * =====================
 /**
  * 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 */
        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)) {
                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;
 }
 
        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;
 
 {
        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, "\\");
 
        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 */
                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);
 
                        "", access_required,
                        servername, username, hnd);
 
@@ -874,16 +876,16 @@ net_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        return True;
 }
 
        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 */
 {
        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));
 
        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;
 }
 
        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 */
 {
        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));
 
        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 */
 {
        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));
 
        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 */
 {
        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));
                
        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;
 }
 
        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 */
 {
        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));
                        
        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 */
 {
        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)) {
                                              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;
 }
 
        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 */
                                                                                       
 {
        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));
 
        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;
 }
 
        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 */
 {
        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)) {
                        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;
 }
 
        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, 
                             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 */
        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)) {
                        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 */
                             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)) {
 
        /* 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 
  **/
  * 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;
 {
 
        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) {
 
        /* 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;
                                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 */
 
 
        /* 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;
 
                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;
        }
 
                return False;
        }
 
-       cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+       rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
 
        *num_printers = 1;
 
 
        *num_printers = 1;
 
@@ -1128,7 +1134,6 @@ out:
 
 }
 
 
 }
 
-
 /** 
  * List print-queues (including local printers that are not shared)
  *
 /** 
  * List print-queues (including local printers that are not shared)
  *
@@ -1144,9 +1149,14 @@ out:
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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; 
 {
        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");
 
 
        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++) {
                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;
 }
 
        return NT_STATUS_OK;
 }
 
-
 /** 
  * List printer-drivers from a server 
  *
 /** 
  * 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.
  **/
  *
  * @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;
 {
        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);
 
        
        ZERO_STRUCT(drv_ctr_enum);
 
-
        printf("listing printer-drivers\n");
 
         for (i=0; archi_table[i].long_archi!=NULL; i++) {
        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 */
                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)) {
                                                                                
                                archi_table[i].long_archi, 
                                &num_drivers, &drv_ctr_enum)) {
                                                                                
@@ -1254,8 +1267,11 @@ done:
  * @return Normal NTSTATUS return.
  **/
 
  * @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; 
 {
        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;
 
        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++) {
                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 */
                        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 */
                        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 */
                        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;
 
 
                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;
                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) 
 
 done:
        if (got_hnd) 
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
        
        return nt_status;
 }
 
        
        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.
  **/
  *
  * @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; 
 {
        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;
 
        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++) {
                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 */
                        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 */
                        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);
                        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) 
 
 done:
        if (got_hnd) 
-               cli_spoolss_close_printer(cli, mem_ctx, &hnd);
+               rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd);
        
        return nt_status;
 }
        
        return nt_status;
 }
@@ -1446,9 +1479,14 @@ done:
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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
 {
        /* 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;
        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;
        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 */
        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 (!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;
        }
                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;
        } 
        
                goto done;
        } 
        
-
        /* do something for all printers */
        for (i = 0; i < num_printers; i++) {
 
        /* 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 */
                */
 
                /* 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;
 
                        MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) 
                        goto done;
 
                got_hnd_src = True;
 
-
                /* open dst printer handle */
                /* 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;
 
                        PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) 
                        goto done;
 
                got_hnd_dst = True;
 
-
                /* check for existing dst printer */
                /* 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 */
                        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;
 
                        goto done;
 
-
                /* Copy Security Descriptor */
 
                /* copy secdesc (info level 2) */
                /* 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 (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"));
                        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) {
 
                /* 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) {
                        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;
                }
 
                        got_hnd_dst = False;
                }
 
@@ -1566,20 +1600,20 @@ NTSTATUS rpc_printer_migrate_security_internals(const DOM_SID *domain_sid, const
 
 done:
 
 
 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;
 }
 
                cli_shutdown(cli_dst);
        }
        return nt_status;
 }
 
-
 /** 
  * Migrate printer-forms from a src server to the dst server
  *
 /** 
  * Migrate printer-forms from a src server to the dst server
  *
@@ -1595,9 +1629,14 @@ done:
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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;
 {
        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;
        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;
        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 */
        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 (!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;
        }
                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 */
 
 
                /* 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;
 
                        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 */
 
 
                /* 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;
 
                        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 */
 
 
                /* 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 */
                        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));
                        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 */
 
                        /* 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", 
                                &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) {
 
                /* 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) {
                        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;
                }
        }
                        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)
 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)
 
        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;
                cli_shutdown(cli_dst);
        }
        return nt_status;
-
 }
 
 }
 
-
 /** 
  * Migrate printer-drivers from a src server to the dst server
  *
 /** 
  * Migrate printer-drivers from a src server to the dst server
  *
@@ -1769,9 +1805,14 @@ done:
  *
  * @return Normal NTSTATUS return.
  **/
  *
  * @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;
 {
        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;
        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;
        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;
        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"));
 
 
        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;
        
        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 */
 
 
        /* 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;
        }
                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 */
                        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 */
                        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 */
                        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;
                        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 */
                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;
                                        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 */
 
 
                        /* 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;
                        }
                                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);
                
                /* 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;
                }
                        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) {
 
                /* 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) {
                        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;
                }
        }
                        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)
 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)
 
        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);
        }
 
                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)
 /** 
  * 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.
  **/
  *
  * @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;
 {
        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;
        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 */
 
        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 (!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;
        }
                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 */
 
 
                /* 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));
                        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 */
 
 
                /* 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) {
                        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) {
                                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;
                                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 */
                   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 */
                        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);
                        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);
 
                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) {
 
                /* 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) {
                        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;
                }
        }
                        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)
 
 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)
 
        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;
 }
 
                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)
 /** 
  * 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.
  **/
  *
  * @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 */
 {
 
        /* 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;
        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;
        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 */
        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 (!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;
        }
                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 */
 
 
                /* 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;
 
                        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 */
 
 
                /* 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;
 
                        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 */
 
 
                /* 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;
 
                                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 (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 */
                                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"));
                }
 
                        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
                        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;
                
                                                    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 
                /* 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 */
                   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" */
                        &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;
                        
                        
                        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 */
                                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 */
                                        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;
 
                                                                &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 */
 
                   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;
                }
                        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 */
                                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;
                                                           &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 */
                                                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;
                                                        
                                                        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 */
                                                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;
 
                                                        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));
 
                        }
                                                subkey, reg_ctr->values[j]->valuename));
 
                        }
-                                               
+
                        TALLOC_FREE( reg_ctr );
                }
 
                        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) {
 
                /* 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) {
                        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;
                }
 
                        got_hnd_dst = False;
                }
 
@@ -2473,13 +2520,12 @@ done:
        SAFE_FREE(unc_name);
 
        if (got_hnd_src)
        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)
 
        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;
                cli_shutdown(cli_dst);
        }
        return nt_status;
index 8bb01cd89a87dfca5a23f706736e21902b8a17ba..33ccb6c1b7f0deb7a2c8476e145036a45e30c733 100644 (file)
@@ -22,7 +22,6 @@
 #include "regfio.h"
 #include "reg_objects.h"
 
 #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;
 {
        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 */
        
        
        /* 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);
        }
        
        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);
        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;
                
                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) ) {
                        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 );
                
                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) ) {
                        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 */
        
 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);
 }
 
        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;
 {
        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 */
        
        
        /* 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);
        }
        
        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);
        }
        
        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]);
        }
        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 */
        
        
        /* 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);
 }
 
        return werror_to_ntstatus(result);
 }
@@ -490,5 +497,3 @@ int net_rpc_registry(int argc, const char **argv)
                
        return net_help_registry( argc, argv );
 }
                
        return net_help_registry( argc, argv );
 }
-
-
index 3a986ed2516d13ee5a63bf533cbb84af1af9c9f9..a563475ee10fbf28c21997eb40166271ec5677b8 100644 (file)
 /********************************************************************
 ********************************************************************/
 
 /********************************************************************
 ********************************************************************/
 
-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;
 
 {
        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;
 
                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] )
        
        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] );
        }
 
                        fstrcpy( name, names[0] );
        }
 
-       cli_lsa_close(cli, mem_ctx, &pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
        return result;
 }
 
 /********************************************************************
 ********************************************************************/
 
        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)
 {
                            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 */
        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;
        }
 
                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;
 
                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] );
 
        
        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;
 }
 
 /********************************************************************
 ********************************************************************/
 
        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;
 {
        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;
 
        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) )
                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 */
                
                
                /* 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");
                        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;
        }
 
        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;
 
 {
        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;
 
        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;
 
 {
        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;
 
        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;
 {
        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;
 
        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))
                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++ ) {
        
                   
        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)) {
                
                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 */
 
                /* 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]) );
                        
                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;
 {
        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;
 
        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))
                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 */
                   
                /* 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);
                
                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;
                
                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;
 {
        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;
        
        
        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) )
                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) {
        /* 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;
        }
 
                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) {
                int i = 1;
 
                if (argv[1] == NULL) {
-                       result = enum_privileges( mem_ctx, cli, &pol );
+                       result = enum_privileges(pipe_hnd, mem_ctx, &pol );
                        goto done;
                }
 
                        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 */
                        
                        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) ) {
                                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;
                        }
                        
                                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));
                        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) {
                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) {
                        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;
                        }
                        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;
                        }
                        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;
        }
 
                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;
        }
        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:
 
 done:
-       cli_lsa_close(cli, mem_ctx, &pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &pol);
 
        return result;
 }
 
        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;
 {
        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;
        }
 
                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;  
 
        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;  
 
                                     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))
                                            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));
        }
                
                        argv[0], nt_errstr(result));
        }
                
-       cli_lsa_close(cli, mem_ctx, &dom_pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
        
        return result;
 }
        
        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;
 {
        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;
        }
 
                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;  
 
        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;  
 
                                     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))
                                               False, argc-1, argv+1);
 
        if (!NT_STATUS_IS_OK(result))
@@ -473,7 +492,7 @@ done:
                        argv[0], nt_errstr(result));
        }
        
                        argv[0], nt_errstr(result));
        }
        
-       cli_lsa_close(cli, mem_ctx, &dom_pol);
+       rpccli_lsa_close(pipe_hnd, mem_ctx, &dom_pol);
 
        return result;
 }      
 
        return result;
 }      
@@ -541,5 +560,3 @@ int net_rpc_rights(int argc, const char **argv)
                
        return net_help_rights( argc, argv );
 }
                
        return net_help_rights( argc, argv );
 }
-
-
index 403250675a5b7df5d9a455aac422f6a2f8adc3a7..f4a0ab90e8f54c663a942ef5f6f0a93c086af036 100644 (file)
@@ -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) 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
 
    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");
 }
 
        d_printf("\n");
 }
 
-
 static const char *display_time(NTTIME *nttime)
 {
        static fstring string;
 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;
         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 {
        }
 
        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;
 
                                               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]);
                 }
                 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, 
 
 /* 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];
        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,
 
        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;
        }
 
                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;
        }
                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. */
 }
 
 /* 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))
 
                    (!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;
 {
        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));
                        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)) ) {
                
                /* 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;
 }
 
        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;
 {
        fstring name;
        fstring comment;
@@ -651,8 +653,7 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
        return NT_STATUS_OK;
 }
 
        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;
 {
        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;
 }
 
        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
 {
 #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;
 
                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;
 
                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;
 
                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;
 
                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;
 
                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;
 
                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;
 
                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;
 
                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;
 }
 
 
                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) {
                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;
         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 {
        }
 
        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)) {
                                               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);
                        }
                        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;
 }
 
        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;
                       *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;
 }
 
        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(), '=', ',');
                    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;
 }
 
        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;
                         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;
 }
 
        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)
 {
                           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;
 }
 
        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)
 {
                         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;
 }
 
        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)
 {
                            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;
 }
 
        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;
 {
        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;
        NTSTATUS result;
        int k;
        TALLOC_CTX *mem_ctx;
@@ -1956,7 +1943,7 @@ fetch_database_to_ldif(struct cli_state *cli, unsigned db_type,
        }
 
        do {
        }
 
        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);
                                               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;
                }
 
                        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);
                /* 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, 
 
 /* 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;
 {
         NTSTATUS result;
-       uchar trust_password[16];
-       DOM_CRED ret_creds;
        fstring my_dom_sid_str;
        fstring rem_dom_sid_str;
        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, "
 
        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;
        }
 
                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)) {
         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 {
         } 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)) {
         }
 
        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)) {
        }
 
         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 {
         } 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)) {
         }
 
        if (!NT_STATUS_IS_OK(result)) {
@@ -2219,4 +2181,3 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid,
 fail:
        return result;
 }
 fail:
        return result;
 }
-
index 8f93ab3d060842f6f45f01c806f25a0e9adcf946..3cc4790884cc10e1802371b60a815cf88fe4a507 100644 (file)
 /********************************************************************
 ********************************************************************/
 
 /********************************************************************
 ********************************************************************/
 
-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;
 {
        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' */
        
        
        /* 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) ) {
                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;
        }
 
                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;
        }
        
        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;
 }
        
        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;
 {
        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 */
 
        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;
                }
                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;
 {
        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 */
        
        
        /* 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) ) {
                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 */
 
        
        /* 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) ) {
                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 */
        
        
        /* 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:  
                
        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;
 }      
                
        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;
 {
        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;
        }
 
                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);
        }
        
        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) ) {
                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:  
        }
 
 done:  
-       cli_svcctl_close_service( cli, mem_ctx, &hSCM  );
+       rpccli_svcctl_close_service(pipe_hnd, mem_ctx, &hSCM  );
                
        return werror_to_ntstatus(result);
 }      
                
        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;
 {
        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 */
        
 
        /* 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);
        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 */
        
        
        /* 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) ) {
                (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 */
 
        
        /* 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;
        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 */
 
 
        /* 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;
        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:  
        }
 
 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);
 }      
 
        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;
 {
        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 */
        
 
        /* 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);
        }
        
        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 );
                
                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);
 }      
                
        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;
 {
        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 */
        
 
        /* 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);
        }
        
        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 );
                
                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);
 }      
                
        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;
 {
        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 */
        
 
        /* 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);
        }
        
        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 );
                
                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);
 }      
                
        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;
 {
        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 */
        
 
        /* 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);
        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 */
        
        
        /* 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) ) {
                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 */
 
        
        /* 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;
        }
        
        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 );
        
        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:  
                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);
 }
 
        return werror_to_ntstatus(result);
 }
 
@@ -525,5 +557,3 @@ int net_rpc_service(int argc, const char **argv)
                
        return net_help_service( argc, argv );
 }
                
        return net_help_service( argc, argv );
 }
-
-
index d5845972730a3af914170d9402d063d71726131c..960379b3838e01e533a95bc9c54702a7d7f865c8 100644 (file)
@@ -31,7 +31,7 @@ static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
 
        memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
 
 
        memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
 
-       if (!process_exists(sessionid.pid)) {
+       if (!process_exists_by_pid(sessionid.pid)) {
                return 0;
        }
 
                return 0;
        }
 
@@ -101,8 +101,8 @@ static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
                return 0;
        }
 
                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)));
 
               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));
 
 
        memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
 
-       if (!process_exists(sessionid.pid))
+       if (!process_exists_by_pid(sessionid.pid)) 
                return 0;
 
        ids->num_entries += 1;
                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++) {
        }
 
        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;
                }
        }
 
                        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, 
                 guest ? "" : uidtoname(ids->entries[i].uid),
                 guest ? "" : gidtoname(ids->entries[i].gid),
                 crec.machine, 
index 3fdd657a2da0f919842f4f42557d74b68272f4df..4f3bb4d41468ff1e8237ac1ab4f6c3ce74420229 100644 (file)
@@ -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) ) {
 {
        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;
        }
                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)) {
                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);
                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;
 
        /* 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);
 #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;
        DATA_BLOB token;
        NTSTATUS status;
        ssize_t len;
+       TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request");
 
        char *user = NULL;
        char *domain = NULL;
 
        char *user = NULL;
        char *domain = NULL;
@@ -857,6 +860,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
                        return;
                }
 
                        return;
                }
 
+               status = NT_STATUS_UNSUCCESSFUL;
                if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
 
                        if ( request.negTokenInit.mechToken.data == NULL ) {
                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;
                if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
 
                        char *principal;
-                       DATA_BLOB auth_data;
                        DATA_BLOB ap_rep;
                        DATA_BLOB session_key;
 
                        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);
 
                        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,
                                                   &request.negTokenInit.mechToken,
-                                                  &principal, &auth_data, &ap_rep,
+                                                  &principal, NULL, &ap_rep,
                                                   &session_key);
 
                                                   &session_key);
 
+                       talloc_destroy(mem_ctx);
+
                        /* Now in "principal" we have the name we are
                            authenticated as. */
 
                        /* 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);
                                user = SMB_STRDUP(principal);
 
                                data_blob_free(&ap_rep);
-                               data_blob_free(&auth_data);
 
                                SAFE_FREE(principal);
                        }
 
                                SAFE_FREE(principal);
                        }
@@ -1052,15 +1056,16 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        }
 
        spnego.type = SPNEGO_NEG_TOKEN_INIT;
        }
 
        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);
 
        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;
                          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.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;
        
        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';
 
               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) {
 
 
        if (retval) {
 
@@ -1189,7 +1194,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
                        return False;
                }
 
                        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)));
 
                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 */
 
 
                /* The server offers a list of mechanisms */
 
-               const char **mechType = spnego.negTokenInit.mechTypes;
+               const char **mechType = (const char **)spnego.negTokenInit.mechTypes;
 
                while (*mechType != NULL) {
 
 
                while (*mechType != NULL) {
 
index c88c0d75797011290791b18280a512bbcd45d897..dacaa1e26f26a0a47ec29959ed2830b89632e01c 100644 (file)
@@ -118,6 +118,27 @@ static int export_groups (struct pdb_context *in, struct pdb_context *out) {
        return 0;
 }
 
        return 0;
 }
 
+/*********************************************************
+ 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
 **********************************************************/
 /*********************************************************
  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 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;
        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},
                {"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},
                {"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},
                {"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},
                {"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);
                }
                        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");
                        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) {
                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);
                        }
                                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 {
                        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);
                }
        }
                        exit(0);
                }
        }
@@ -829,7 +854,10 @@ int main (int argc, char **argv)
                } else {
                        bout = bdef;
                }
                } 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 {
                        if (!(checkparms & BIT_USER))
                                return export_groups(bin, bout);
                } else {
index 00000b5cfbe51095d40fc09daad94c08a6029378..36efcc247d56bd364120b849ade959d55ffeb86c 100644 (file)
@@ -64,6 +64,7 @@ static const struct perm_value standard_values[] = {
 };
 
 static struct cli_state *global_hack_cli;
 };
 
 static struct cli_state *global_hack_cli;
+static struct rpc_pipe_client *global_pipe_hnd;
 static POLICY_HND pol;
 static BOOL got_policy_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) {
        /* Initialise cli LSA connection */
 
        if (!global_hack_cli) {
+               NTSTATUS ret;
                global_hack_cli = connect_one("IPC$");
                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;
                }
        }
                                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. */
 
                /* 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;
                }
                                                         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() ||
        /* 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]) {
                                                 &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() ||
        }
 
        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;
                                                  &pol, 1, &str, &sids, 
                                                  &types))) {
                result = False;
index c0de85cea5d4eac826e567a4b0968e5ba28e71cd..a0304eb89a9636a504762e2a8a0855f52759e7f0 100644 (file)
@@ -34,7 +34,8 @@ static int num_replies;               /* Used by message callback fns */
 
 /* Send a message to a destination pid.  Zero means broadcast smbd. */
 
 
 /* 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;
                         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 (!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, 
                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 */
 
 
 /* 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 */
 
        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++;
 {
        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. */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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 "
 {
        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 */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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++;
 }
 
        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");
 {
        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);
 
 
        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 */
 
 
        /* 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 */
 
 
 /* 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;
 
 {
        int v;
 
@@ -203,7 +212,7 @@ static BOOL do_profile(const pid_t pid, const int argc, const char **argv)
 
 /* Return the profiling level */
 
 
 /* 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;
 {
        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;
        }
        
                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;
 
 {
        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);
 }
 
        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");
 {
        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);
 
        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 */
 
 
        /* 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 */
 
 
 /* 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");
 {
        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);
 
 
        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 */
 
 
        /* 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 */
 
 
 /* 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;
 
 {
        const char *cmd;
 
@@ -428,7 +441,8 @@ static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
                        return False;
                }
 
                        return False;
                }
 
-               notify_printer_byname(argv[2], attribute, argv[4]);
+               notify_printer_byname(argv[2], attribute,
+                                     CONST_DISCARD(char *, argv[4]));
 
                goto send;
        }
 
                goto send;
        }
@@ -443,7 +457,8 @@ send:
 
 /* Close a share */
 
 
 /* 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 "
 {
        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 */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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");
 {
        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);
 
 
        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 */
 
 
        /* 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 */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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> "
 {
        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 */
 
 
 /* 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");
 {
        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 */
 
 
 /* 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 "
 {
        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);
 }
 
                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");
 {
        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);
 }
 
        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;
 
 {
        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 */
 
 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"  },
        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 */
 
 
 /* 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 */
 
        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 */
 
 
        /* 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 */
 
 
        /* 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 */
 
 
        /* 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);
 
 
        fprintf(stderr,"Can't find pid for destination '%s'\n", dest);
 
-       return -1;
+       return result;
 }      
 
 /* Execute smbcontrol command */
 }      
 
 /* 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];
 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 */
 
        int i;
 
        /* Check destination */
 
-       if ((pid = parse_dest(dest)) == -1)
+       pid = parse_dest(dest);
+       if (!procid_valid(&pid)) {
                return False;
                return False;
+       }
 
        /* Check command */
 
 
        /* Check command */
 
index 81f7dd42bbc2c56f014d32577c090693d00c825e..c516fbb2187aa1ef7241ab86319d2b90fffc2e53 100644 (file)
@@ -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};
 
 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;
 
 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) {
        /* Initialise cli LSA connection */
 
        if (!cli_ipc) {
+               NTSTATUS ret;
                cli_ipc = connect_one("IPC$");
                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;
                }
        }
                                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. */
 
                /* 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;
                }
                                                         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() ||
        /* 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]) {
                                                 &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() ||
        }
 
        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;
                                                  &pol, 1, &str, &sids, 
                                                  &types))) {
                result = False;
index 96e4bd266b9e13cdc882039a0575071a88ed84b7..4709cfbaee105840c3c3935535ab6ea8bb19b105 100644 (file)
@@ -98,7 +98,7 @@ static BOOL Ucrit_addPid( pid_t pid )
        return True;
 }
 
        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) {
 {
        static int count;
        if (count==0) {
@@ -108,8 +108,8 @@ static void print_share_mode(share_mode_entry *e, char *fname)
        }
        count++;
 
        }
        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;
                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)
 {
                      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++;
 
        }
        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);
 }
               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;
        }
 
                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)));
 
               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));
 
 
        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;
        }
 
                return 0;
        }
 
index 2b72479ac0762082b564388a201465c17611339a..b4561b58deb4b0ce516ae5f559891d39779f82e4 100644 (file)
@@ -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;
        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;
        static char *new_local_machine = NULL;
        const char *cname;
        const char *caddr;
index d259717da0bfd25208812e7404cb9ca48281bd97..c7a7a3598ee4fe0ed71dbd44e12db152f3856819 100644 (file)
@@ -21,8 +21,6 @@
 #include "includes.h"
 #include "web/swat_proto.h"
 
 #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 */
 #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)
 {
    response */
 BOOL nmbd_running(void)
 {
+       extern struct in_addr loopback_ip;
        int fd, count, flags;
        struct in_addr *ip_list;
 
        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;
 BOOL smbd_running(void)
 {
        static struct cli_state cli;
+       extern struct in_addr loopback_ip;
 
        if (!cli_initialise(&cli))
                return False;
 
        if (!cli_initialise(&cli))
                return False;
index cc2924afde6982da66fdbed8ae8a9c66099abd98..ca671822d87a7f3301049fba276e55addd735b8c 100644 (file)
@@ -54,8 +54,8 @@ struct pri_list {
 };
 
 static int qsort_cmp_list(const void *x, const void *y) {
 };
 
 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;
        if (a->pri > b->pri) return -1;
        if (a->pri == b->pri) return 0;
        return 1;
index 9ffda5bb941bdcba9adc69d12b16b32d0107213d..8f28748918f3535282ec540782b764c4ee2b2978 100644 (file)
@@ -121,11 +121,11 @@ void stop_winbindd(void)
 }
 #endif
 /* kill a specified process */
 }
 #endif
 /* kill a specified process */
-void kill_pid(pid_t pid)
+void kill_pid(struct process_id pid)
 {
        if (geteuid() != 0) return;
 
 {
        if (geteuid() != 0) return;
 
-       if (pid <= 0) return;
+       if (procid_to_pid(&pid) <= 0) return;
 
 
-       kill(pid, SIGTERM);
+       kill(procid_to_pid(&pid), SIGTERM);
 }
 }
index 871e07b5d063a7a42bb194da3028c0c832d5b3f7..edc03183730d14c97a7eabf7bd772c1d65cfae0a 100644 (file)
 
 PIDMAP {
        PIDMAP  *next, *prev;
 
 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 */
 
        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)
 
 /* 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 */
 }
 
 /* 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) {
 {
        /* 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 */
 }
 
 /* lookup PID <-> Machine name mapping */
-static char *mapPid2Machine (pid_t pid)
+static char *mapPid2Machine (struct process_id pid)
 {
        static char pidbuf [64];
        PIDMAP *map;
 {
        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) {
        /* 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 */
 
                                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 */
        }
 
        /* 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;
 }
 
        return pidbuf;
 }
 
@@ -105,7 +106,7 @@ static char *tstring(time_t t)
        return buf;
 }
 
        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,
 {
        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];
 
        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);
                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));
        
 
        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);
 
                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) {
               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");
 
        }
        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;
 
        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),
               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;
               crec.machine,
               tstring(crec.start));
        return 0;
@@ -236,7 +238,7 @@ void status_page(void)
        int nr_running=0;
        BOOL waitup = False;
 
        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();
 
        if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
                stop_smbd();
index 15612484a354bccb35665c1f6888a5564ba6bb30..4082574e442fc7345d92386e8b255a305dd62ed8 100644 (file)
@@ -188,12 +188,12 @@ static const char* get_parm_translated(
        if(strcmp(pLabel, pTranslated) != 0)
        {
                pstr_sprintf(output,
        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, 
                   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;
 }
          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);
        }
 
                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\">",
        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:
                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;
                        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);
        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\'\">",
                       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);
        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\'\">",
                       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 
 ****************************************************************************/
 }
 
 /****************************************************************************
   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;
        
 {
        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) {
        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) ) {
        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)
 {
 ****************************************************************************/
 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);
 {
        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("<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>");
                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;
 
 {
        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);
 
        if (cgi_variable("Commit")) {
                commit_parameters(GLOBAL_SECTION_SNUM);
@@ -841,7 +892,7 @@ static void globals_page(void)
        if ( cgi_variable("AdvMode"))
                mode = 1;
 
        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 ) {
 
        ViewModeBoxes( mode );
        switch ( mode ) {
@@ -885,6 +936,8 @@ static void shares_page(void)
                snum = lp_servicenumber(share);
 
        printf("<H2>%s</H2>\n", _("Share Parameters"));
                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);
 
        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"));
                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 "));
  
         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);
        }
 
                have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
        }
 
-       show_main_buttons();
-
        page = cgi_pathinfo();
 
        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,"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 (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();
        }
        } else {
                welcome_page();
        }