r5739: sync for 3.0.12rc1 (current with SAMBA_3_0 r5738)
authorGerald Carter <jerry@samba.org>
Fri, 11 Mar 2005 10:52:54 +0000 (10:52 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 11 Mar 2005 10:52:54 +0000 (10:52 +0000)
73 files changed:
examples/LDAP/samba.schema.at.IBM-DS
examples/LDAP/samba.schema.oc.IBM-DS
examples/pdb/mysql/mysql.dump
source/Makefile.in
source/VERSION
source/auth/auth_sam.c
source/auth/auth_util.c
source/client/client.c
source/client/clitar.c
source/client/mount.cifs.c
source/configure.in
source/groupdb/mapping.c
source/include/libsmb_internal.h
source/include/libsmbclient.h
source/include/local.h
source/include/msdfs.h
source/include/passdb.h
source/include/printing.h
source/include/privileges.h
source/include/rpc_lsa.h
source/include/rpc_samr.h
source/include/smb.h
source/include/smb_macros.h
source/include/smbldap.h
source/include/trans2.h
source/lib/privileges.c
source/lib/util_pw.c
source/libsmb/cliconnect.c
source/libsmb/clidfs.c
source/libsmb/clientgen.c
source/libsmb/clilist.c
source/libsmb/libsmb_cache.c
source/libsmb/libsmbclient.c
source/locking/brlock.c
source/locking/posix.c
source/nmbd/nmbd_winsproxy.c
source/nsswitch/winbindd_passdb.c
source/nsswitch/winbindd_rpc.c
source/param/loadparm.c
source/passdb/pdb_interface.c
source/passdb/pdb_ldap.c
source/passdb/pdb_pgsql.c
source/passdb/pdb_sql.c
source/printing/nt_printing.c
source/printing/pcap.c
source/printing/print_svid.c
source/printing/printing.c
source/rpc_client/cli_lsarpc.c
source/rpc_client/cli_samr.c
source/rpc_parse/parse_lsa.c
source/rpc_parse/parse_samr.c
source/rpc_server/srv_lsa.c
source/rpc_server/srv_lsa_nt.c
source/rpc_server/srv_samr_nt.c
source/rpc_server/srv_samr_util.c
source/rpc_server/srv_spoolss_nt.c
source/rpcclient/cmd_lsarpc.c
source/sam/idmap_ldap.c
source/sam/idmap_rid.c
source/smbd/close.c
source/smbd/dir.c
source/smbd/fileio.c
source/smbd/files.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/posix_acls.c
source/smbd/reply.c
source/smbd/service.c
source/smbd/trans2.c
source/torture/torture.c
source/utils/net_help.c
source/utils/net_rpc.c
source/utils/net_rpc_rights.c

index b2c3c875dc8e0b2737627befa912ae245daff60c..f14d8e164df8fd09ee648bbe5ea93738f66e221b 100644 (file)
@@ -1,8 +1,10 @@
 ## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only
                                                                                 
 attributetypes=( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword'        DESC 'LanManager Password' EQUALITY caseIgnoreIA5Match  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.24 DBNAME( 'sambaLMPassword'  'sambaLMPassword' ) ACCESS-CLASS critical )
 
 attributetypes=( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword' DESC 'MD4 hash of the unicode password'EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.25 DBNAME( 'sambaNTPassword'  'sambaNTPassword' ) ACCESS-CLASS critical )
 
 attributetypes=( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags' DESC 'Account Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
 
@@ -44,4 +46,33 @@ attributetypes=( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid' DESC 'Next NT rid t
 
 attributetypes=( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase' DESC 'Base at which the samba RID generation algorithm should operate' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
 
-attributetypes=( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC '' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
+attributetypes=( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName' DESC 'Share Name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName' DESC 'Option Name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption' DESC 'A boolean option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption' DESC 'An integer option' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption' DESC 'A string option' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption' DESC 'A string list option' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial' DESC 'munged dial' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount' DESC 'Bad password attempt count' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime' DESC 'Time of the last bad password attempt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList' DESC 'Security ID List' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags' DESC 'Trust Password Flags' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory' DESC 'Concatenated MD4 hashes of the unicode passwords used on this account' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
+IBMAttributetypes=( 1.3.6.1.4.1.7165.2.1.54 DBNAME( 'sambaPasswordHistory'  'sambaPasswordHistory' ) ACCESS-CLASS critical )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours' DESC 'Logon Hours' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE )
+
+attributetypes=( 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 )
+
+attributetypes=( 1.3.6.1.4.1.7165.2.1.57 NAME 'sambaAccountPolicyValue' DESC 'Account Policy Value' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
index 86e1dee0aca5fb008d3558bfc9f5eeefa2009f44..2b00a5e8c642ad40939764e8ce7e1b9a3a4fcb02 100644 (file)
@@ -1,8 +1,8 @@
 ## Samba 3.0 schema for IBM Directory Server 5.1 - object classes only
 
-objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial ))
+objectclasses=( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY DESC 'Samba 3.0 Auxilary SAM Account' MUST ( uid $ sambaSID ) MAY (  cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $ sambaProfilePath $ description $ sambaUserWorkstations $ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $ sambaBadPasswordCount $ sambaBadPasswordTime $ sambaPasswordHistory $ sambaLogonHours))
 
-objectclasses=( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY  ( displayName $ description ))
+objectclasses=( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY DESC 'Samba Group Mapping' MUST ( gidNumber $ sambaSID $ sambaGroupType ) MAY  ( displayName $ description $ sambaSIDList ))
 
 objectclasses=( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL DESC 'Samba Domain Information' MUST ( sambaDomainName $ sambaSID ) MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $ sambaAlgorithmicRidBase ) )
 
@@ -12,4 +12,12 @@ objectclasses=( 1.3.6.1.4.1.7165.1.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIAR
 
 objectclasses=( 1.3.6.1.4.1.7165.1.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL DESC 'Structural Class for a SID' MUST ( sambaSID ) )
 
+objectclasses=( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY DESC 'Samba Configuration Section' MAY ( description ) )
 
+objectclasses=( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL DESC 'Samba Share Section' MUST ( sambaShareName ) MAY ( description ) )
+
+objectclasses=( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL DESC 'Samba Configuration Option' MUST ( sambaOptionName ) MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $ sambaStringListoption $ description ) )
+
+objectclasses=( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL DESC 'Samba Trust Password' MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags ) MAY ( sambaSID $ sambaPwdLastSet ))
+
+objectclasses=( 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 890135215432668de60a49bce953db97532978f8..72018ce5a707d4aab447e9a742f3809b74e5bb6e 100644 (file)
@@ -31,7 +31,7 @@ CREATE TABLE user (
        logon_divs int(9),
        hours_len int(9),
        unknown_5 int(9),
-       unknown_6 int(9),
+       unknown_6 int(9) default "1260",
        bad_password_count int(9),
        logon_count int(9)
 );
index eb39dbf88bff56ef95f6aa4f28f276f7a03b3e1e..fda2bd3d93a8567f7aad3074e11413eeef48bcc7 100644 (file)
@@ -173,8 +173,6 @@ SNPRINTF_OBJ = lib/snprintf.o
 
 WBCOMMON_OBJ = nsswitch/wb_common.o
 
-DUMMYROOT_OBJ = lib/dummyroot.o
-
 AFS_OBJ = lib/afs.o
 
 AFS_SETTOKEN_OBJ = lib/afs_settoken.o
@@ -208,7 +206,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
          lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
          lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
 
-LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
+LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummyroot.o lib/dummysmbd.o
 
 READLINE_OBJ = lib/readline.o
 
@@ -420,7 +418,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
             nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
 
 NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
-           $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+           $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) 
 
 WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
              wrepld/partners.o
@@ -436,20 +434,20 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
           $(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
           $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
           $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \
-           $(PASSCHANGE_OBJ) $(DUMMYROOT_OBJ) 
+           $(PASSCHANGE_OBJ)
 
 SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
             $(PARAM_OBJ) $(LIB_NONSMBD_OBJ)
 
 STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
-            $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ) 
+            $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(ERRORMAP_OBJ) 
              
 
 SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
        $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
        $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
-       $(PRINTBASE_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
+       $(PRINTBASE_OBJ) $(ERRORMAP_OBJ)
 
 SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
              $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
@@ -465,11 +463,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) \
 SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSCHANGE_OBJ) $(PARAM_OBJ) $(SECRETS_OBJ) \
                $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
                 $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
-               $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) $(DUMMYROOT_OBJ)
+               $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ)
 
 PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
                $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
-               $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
+               $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) 
 
 SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ)
 
@@ -485,7 +483,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
              $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
              $(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
             $(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
-            $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ)
+            $(SMBLDAP_OBJ) $(DCUTIL_OBJ) 
 
 PAM_WINBIND_PICOBJ = nsswitch/pam_winbind.@PICSUFFIX@ \
        nsswitch/wb_common.@PICSUFFIX@ lib/replace1.@PICSUFFIX@ \
@@ -518,7 +516,7 @@ LIBBIGBALLOFMUD_MAJOR = 0
 
 LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
        $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
-       $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
+       $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) 
 
 LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
 
@@ -539,7 +537,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
          $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
          $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
          $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
-         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ) $(SERVER_MUTEX_OBJ) \
+         $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
          $(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
 
 CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
@@ -568,7 +566,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                  $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
 
 LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
-               $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)  
+               $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)  
 
 NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
                  $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
@@ -580,7 +578,7 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ
 LOG2PCAP_OBJ = utils/log2pcaphex.o
 
 LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
-               $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
+               $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
 
 SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
                           $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
@@ -633,7 +631,7 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
 
 PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
                pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
-               $(DUMMYROOT_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
+               $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
                $(SECRETS_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
 
 PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
@@ -663,7 +661,7 @@ WINBINDD_OBJ = \
                $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
                $(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
                $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
-               $(DCUTIL_OBJ) $(IDMAP_OBJ) $(DUMMYROOT_OBJ) \
+               $(DCUTIL_OBJ) $(IDMAP_OBJ) \
                $(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
 
 WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -1337,7 +1335,7 @@ installclientlib: installdirs libsmbclient
 
 PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
        $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
-       $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
+       $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
 
 PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
 
index bd34be8040c9c7035d565783a5687c04afc2146a..99d75e80bdda5f43412cfe25f8d6b9fc0f16abf6 100644 (file)
@@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=12
 # e.g. SAMBA_VERSION_PRE_RELEASE=1                     #
 #  ->  "2.2.9pre1"                                     #
 ########################################################
-SAMBA_VERSION_PRE_RELEASE=1
+SAMBA_VERSION_PRE_RELEASE=
 
 ########################################################
 # For 'rc' releases the version will be                #
@@ -39,7 +39,7 @@ SAMBA_VERSION_PRE_RELEASE=1
 # e.g. SAMBA_VERSION_RC_RELEASE=1                      #
 #  ->  "3.0.0rc1"                                      #
 ########################################################
-SAMBA_VERSION_RC_RELEASE=
+SAMBA_VERSION_RC_RELEASE=1
 
 ########################################################
 # To mark SVN snapshots this should be set to 'yes'    #
index 35f85f5e6085f66f37c9f11445c710cedc6e644e..9da59f220aa1f06e68a1af1c3078496ff4945e8b 100644 (file)
@@ -232,6 +232,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
        NTSTATUS nt_status;
+       NTSTATUS update_login_attempts_status;
        DATA_BLOB user_sess_key = data_blob(NULL, 0);
        DATA_BLOB lm_sess_key = data_blob(NULL, 0);
        BOOL updated_autolock = False, updated_badpw = False;
@@ -269,7 +270,12 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
 
        nt_status = sam_password_ok(auth_context, mem_ctx, sampass, 
                                    user_info, &user_sess_key, &lm_sess_key);
-       
+
+       /* Notify passdb backend of login success/failure. If not NT_STATUS_OK the backend doesn't like the login */
+       update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
+       if (!NT_STATUS_IS_OK(update_login_attempts_status))
+               nt_status = update_login_attempts_status;
+
        if (!NT_STATUS_IS_OK(nt_status)) {
                if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && 
                    pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {  
index f3c01a58ca68efea5a1c2b9dc8d5e3917834f2f3..7cab3df99e4bd9452e0aac57e9f1b4160139cd36 100644 (file)
@@ -50,6 +50,7 @@ static int smb_create_user(const char *domain, const char *unix_username, const
        if (homedir)
                all_string_sub(add_script, "%H", homedir, sizeof(pstring));
        ret = smbrun(add_script,NULL);
+       flush_pwnam_cache();
        DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
        return ret;
 }
index 55e9f1a71d9b674c91c1d11a3777e7212304aaaa..b00e7f2273f29230a558af446d05709f191f9725 100644 (file)
@@ -217,7 +217,7 @@ static int do_dskattr(void)
        struct cli_state *targetcli;
        pstring targetpath;
 
-       if ( !cli_resolve_path( cli, cur_dir, &targetcli, targetpath ) ) {
+       if ( !cli_resolve_path( "", cli, cur_dir, &targetcli, targetpath ) ) {
                d_printf("Error in dskattr: %s\n", cli_errstr(cli));
        }
 
@@ -277,7 +277,7 @@ static int do_cd(char *newdir)
        pstrcat(cur_dir,"\\");
        dos_clean_name(cur_dir);
        
-       if ( !cli_resolve_path( cli, dname, &targetcli, targetpath ) ) {
+       if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) {
                d_printf("cd %s: %s\n", dname, cli_errstr(cli));
                pstrcpy(cur_dir,saved_dir);
                goto out;
@@ -509,7 +509,7 @@ static int do_list_queue_empty(void)
  A helper for do_list.
 ****************************************************************************/
 
-static void do_list_helper(file_info *f, const char *mask, void *state)
+static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, void *state)
 {
        if (f->mode & aDIR) {
                if (do_list_dirs && do_this_one(f)) {
@@ -526,7 +526,8 @@ static void do_list_helper(file_info *f, const char *mask, void *state)
                                return;
                        }
 
-                       pstrcpy(mask2, mask);
+                       pstrcpy(mask2, mntpoint);
+                       pstrcat(mask2, mask);
                        p = strrchr_m(mask2,'\\');
                        if (!p)
                                return;
@@ -581,8 +582,9 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
                        
                        /* check for dfs */
                        
-                       if ( !cli_resolve_path( cli, head, &targetcli, targetpath ) ) {
+                       if ( !cli_resolve_path( "", cli, head, &targetcli, targetpath ) ) {
                                d_printf("do_list: [%s] %s\n", head, cli_errstr(cli));
+                               remove_do_list_queue_head();
                                continue;
                        }
                        
@@ -607,7 +609,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
        } else {
                /* check for dfs */
                        
-               if ( cli_resolve_path( cli, mask, &targetcli, targetpath ) ) {
+               if ( cli_resolve_path( "", cli, mask, &targetcli, targetpath ) ) {
                        if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1) 
                                d_printf("%s listing %s\n", cli_errstr(targetcli), targetpath);
                }
@@ -720,7 +722,7 @@ static int do_get(char *rname, char *lname, BOOL reget)
                strlower_m(lname);
        }
 
-       if ( !cli_resolve_path( cli, rname, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, rname, &targetcli, targetname ) ) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
@@ -1016,7 +1018,7 @@ static BOOL do_mkdir(char *name)
        struct cli_state *targetcli;
        pstring targetname;
        
-       if ( !cli_resolve_path( cli, name, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, name, &targetcli, targetname ) ) {
                d_printf("mkdir %s: %s\n", name, cli_errstr(cli));
                return False;
        }
@@ -1141,7 +1143,7 @@ static int do_put(char *rname, char *lname, BOOL reput)
        struct cli_state *targetcli;
        pstring targetname;
        
-       if ( !cli_resolve_path( cli, rname, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, rname, &targetcli, targetname ) ) {
                d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
                return 1;
        }
@@ -1653,7 +1655,7 @@ static int cmd_open(void)
        }
        pstrcat(mask,buf);
 
-       if ( !cli_resolve_path( cli, mask, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
                d_printf("open %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -1683,7 +1685,7 @@ static int cmd_rmdir(void)
        }
        pstrcat(mask,buf);
 
-       if ( !cli_resolve_path( cli, mask, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
                d_printf("rmdir %s: %s\n", mask, cli_errstr(cli));
                return 1;
        }
@@ -1719,7 +1721,7 @@ static int cmd_link(void)
        pstrcat(oldname,buf);
        pstrcat(newname,buf2);
 
-       if ( !cli_resolve_path( cli, oldname, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, oldname, &targetcli, targetname ) ) {
                d_printf("link %s: %s\n", oldname, cli_errstr(cli));
                return 1;
        }
@@ -1794,7 +1796,7 @@ static int cmd_chmod(void)
        mode = (mode_t)strtol(buf, NULL, 8);
        pstrcat(src,buf2);
 
-       if ( !cli_resolve_path( cli, src, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
                d_printf("chmod %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -1942,7 +1944,7 @@ static int cmd_getfacl(void)
 
        pstrcat(src,name);
        
-       if ( !cli_resolve_path( cli, src, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2107,7 +2109,7 @@ static int cmd_stat(void)
        pstrcat(src,name);
 
        
-       if ( !cli_resolve_path( cli, src, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
                d_printf("stat %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2183,7 +2185,7 @@ static int cmd_chown(void)
        gid = (gid_t)atoi(buf2);
        pstrcat(src,buf3);
 
-       if ( !cli_resolve_path( cli, src, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
                d_printf("chown %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2255,7 +2257,7 @@ static int cmd_hardlink(void)
        pstrcat(src,buf);
        pstrcat(dest,buf2);
 
-       if ( !cli_resolve_path( cli, src, &targetcli, targetname ) ) {
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
                d_printf("hardlink %s: %s\n", src, cli_errstr(cli));
                return 1;
        }
@@ -2667,7 +2669,7 @@ static int cmd_show_connect( void )
        struct cli_state *targetcli;
        pstring targetpath;
        
-       if ( !cli_resolve_path( cli, cur_dir, &targetcli, targetpath ) ) {
+       if ( !cli_resolve_path( "", cli, cur_dir, &targetcli, targetpath ) ) {
                d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli));
                return 1;
        }
@@ -2871,7 +2873,7 @@ typedef struct {
        int len;
 } completion_remote_t;
 
-static void completion_remote_filter(file_info *f, const char *mask, void *state)
+static void completion_remote_filter(const char *mnt, file_info *f, const char *mask, void *state)
 {
        completion_remote_t *info = (completion_remote_t *)state;
 
index 14ebffb60ffd58d0b9417846bbfd78be35583ce8..524feca1d2ac5bc89ba24bf51e97bd78780a3791 100644 (file)
@@ -1761,11 +1761,7 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
                }
 
        } else {
-               if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) {
-                       if (!dry_run) {
-                               DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
-                               dry_run = True;
-                       }
+               if (tar_type=='c' && dry_run) {
                        tarhandle=-1;
                } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
                                        || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {
index d648629f9c31fd59b0f117db3a0d33f8954f8c12..7b30b98fa7b30d454b4e813131e7cb785cf20253 100755 (executable)
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <pwd.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -38,7 +39,7 @@
 #include <fcntl.h>
 
 #define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "5"
+#define MOUNT_CIFS_VERSION_MINOR "6"
 
 #ifndef MOUNT_CIFS_VENDOR_SUFFIX
 #define MOUNT_CIFS_VENDOR_SUFFIX ""
@@ -78,7 +79,7 @@ static void mount_cifs_usage(void)
        printf(" to a local directory.\n\nOptions:\n");
        printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
        printf("\nLess commonly used options:");
-       printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,\n\trw,ro,sep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec");
+       printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,\n\trw,ro,sep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,directio");
        printf("\n\nOptions not needed for servers supporting CIFS Unix extensions (e.g. most Samba versions):");
        printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>");
        printf("\n\nRarely used options:");
@@ -294,6 +295,8 @@ static int parse_options(char * options, int * filesys_flags)
                        if(!value || !*value) {
                                strncpy(data,",,,,,",5);
                        }
+               } else if (strncmp(data, "user_xattr",10) == 0) {
+                  /* do nothing - need to skip so not parsed as user name */
                } else if (strncmp(data, "user", 4) == 0) {
                        if (!value || !*value) {
                                if(data[4] == '\0') {
@@ -657,6 +660,7 @@ int main(int argc, char ** argv)
        int gid = 0;
        int optlen = 0;
        int orgoptlen = 0;
+       int retry = 0; /* set when we have to retry mount with uppercase */
        struct stat statbuf;
        struct utsname sysinfo;
        struct mntent mountent;
@@ -846,6 +850,7 @@ int main(int argc, char ** argv)
        }
        /* FIXME launch daemon (handles dfs name resolution and credential change) 
           remember to clear parms and overwrite password field before launching */
+mount_retry:
        if(orgoptions) {
                optlen = strlen(orgoptions);
                orgoptlen = optlen;
@@ -897,6 +902,8 @@ int main(int argc, char ** argv)
                printf("\nmount.cifs kernel mount options %s \n",options);
        if(mount(share_name, mountpoint, "cifs", flags, options)) {
        /* remember to kill daemon on error */
+               char * tmp;
+
                switch (errno) {
                case 0:
                        printf("mount failed but no error number set\n");
@@ -904,7 +911,21 @@ int main(int argc, char ** argv)
                case ENODEV:
                        printf("mount error: cifs filesystem not supported by the system\n");
                        break;
+               case ENXIO:
+                       if(retry == 0) {
+                               retry = 1;
+                               tmp = share_name;
+                               while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) {
+                                       *tmp = toupper((unsigned char)*tmp);
+                                       tmp++;
+                               }
+                               if(!*tmp) {
+                                       printf("retrying with upper case share name\n");
+                                       goto mount_retry;
+                               }
+                       }
                default:
+                       
                        printf("mount error %d = %s\n",errno,strerror(errno));
                }
                printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
index 40aa263c7a1357383d6a7fb2316c8a46a0fac978..7338b879eea59fb3e7678a0cc3847dd795d7e341 100644 (file)
@@ -239,6 +239,22 @@ AC_ARG_ENABLE(developer, [  --enable-developer      Turn on developer warnings a
     [if eval "test x$enable_developer = xyes"; then
         developer=yes
        CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+       # Add -Wdeclaration-after-statement if compiler supports it
+       AC_CACHE_CHECK(
+          [that the C compiler understands -Wdeclaration-after-statement],
+          samba_cv_HAVE_Wdeclaration_after_statement, [
+         AC_TRY_RUN_STRICT([
+           int main(void)
+           {
+               return 0;
+           }],[-Wdeclaration-after-statement],[$CPPFLAGS],[$LDFLAGS],
+           samba_cv_HAVE_Wdeclaration_after_statement=yes,
+           samba_cv_HAVE_Wdeclaration_after_statement=no,
+           samba_cv_HAVE_Wdeclaration_after_statement=cross)
+       ])
+       if test x"$samba_cv_HAVE_Wdeclaration_after_statement" = x"yes"; then
+           CFLAGS="${CFLAGS} -Wdeclaration-after-statement"
+       fi
     fi])
 
 AC_ARG_ENABLE(krb5developer, [  --enable-krb5developer  Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
@@ -4525,7 +4541,7 @@ SMB_MODULE(pdb_pgsql, passdb/pdb_pgsql.o, "bin/pgsql.$SHLIBEXT", PDB,
 ## end of contributed pdb_modules
 ###########################################################################
 
-SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o, "bin/ldapsam.$SHLIBEXT", PDB, 
+SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT", PDB, 
                   [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] )
 SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB)
 SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
index 1c29cc77c42a3241f978e7ffcfe472637b7f716b..5613240a12162bbe66990662549d54a57ba9a6fc 100644 (file)
@@ -1050,6 +1050,7 @@ int smb_set_primary_group(const char *unix_group, const char* unix_user)
                all_string_sub(add_script, "%g", unix_group, sizeof(add_script));
                all_string_sub(add_script, "%u", unix_user, sizeof(add_script));
                ret = smbrun(add_script,NULL);
+               flush_pwnam_cache();
                DEBUG(ret ? 0 : 3,("smb_set_primary_group: "
                         "Running the command `%s' gave %d\n",add_script,ret));
                return ret;
@@ -1060,6 +1061,7 @@ int smb_set_primary_group(const char *unix_group, const char* unix_user)
        if ( winbind_set_user_primary_group( unix_user, unix_group ) ) {
                DEBUG(3,("smb_delete_group: winbindd set the group (%s) as the primary group for user (%s)\n",
                        unix_group, unix_user));
+               flush_pwnam_cache();
                return 0;
        }               
        
index 9111f36eaf730bba8f6d45e97ad9e457038f78ea..803f9e1f10888e6e7d1639f2bb044d2de4685cb0 100644 (file)
@@ -13,6 +13,7 @@ struct _SMBCSRV {
        struct cli_state cli;
        dev_t dev;
        BOOL no_pathinfo2;
+        BOOL no_nt_session;
        int server_fd;
 
        SMBCSRV *next, *prev;
@@ -50,9 +51,18 @@ struct smbc_internal_data {
         */
        int     _initialized;
 
-       /** INTERNAL: dirent pointer location 
-        */
-       char    _dirent[512];  
+        /** INTERNAL: dirent pointer location
+         *
+         * Leave room for any urlencoded filename and the comment field.
+         *
+         * We really should use sizeof(struct smbc_dirent) plus (NAME_MAX * 3)
+         * plus whatever the max length of a comment is, plus a couple of null
+         * terminators (one after the filename, one after the comment).
+         *
+         * According to <linux/limits.h>, NAME_MAX is 255.  Is it longer
+         * anyplace else?
+         */
+       char    _dirent[1024];
 
        /** INTERNAL: server connection list
         */
@@ -61,6 +71,66 @@ struct smbc_internal_data {
        /** INTERNAL: open file/dir list
         */
        SMBCFILE * _files;
+        /** user options selections that apply to this session
+         */
+        struct _smbc_options {
+
+                /*
+                 * From how many local master browsers should the list of
+                 * workgroups be retrieved?  It can take up to 12 minutes or
+                 * longer after a server becomes a local master browser, for
+                 * it to have the entire browse list (the list of
+                 * workgroups/domains) from an entire network.  Since a client
+                 * never knows which local master browser will be found first,
+                 * the one which is found first and used to retrieve a browse
+                 * list may have an incomplete or empty browse list.  By
+                 * requesting the browse list from multiple local master
+                 * browsers, a more complete list can be generated.  For small
+                 * networks (few workgroups), it is recommended that this
+                 * value be set to 0, causing the browse lists from all found
+                 * local master browsers to be retrieved and merged.  For
+                 * networks with many workgroups, a suitable value for this
+                 * variable is probably somewhere around 3. (Default: 3).
+                 */
+                int browse_max_lmb_count;
+
+                /*
+                 * There is a difference in the desired return strings from
+                 * smbc_readdir() depending upon whether the filenames are to
+                 * be displayed to the user, or whether they are to be
+                 * appended to the path name passed to smbc_opendir() to call
+                 * a further smbc_ function (e.g. open the file with
+                 * smbc_open()).  In the former case, the filename should be
+                 * in "human readable" form.  In the latter case, the smbc_
+                 * functions expect a URL which must be url-encoded.  Those
+                 * functions decode the URL.  If, for example, smbc_readdir()
+                 * returned a file name of "abc%20def.txt", passing a path
+                 * with this file name attached to smbc_open() would cause
+                 * smbc_open to attempt to open the file "abc def.txt" since
+                 * the %20 is decoded into a space.
+                 *
+                 * Set this option to True if the names returned by
+                 * smbc_readdir() should be url-encoded such that they can be
+                 * passed back to another smbc_ call.  Set it to False if the
+                 * names returned by smbc_readdir() are to be presented to the
+                 * user.
+                 *
+                 * For backwards compatibility, this option defaults to False.
+                 */
+                int urlencode_readdir_entries;
+
+                /*
+                 * Some Windows versions appear to have a limit to the number
+                 * of concurrent SESSIONs and/or TREE CONNECTions.  In
+                 * one-shot programs (i.e. the program runs and then quickly
+                 * ends, thereby shutting down all connections), it is
+                 * probably reasonable to establish a new connection for each
+                 * share.  In long-running applications, the limitation can be
+                 * avoided by using only a single connection to each server,
+                 * and issuing a new TREE CONNECT when the share is accessed.
+                 */
+                int one_share_per_server;
+        } options;
 };     
 
 
index efb04285a7fdfef9b38ab3a37db1ba28970b7a13..abcf660c9dedfcf9f09097c25afb10c225eeb78c 100644 (file)
@@ -68,6 +68,8 @@
 #include <fcntl.h>
 #include <utime.h>
 
+#define SMBC_CTX_VERSION       1
+
 #define SMBC_BASE_FD        10000 /* smallest file descriptor returned */
 
 #define SMBC_WORKGROUP      1
@@ -125,6 +127,19 @@ struct smbc_dirent
 #define SMBC_XATTR_FLAG_REPLACE      0x2 /* fail if attr does not exist */
 
 
+/*
+ * Mappings of the DOS mode bits, as returned by smbc_getxattr() when the
+ * attribute name "system.dos_attr.mode" (or "system.dos_attr.*" or
+ * "system.*") is specified.
+ */
+#define SMBC_DOS_MODE_READONLY       0x01
+#define SMBC_DOS_MODE_HIDDEN         0x02
+#define SMBC_DOS_MODE_SYSTEM         0x04
+#define SMBC_DOS_MODE_VOLUME_ID      0x08
+#define SMBC_DOS_MODE_DIRECTORY      0x10
+#define SMBC_DOS_MODE_ARCHIVE        0x20
+
+
 #ifndef ENOATTR
 # define ENOATTR ENOENT        /* No such attribute */
 #endif
@@ -457,13 +472,13 @@ struct _SMBCCTX {
        struct smbc_internal_data * internal;
 
        int flags;
-       
 };
 
 /* Flags for SMBCCTX->flags */
 #define SMB_CTX_FLAG_USE_KERBEROS (1 << 0)
 #define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1)
 #define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2) /* don't try to do automatic anon login */
+#define SMBCCTX_FLAG_CTXVER (1 << 3 ) /* internal flag used to define _SMBCCTX version */
 
 /**@ingroup misc
  * Create a new SBMCCTX (a context).
@@ -2185,4 +2200,75 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv);
 }
 #endif
 
+/**@ingroup directory
+ * Convert strings of %xx to their single character equivalent.
+ *
+ * @param dest      A pointer to a buffer in which the resulting decoded
+ *                  string should be placed.  This may be a pointer to the
+ *                  same buffer as src_segment.
+ * 
+ * @param src       A pointer to the buffer containing the URL to be decoded.
+ *                  Any %xx sequences herein are converted to their single
+ *                  character equivalent.  Each 'x' must be a valid hexadecimal
+ *                  digit, or that % sequence is left undecoded.
+ *
+ * @param max_dest_len
+ *                  The size of the buffer pointed to by dest_segment.
+ * 
+ * @return          The number of % sequences which could not be converted
+ *                  due to lack of two following hexadecimal digits.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+int
+smbc_urldecode(char *dest, char * src, size_t max_dest_len);
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+ * Convert any characters not specifically allowed in a URL into their %xx
+ * equivalent.
+ *
+ * @param dest      A pointer to a buffer in which the resulting encoded
+ *                  string should be placed.  Unlike smbc_urldecode(), this
+ *                  must be a buffer unique from src.
+ * 
+ * @param src       A pointer to the buffer containing the string to be encoded.
+ *                  Any character not specifically allowed in a URL is converted
+ *                  into its hexadecimal value and encoded as %xx.
+ *
+ * @param max_dest_len
+ *                  The size of the buffer pointed to by dest_segment.
+ * 
+ * @returns         The remaining buffer length.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+int
+smbc_urlencode(char * dest, char * src, int max_dest_len);
+#ifdef __cplusplus
+}
+#endif
+
+
+/**@ingroup directory
+ * Return the version of the linked Samba code, and thus the version of the
+ * libsmbclient code.
+ *
+ * @return          The version string.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+const char *
+smbc_version(void);
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif /* SMBCLIENT_H_INCLUDED */
index 7d5baa21fa82c132c21bcff29ff3cefa1c46070f..8960a4af553e4db0f315e2bb75b5bb65f08de480 100644 (file)
 /* the maximum age in seconds of a password. Should be a lp_ parameter */
 #define MAX_PASSWORD_AGE (21*24*60*60)
 
+/* Default allocation roundup. */
+#define SMB_ROUNDUP_ALLOCATION_SIZE 0x100000
+
 /* shall we deny oplocks to clients that get timeouts? */
 #define FASCIST_OPLOCK_BACKOFF 1
 
index eaefa81c5b83b03c26ac7a8105fa83a883821aea..8b365d02ea6d27d8594859a9c0366d34309c18eb 100644 (file)
@@ -72,14 +72,6 @@ struct dfs_path
              return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED,     \
                               ERRSRV, ERRbadpath);; }          
 
-#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf)           \
-{ if ( (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) ||                \
-       ((get_remote_arch() == RA_WIN95) && lp_msdfs_root(SNUM(conn))) )        \
-        if (lp_host_msdfs() && dfs_redirect(name,conn,True))           \
-                return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED,          \
-                                  ERRSRV, ERRbadpath);; }          
-
 #define init_dfsroot(conn, inbuf, outbuf)                      \
 { if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) {          \
         DEBUG(2,("Serving %s as a Dfs root\n",                         \
index 3c244e7625be58732ffda80d6ead225b1be6ff0d..5a70bb45a8cc24265e761d6d0de32215eb4cbdfd 100644 (file)
@@ -241,7 +241,7 @@ struct acct_info
  * this SAMBA will load. Increment this if *ANY* changes are made to the interface. 
  */
 
-#define PASSDB_INTERFACE_VERSION 7
+#define PASSDB_INTERFACE_VERSION 8
 
 typedef struct pdb_context 
 {
@@ -267,6 +267,8 @@ typedef struct pdb_context
        
        NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
 
+       NTSTATUS (*pdb_update_login_attempts)(struct pdb_context *context, SAM_ACCOUNT *sam_acct, BOOL success);
+
        NTSTATUS (*pdb_getgrsid)(struct pdb_context *context, GROUP_MAP *map, DOM_SID sid);
        
        NTSTATUS (*pdb_getgrgid)(struct pdb_context *context, GROUP_MAP *map, gid_t gid);
@@ -371,6 +373,8 @@ typedef struct pdb_methods
        
        NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username);
        
+       NTSTATUS (*update_login_attempts)(struct pdb_methods *methods, SAM_ACCOUNT *sam_acct, BOOL success);
+
        NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid);
 
        NTSTATUS (*getgrgid)(struct pdb_methods *methods, GROUP_MAP *map, gid_t gid);
index fd1e7e43e4e89f6fa77ec77473656fa60a8fa202..43ff8dd39e83e57f8446ffcab7d8622ba35fd2f3 100644 (file)
@@ -75,7 +75,9 @@ extern struct printif cups_printif;
 
 #define MAX_CACHE_VALID_TIME 3600
 
+#ifndef PRINT_SPOOL_PREFIX
 #define PRINT_SPOOL_PREFIX "smbprn."
+#endif
 #define PRINT_DATABASE_VERSION 5
 
 /* There can be this many printing tdb's open, plus any locked ones. */
index 5266e46e3a3fee2e53bb743d927061696985e8ce..c7a9b0560da45c7bc6ed93d519040610a9dbf965 100644 (file)
@@ -6,7 +6,7 @@
    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    Copyright (C) Paul Ashton 1997
    Copyright (C) Simo Sorce 2003
-   Copyright (C) Gerald (Jerry) Carter 2004
+   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
index 01add64727c1ca744882e3450260e355d0b2b746..a0d78280c20835f448b8d409692f27e9dfb98c62 100644 (file)
@@ -698,20 +698,20 @@ typedef struct lsa_r_setsystemaccount
        NTSTATUS status;
 } LSA_R_SETSYSTEMACCOUNT;
 
+typedef struct {
+       UNIHDR hdr;
+       UNISTR2 unistring;
+} LSA_STRING;
 
-typedef struct lsa_q_lookupprivvalue
-{
+typedef struct {
        POLICY_HND pol; /* policy handle */
-       UNIHDR hdr_right;
-       UNISTR2 uni2_right;
-} LSA_Q_LOOKUPPRIVVALUE;
+       LSA_STRING privname;
+} LSA_Q_LOOKUP_PRIV_VALUE;
 
-typedef struct lsa_r_lookupprivvalue
-{
+typedef struct {
        LUID luid;
        NTSTATUS status;
-} LSA_R_LOOKUPPRIVVALUE;
-
+} LSA_R_LOOKUP_PRIV_VALUE;
 
 typedef struct lsa_q_addprivs
 {
@@ -740,5 +740,4 @@ typedef struct lsa_r_removeprivs
        NTSTATUS status;
 } LSA_R_REMOVEPRIVS;
 
-
 #endif /* _RPC_LSA_H */
index e041ee26f0b885b91b182532e8b6887e3eb18dfa..6559127df11fe26acb102c7f0a59fe81337e8e36 100644 (file)
@@ -148,6 +148,8 @@ SamrTestPrivateFunctionsUser
 
 typedef struct logon_hours_info
 {
+       uint32 max_len; /* normally 1260 bytes */
+       uint32 offset;
        uint32 len; /* normally 21 bytes */
        uint8 hours[32];
 
@@ -212,9 +214,6 @@ typedef struct sam_user_info_23
        UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
        UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
 
-       uint32 unknown_6; /* 0x0000 04ec */
-       uint32 padding4;
-
        LOGON_HRS logon_hrs;
 
 } SAM_USER_INFO_23;
@@ -336,9 +335,6 @@ typedef struct sam_user_info_21
        UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
        UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel number */
 
-       uint32 unknown_6; /* 0x0000 04ec */
-       uint32 padding4;
-
        LOGON_HRS logon_hrs;
 
 } SAM_USER_INFO_21;
index ff645134109ad57a3a1834c35138caf34abf6c2a..91ec52df2375b7c7c3c52a1b67a4f1051852187a 100644 (file)
@@ -404,7 +404,9 @@ typedef struct files_struct {
        struct timeval open_time;
        int share_mode;
        uint32 desired_access;
+       BOOL pending_modtime_owner;
        time_t pending_modtime;
+       time_t last_write_time;
        int oplock_type;
        int sent_oplock_break;
        unsigned long file_id;
@@ -1121,8 +1123,11 @@ struct bitmap {
 #define FILE_ATTRIBUTE_NORMAL          0x080L
 #define FILE_ATTRIBUTE_TEMPORARY       0x100L
 #define FILE_ATTRIBUTE_SPARSE          0x200L
+#define FILE_ATTRIBUTE_REPARSE_POINT    0x400L
 #define FILE_ATTRIBUTE_COMPRESSED      0x800L
+#define FILE_ATTRIBUTE_OFFLINE          0x1000L
 #define FILE_ATTRIBUTE_NONINDEXED      0x2000L
+#define FILE_ATTRIBUTE_ENCRYPTED        0x4000L
 #define SAMBA_ATTRIBUTES_MASK          0x7F
 
 /* Flags - combined with attributes. */
index b1ac617f5cfd79271d4655846b6db2a3bedbf65c..4fa9ffa5ace418c34caf98052185326ed1916333 100644 (file)
 /* this is how errors are generated */
 #define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
 
+#define SMB_ROUNDUP(x,r) ( ((x)%(r)) ? ( (((x)+(r))/(r))*(r) ) : (x))
+
 /* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
 #define smb_buf(buf) (((char *)(buf)) + smb_size + CVAL(buf,smb_wct)*2)
 #define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2))
index d005104dea432dcb893908d455e2eb3045a74e34..e6a6a1b7c6825bfc2fc177374e24b30689d2572b 100644 (file)
@@ -155,6 +155,31 @@ struct smbldap_state {
        struct timeval last_rebind;
 };
 
+/* struct used by both pdb_ldap.c and pdb_nds.c */
+
+struct ldapsam_privates {
+       struct smbldap_state *smbldap_state;
+
+       /* Former statics */
+       LDAPMessage *result;
+       LDAPMessage *entry;
+       int index;
+
+       const char *domain_name;
+       DOM_SID domain_sid;
+
+       /* configuration items */
+       int schema_ver;
+
+       char *domain_dn;
+
+       /* Is this NDS ldap? */
+       int is_nds_ldap;
+
+       /* ldap server location parameter */
+       char *location;
+};
+
 #endif         /* HAVE_LDAP */
 
 struct smbldap_state;
index b1fe2d9d832ec20b458618a9ad1c56d56cb2e583..68358344f4e071a3184688b95b29590458cfd80c 100644 (file)
@@ -433,7 +433,12 @@ Offset Size         Name
 #define SMB_QUERY_FILE_UNIX_LINK       0x201
 #define SMB_SET_FILE_UNIX_LINK         0x201
 #define SMB_SET_FILE_UNIX_HLINK        0x203
+/* SMB_QUERY_POSIX_ACL 0x204 see below */
+#define SMB_QUERY_XATTR                0x205 /* need for non-user XATTRs */
+#define SMB_QUERY_ATTR_FLAGS           0x206 /* chflags, chattr */
+#define SMB_SET_ATTR_FLAGS             0x206 
 
+/* Transact 2 Find First levels */
 #define SMB_FIND_FILE_UNIX             0x202
 
 /*
@@ -457,6 +462,26 @@ Offset Size         Name
 #define CIFS_UNIX_FCNTL_LOCKS_CAP           0x1
 #define CIFS_UNIX_POSIX_ACLS_CAP            0x2
 
+#define SMB_QUERY_POSIX_FS_INFO     0x201
+
+/* Returns FILE_SYSTEM_POSIX_INFO struct as follows
+      (NB   For undefined values return -1 in that field) 
+   le32 OptimalTransferSize;    bsize on some os, iosize on other os, This 
+                               is a hint to the client about best size. Server
+                               can return -1 if no preference, ie if SMB 
+                               negotiated size is adequate for optimal
+                               read/write performance
+   le32 BlockSize; (often 512 bytes) NB: BlockSize * TotalBlocks = disk space
+   le64 TotalBlocks;  redundant with other infolevels but easy to ret here
+   le64 BlocksAvail;  although redundant, easy to return
+   le64 UserBlocksAvail;      bavail 
+   le64 TotalFileNodes;
+   le64 FreeFileNodes;
+   le64 FileSysIdentifier;    fsid 
+   (NB statfs field Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call) 
+   (NB statfs field flags can come from FILE_SYSTEM_DEVICE_INFO call)  
+*/
+
 /* ... more as we think of them :-). */
 
 /* SMB POSIX ACL definitions. */
index 5a5afa4d72c062bbffab2c9783c91ecfaef3e488..8b5348e1f25026eaf69589258b83557865cc39c9 100644 (file)
@@ -3,7 +3,7 @@
    Privileges handling functions
    Copyright (C) Jean François Micouleau      1998-2001
    Copyright (C) Simo Sorce                    2002-2003
-   Copyright (C) Gerald (Jerry) Carter          2004
+   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
@@ -40,6 +40,43 @@ const SE_PRIV se_add_users       = SE_ADD_USERS;
 const SE_PRIV se_disk_operators  = SE_DISK_OPERATOR;
 const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN;
 
+/********************************************************************
+ This is a list of privileges reported by a WIndows 2000 SP4 AD DC
+ just for reference purposes:
+
+            SeCreateTokenPrivilege  Create a token object
+     SeAssignPrimaryTokenPrivilege  Replace a process level token
+             SeLockMemoryPrivilege  Lock pages in memory
+          SeIncreaseQuotaPrivilege  Increase quotas
+         SeMachineAccountPrivilege  Add workstations to domain
+                    SeTcbPrivilege  Act as part of the operating system
+               SeSecurityPrivilege  Manage auditing and security log
+          SeTakeOwnershipPrivilege  Take ownership of files or other objects
+             SeLoadDriverPrivilege  Load and unload device drivers
+          SeSystemProfilePrivilege  Profile system performance
+             SeSystemtimePrivilege  Change the system time
+   SeProfileSingleProcessPrivilege  Profile single process
+   SeIncreaseBasePriorityPrivilege  Increase scheduling priority
+         SeCreatePagefilePrivilege  Create a pagefile
+        SeCreatePermanentPrivilege  Create permanent shared objects
+                 SeBackupPrivilege  Back up files and directories
+                SeRestorePrivilege  Restore files and directories
+               SeShutdownPrivilege  Shut down the system
+                  SeDebugPrivilege  Debug programs
+                  SeAuditPrivilege  Generate security audits
+      SeSystemEnvironmentPrivilege  Modify firmware environment values
+           SeChangeNotifyPrivilege  Bypass traverse checking
+         SeRemoteShutdownPrivilege  Force shutdown from a remote system
+                 SeUndockPrivilege  Remove computer from docking station
+              SeSyncAgentPrivilege  Synchronize directory service data
+       SeEnableDelegationPrivilege  Enable computer and user accounts to be trusted for delegation
+           SeManageVolumePrivilege  Perform volume maintenance tasks
+            SeImpersonatePrivilege  Impersonate a client after authentication
+           SeCreateGlobalPrivilege  Create global objects
+
+********************************************************************/
+
+
 PRIVS privs[] = {
 #if 0  /* usrmgr will display these twice if you include them.  We don't 
           use them but we'll keep the bitmasks reserved in privileges.h anyways */
@@ -58,38 +95,6 @@ PRIVS privs[] = {
        {SE_END,                        "",                                     ""}
 };
 
-#if 0  /* not needed currently */
-PRIVS privs[] = {
-       {SE_ASSIGN_PRIMARY_TOKEN,       "SeAssignPrimaryTokenPrivilege",        "Assign Primary Token"},
-       {SE_CREATE_TOKEN,               "SeCreateTokenPrivilege",               "Create Token"},
-       {SE_LOCK_MEMORY,                "SeLockMemoryPrivilege",                "Lock Memory"},
-       {SE_INCREASE_QUOTA,             "SeIncreaseQuotaPrivilege",             "Increase Quota"},
-       {SE_UNSOLICITED_INPUT,          "SeUnsolicitedInputPrivilege",          "Unsolicited Input"},
-       {SE_TCB,                        "SeTcbPrivilege",                       "Act as part of the operating system"},
-       {SE_SECURITY,                   "SeSecurityPrivilege",                  "Security Privilege"},
-       {SE_TAKE_OWNERSHIP,             "SeTakeOwnershipPrivilege",             "Take Ownership Privilege"},
-       {SE_LOAD_DRIVER,                "SeLocalDriverPrivilege",               "Local Driver Privilege"},
-       {SE_SYSTEM_PROFILE,             "SeSystemProfilePrivilege",             "System Profile Privilege"},
-       {SE_SYSTEM_TIME,                "SeSystemtimePrivilege",                "System Time"},
-       {SE_PROF_SINGLE_PROCESS,        "SeProfileSingleProcessPrivilege",      "Profile Single Process Privilege"},
-       {SE_INC_BASE_PRIORITY,          "SeIncreaseBasePriorityPrivilege",      "Increase Base Priority Privilege"},
-       {SE_CREATE_PAGEFILE,            "SeCreatePagefilePrivilege",            "Create Pagefile Privilege"},
-       {SE_CREATE_PERMANENT,           "SeCreatePermanentPrivilege",           "Create Permanent"},
-       {SE_BACKUP,                     "SeBackupPrivilege",                    "Backup Privilege"},
-       {SE_RESTORE,                    "SeRestorePrivilege",                   "Restore Privilege"},
-       {SE_SHUTDOWN,                   "SeShutdownPrivilege",                  "Shutdown Privilege"},
-       {SE_DEBUG,                      "SeDebugPrivilege",                     "Debug Privilege"},
-       {SE_AUDIT,                      "SeAuditPrivilege",                     "Audit"},
-       {SE_SYSTEM_ENVIRONMENT,         "SeSystemEnvironmentPrivilege",         "System Environment Privilege"},
-       {SE_CHANGE_NOTIFY,              "SeChangeNotifyPrivilege",              "Change Notify"},
-       {SE_UNDOCK,                     "SeUndockPrivilege",                    "Undock"},
-       {SE_SYNC_AGENT,                 "SeSynchronizationAgentPrivilege",      "Synchronization Agent"},
-       {SE_ENABLE_DELEGATION,          "SeEnableDelegationPrivilege",          "Enable Delegation"},
-       {SE_ALL_PRIVS,                  "SeAllPrivileges",                      "All Privileges"}
-       {SE_END,                        "",                                     ""}
-};
-#endif
-
 typedef struct priv_sid_list {
        SE_PRIV privilege;
        SID_LIST sids;
@@ -177,6 +182,24 @@ static BOOL se_priv_empty( const SE_PRIV *mask )
        return se_priv_equal( &p1, &se_priv_none );
 }
 
+/*********************************************************************
+ Lookup the SE_PRIV value for a privilege name 
+*********************************************************************/
+
+BOOL se_priv_from_name( const char *name, SE_PRIV *mask )
+{
+       int i;
+
+       for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
+               if ( strequal( privs[i].name, name ) ) {
+                       se_priv_copy( mask, &privs[i].se_priv );
+                       return True;
+               }
+       }
+
+       return False;
+}
+
 /***************************************************************************
  dump an SE_PRIV structure to the log files
 ****************************************************************************/
@@ -369,11 +392,9 @@ LUID_ATTR get_privilege_luid( SE_PRIV *mask )
        
        for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
        
-               /* just use the index+1 (so its non-zero) into the 
-                  array as the lower portion of the LUID */
-       
                if ( se_priv_equal( &privs[i].se_priv, mask ) ) {
                        priv_luid.luid.low = GENERATE_LUID_LOW(i);
+                       break;
                }
        }
 
@@ -664,9 +685,6 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l
 {
        int i;
 
-       /* don't crash if the source pointer is NULL (since we don't
-          do priviledges now anyways) */
-
        if ( !old_la )
                return NT_STATUS_OK;
 
@@ -731,26 +749,6 @@ char* luid_to_privilege_name(const LUID *set)
        return name;
 }
 
-/****************************************************************************
- Convert an LUID to a 32-bit mask
-****************************************************************************/
-
-SE_PRIV* luid_to_privilege_mask(const LUID *set)
-{
-       static SE_PRIV mask;
-       int max = count_all_privileges();
-       
-       if (set->high != 0)
-               return NULL;
-
-       if ( set->low > max )
-               return NULL;
-
-       se_priv_copy( &mask, &privs[set->low - 1].se_priv );
-
-       return &mask;
-}
-
 /*******************************************************************
  return the number of elements in the privlege array
 *******************************************************************/
index 0d7ffe09e9bc343a8b6358a9868d380e8c532a53..13349bad34e256684fc6d2b60e2e795859ca466a 100644 (file)
@@ -70,6 +70,20 @@ static void init_pwnam_cache(void)
        return;
 }
 
+void flush_pwnam_cache(void)
+{
+       int i;
+
+       init_pwnam_cache();
+
+       for (i=0; i<PWNAMCACHE_SIZE; i++) {
+               if (pwnam_cache[i] == NULL)
+                       continue;
+
+               passwd_free(&pwnam_cache[i]);
+       }
+}
+
 struct passwd *getpwnam_alloc(const char *name) 
 {
        int i;
index 01a92a89ba4884dca7f5314f2487d73b75938348..aa37a29391c53e131116e1ce1d2a200f8a850973 100644 (file)
@@ -888,7 +888,12 @@ BOOL cli_ulogoff(struct cli_state *cli)
        if (!cli_receive_smb(cli))
                return False;
 
-       return !cli_is_error(cli);
+       if (cli_is_error(cli)) {
+               return False;
+       }
+
+        cli->cnum = -1;
+        return True;
 }
 
 /****************************************************************************
index 6db6330ca6bf64ae6f2c5f954a7b16c41903ae37..e4308fdb5a4a5a55a2e060c369e646cc102299b5 100644 (file)
@@ -27,6 +27,7 @@
 struct client_connection {
        struct client_connection *prev, *next;
        struct cli_state *cli;
+       pstring mount;
 };
 
 /* global state....globals reek! */
@@ -166,6 +167,44 @@ static struct cli_state *do_connect( const char *server, const char *share,
        return c;
 }
 
+/****************************************************************************
+****************************************************************************/
+
+static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt )
+{
+       struct client_connection *p;
+       int i;
+
+       for ( p=connections,i=0; p; p=p->next,i++ ) {
+               if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) )
+                       break;
+       }
+       
+       if ( p ) {
+               pstrcpy( p->mount, mnt );
+               dos_clean_name( p->mount );
+       }
+}
+
+/****************************************************************************
+****************************************************************************/
+
+const char * cli_cm_get_mntpoint( struct cli_state *c )
+{
+       struct client_connection *p;
+       int i;
+
+       for ( p=connections,i=0; p; p=p->next,i++ ) {
+               if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) )
+                       break;
+       }
+       
+       if ( p )
+               return p->mount;
+               
+       return NULL;
+}
+
 /********************************************************************
  Add a new connection to the list
 ********************************************************************/
@@ -186,6 +225,8 @@ static struct cli_state* cli_cm_connect( const char *server, const char *share,
 
        DLIST_ADD( connections, node );
 
+       cli_cm_set_mntpoint( node->cli, "" );
+
        return node->cli;
 
 }
@@ -443,7 +484,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path,
        char *p;
        size_t pathlen = 2*(strlen(path)+1);
        uint16 num_referrals;
-       CLIENT_DFS_REFERRAL *referrals;
+       CLIENT_DFS_REFERRAL *referrals = NULL;
        
        memset(param, 0, sizeof(param));
        SSVAL(param, 0, 0x03);  /* max referral level */
@@ -516,7 +557,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path,
 /********************************************************************
 ********************************************************************/
 
-BOOL cli_resolve_path( struct cli_state *rootcli, const char *path,
+BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path,
                        struct cli_state **targetcli, pstring targetpath )
 {
        CLIENT_DFS_REFERRAL *refs = NULL;
@@ -528,6 +569,8 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path,
        fstring server, share;
        struct cli_state *newcli;
        pstring newpath;
+       pstring newmount;
+       char *ppath;
        
        SMB_STRUCT_STAT sbuf;
        uint32 attributes;
@@ -585,16 +628,29 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path,
                        
                return False;
        }
+       
+       /* parse out the consumed mount path */
+       /* trim off the \server\share\ */
 
-       /* check for another dfs refeerrali, note that we are not 
+       fullpath[consumed/2] = '\0';
+       dos_clean_name( fullpath );
+       ppath = strchr_m( fullpath, '\\' );
+       ppath = strchr_m( ppath+1, '\\' );
+       ppath = strchr_m( ppath+1, '\\' );
+       ppath++;
+       
+       pstr_sprintf( newmount, "%s\\%s", mountpt, ppath );
+       cli_cm_set_mntpoint( *targetcli, newmount );
+
+       /* check for another dfs referral, note that we are not 
           checking for loops here */
 
        if ( !strequal( targetpath, "\\" ) ) {
-               if ( cli_resolve_path( *targetcli, targetpath, &newcli, newpath ) ) {
+               if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) {
                        *targetcli = newcli;
                        pstrcpy( targetpath, newpath );
                }
        }
-       
+
        return True;
 }
index 369fba3521877104ce1967d26e4969b79b80f514..b7bc780a1a195ccd1f00fe579c9f72d329da77de 100644 (file)
@@ -282,6 +282,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
        cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
        cli->oplock_handler = cli_oplock_ack;
        cli->case_sensitive = False;
+       cli->smb_rw_error = 0;
 
        cli->use_spnego = lp_client_use_spnego();
 
index 532fb3a772e4147b592efe27c2a2168b38ea762e..dcac17d24a2383427691f8a46e5d8dafcb9fe19c 100644 (file)
@@ -143,7 +143,7 @@ static int interpret_long_filename(struct cli_state *cli,
 ****************************************************************************/
 
 int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, 
-                void (*fn)(file_info *, const char *, void *), void *state)
+                void (*fn)(const char *, file_info *, const char *, void *), void *state)
 {
 #if 0
        int max_matches = 1366; /* Match W2k - was 512. */
@@ -191,7 +191,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
                        setup = TRANSACT2_FINDFIRST;
                        SSVAL(param,0,attribute); /* attribute */
                        SSVAL(param,2,max_matches); /* max count */
-                       SSVAL(param,4,4+2);     /* resume required + close on end */
+                       SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
                        SSVAL(param,6,info_level); 
                        SIVAL(param,8,0);
                        p = param+12;
@@ -203,7 +203,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
                        SSVAL(param,2,max_matches); /* max count */
                        SSVAL(param,4,info_level); 
                        SIVAL(param,6,0); /* ff_resume_key */
-                       SSVAL(param,10,8+4+2);  /* continue + resume required + close on end */
+                       /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren
+                          can miss filenames. Use last filename continue instead. JRA */
+                       SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
                        p = param+12;
                        p += clistr_push(cli, param+12, mask, sizeof(param)-12, 
                                         STR_TERMINATE);
@@ -268,24 +270,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
                p = rdata;
 
                /* we might need the lastname for continuations */
-               if (ff_lastname > 0) {
-                       switch(info_level) {
-                               case 260:
-                                       clistr_pull(cli, mask, p+ff_lastname,
-                                                   sizeof(mask), 
-                                                   data_len-ff_lastname,
-                                                   STR_TERMINATE);
-                                       break;
-                               case 1:
-                                       clistr_pull(cli, mask, p+ff_lastname+1,
-                                                   sizeof(mask), 
-                                                   -1,
-                                                   STR_TERMINATE);
-                                       break;
-                               }
-               } else {
-                       pstrcpy(mask,"");
-               }
  
                /* and add them to the dirlist pool */
                tdl = SMB_REALLOC(dirlist,dirlist_len + data_len);
@@ -299,10 +283,18 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
 
                /* put in a length for the last entry, to ensure we can chain entries 
                   into the next packet */
-               for (p2=p,i=0;i<(ff_searchcount-1);i++)
-                       p2 += interpret_long_filename(cli,info_level,p2,NULL);
+               for (p2=p,i=0;i<(ff_searchcount-1);i++) {
+                       p2 += interpret_long_filename(cli,info_level,p2,&finfo);
+               }
                SSVAL(p2,0,data_len - PTR_DIFF(p2,p));
 
+               /* we might need the lastname for continuations */
+               if (ff_lastname > 0) {
+                       pstrcpy(mask, finfo.name);
+               } else {
+                       pstrcpy(mask,"");
+               }
+
                /* grab the data for later use */
                memcpy(dirlist+dirlist_len,p,data_len);
                dirlist_len += data_len;
@@ -322,8 +314,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
        }
 
        for (p=dirlist,i=0;i<total_received;i++) {
+               const char *mnt = cli_cm_get_mntpoint( cli );
+               
                p += interpret_long_filename(cli,info_level,p,&finfo);
-               fn(&finfo, Mask, state);
+               
+               fn( mnt,&finfo, Mask, state );
        }
 
        /* free up the dirlist buffer */
@@ -365,7 +360,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi
 ****************************************************************************/
 
 int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, 
-                void (*fn)(file_info *, const char *, void *), void *state)
+                void (*fn)(const char *, file_info *, const char *, void *), void *state)
 {
        char *p;
        int received = 0;
@@ -472,7 +467,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
        for (p=dirlist,i=0;i<num_received;i++) {
                file_info finfo;
                p += interpret_short_filename(cli, p,&finfo);
-               fn(&finfo, Mask, state);
+               fn("\\", &finfo, Mask, state);
        }
 
        SAFE_FREE(dirlist);
@@ -485,7 +480,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
 ****************************************************************************/
 
 int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, 
-            void (*fn)(file_info *, const char *, void *), void *state)
+            void (*fn)(const char *, file_info *, const char *, void *), void *state)
 {
        if (cli->protocol <= PROTOCOL_LANMAN1)
                return cli_list_old(cli, Mask, attribute, fn, state);
index ddb27535233abc12488d12085a0b365f6c41dda1..71399f14db8edbe500edabcd4fa67cc83344f218 100644 (file)
@@ -1,3 +1,4 @@
+
 /* 
    Unix SMB/CIFS implementation.
    SMB client library implementation (server cache)
 
 #include "includes.h"
 
-/*
- * Define this to get the real SMBCFILE and SMBCSRV structures 
- */
-#define _SMBC_INTERNAL
 #include "include/libsmbclient.h"
-
+#include "../include/libsmb_internal.h"
 /*
  * Structure we use if internal caching mechanism is used 
  * nothing fancy here.
@@ -115,11 +112,53 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server,
        
        /* Search the cache lines */
        for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) {
+
                if (strcmp(server,srv->server_name)  == 0 &&
-                   strcmp(share,srv->share_name)    == 0 &&
                    strcmp(workgroup,srv->workgroup) == 0 &&
-                   strcmp(user, srv->username)  == 0) 
-                       return srv->server;
+                   strcmp(user, srv->username)  == 0) {
+
+                        /* If the share name matches, we're cool */
+                        if (strcmp(share, srv->share_name) == 0) {
+                                return srv->server;
+                        }
+
+                        /*
+                         * We only return an empty share name or the attribute
+                         * server on an exact match (which would have been
+                         * caught above).
+                         */
+                        if (*share == '\0' || strcmp(share, "*IPC$") == 0)
+                                continue;
+
+                        /*
+                         * Never return an empty share name or the attribute
+                         * server if it wasn't what was requested.
+                         */
+                        if (*srv->share_name == '\0' ||
+                            strcmp(srv->share_name, "*IPC$") == 0)
+                                continue;
+
+                        /*
+                         * If we're only allowing one share per server, then
+                         * a connection to the server (other than the
+                         * attribute server connection) is cool.
+                         */
+                        if (context->internal->options.one_share_per_server) {
+                                /*
+                                 * The currently connected share name
+                                 * doesn't match the requested share, so
+                                 * disconnect from the current share.
+                                 */
+                                if (! cli_tdis(&srv->server->cli)) {
+                                        /* Sigh. Couldn't disconnect. */
+                                        cli_shutdown(&srv->server->cli);
+                                        context->callbacks.remove_cached_srv_fn(context, srv->server);
+                                        continue;
+                                }
+
+                                return srv->server;
+                        }
+                }
        }
 
        return NULL;
index 8eeadc8a7831996153b6adc995fff38b08209825..c876720cfab5bb90bdf3a8e4d92bea070ce1dcf9 100644 (file)
@@ -5,7 +5,7 @@
    Copyright (C) Richard Sharpe 2000, 2002
    Copyright (C) John Terpstra 2000
    Copyright (C) Tom Jansen (Ninja ISD) 2002 
-   Copyright (C) Derrell Lipman 2003
+   Copyright (C) Derrell Lipman 2003, 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
 
 #include "include/libsmb_internal.h"
 
+
+/*
+ * DOS Attribute values (used internally)
+ */
+typedef struct DOS_ATTR_DESC
+{
+    int mode;
+    unsigned long long size;
+    time_t a_time;
+    time_t c_time;
+    time_t m_time;
+    unsigned long long inode;
+} DOS_ATTR_DESC;
+
+
 /*
  * Internal flags for extended attributes
  */
@@ -84,73 +99,103 @@ hex2int( unsigned int _char )
     return -1;
 }
 
-static void 
-decode_urlpart(char *segment, size_t sizeof_segment)
+/*
+ * smbc_urldecode()
+ *
+ * Convert strings of %xx to their single character equivalent.  Each 'x' must
+ * be a valid hexadecimal digit, or that % sequence is left undecoded.
+ *
+ * dest may, but need not be, the same pointer as src.
+ *
+ * Returns the number of % sequences which could not be converted due to lack
+ * of two following hexadecimal digits.
+ */
+int
+smbc_urldecode(char *dest, char * src, size_t max_dest_len)
 {
-    int old_length = strlen(segment);
-    int new_length = 0;
-    int new_length2 = 0;
-    int i = 0;
-    pstring new_segment;
-    char *new_usegment = 0;
-
-    if ( !old_length ) {
-       return;
-    }
+        int old_length = strlen(src);
+        int i = 0;
+        int err_count = 0;
+        pstring temp;
+        char * p;
 
-    /* make a copy of the old one */
-    new_usegment = (char*)SMB_MALLOC( old_length * 3 + 1 );
-
-    while( i < old_length ) {
-       int bReencode = False;
-       unsigned char character = segment[ i++ ];
-       if ((character <= ' ') || (character > 127))
-           bReencode = True;
-
-       new_usegment [ new_length2++ ] = character;
-       if (character == '%' ) {
-           int a = i+1 < old_length ? hex2int( segment[i] ) : -1;
-           int b = i+1 < old_length ? hex2int( segment[i+1] ) : -1;
-           if ((a == -1) || (b == -1)) { /* Only replace if sequence is valid */
-               /* Contains stray %, make sure to re-encode! */
-               bReencode = True;
-           } else {
-               /* Valid %xx sequence */
-               character = a * 16 + b; /* Replace with value of %dd */
-               if (!character)
-                   break; /* Stop at %00 */
-
-               new_usegment [ new_length2++ ] = (unsigned char) segment[i++];
-               new_usegment [ new_length2++ ] = (unsigned char) segment[i++];
-           }
-       }
-       if (bReencode) {
-           unsigned int c = character / 16;
-           new_length2--;
-           new_usegment [ new_length2++ ] = '%';
-
-           c += (c > 9) ? ('A' - 10) : '0';
-           new_usegment[ new_length2++ ] = c;
-
-           c = character % 16;
-           c += (c > 9) ? ('A' - 10) : '0';
-           new_usegment[ new_length2++ ] = c;
-       }
-
-       new_segment [ new_length++ ] = character;
-    }
-    new_segment [ new_length ] = 0;
+        if ( old_length == 0 ) {
+                return 0;
+        }
+
+        p = temp;
+        while ( i < old_length ) {
+                unsigned char character = src[ i++ ];
 
-    free(new_usegment);
+                if (character == '%') {
+                        int a = i+1 < old_length ? hex2int( src[i] ) : -1;
+                        int b = i+1 < old_length ? hex2int( src[i+1] ) : -1;
 
-    /* realloc it with unix charset */
-    pull_utf8_allocate(&new_usegment, new_segment);
+                        /* Replace valid sequence */
+                        if (a != -1 && b != -1) {
 
-    /* this assumes (very safely) that removing %aa sequences
-       only shortens the string */
-    strncpy(segment, new_usegment, sizeof_segment);
+                                /* Replace valid %xx sequence with %dd */
+                                character = (a * 16) + b;
+
+                                if (character == '\0') {
+                                        break; /* Stop at %00 */
+                                }
+
+                                i += 2;
+                        } else {
+
+                                err_count++;
+                        }
+                }
+
+                *p++ = character;
+        }
+
+        *p = '\0';
+
+        strncpy(dest, temp, max_dest_len);
+
+        return err_count;
+}
+
+/*
+ * smbc_urlencode()
+ *
+ * Convert any characters not specifically allowed in a URL into their %xx
+ * equivalent.
+ *
+ * Returns the remaining buffer length.
+ */
+int
+smbc_urlencode(char * dest, char * src, int max_dest_len)
+{
+        char hex[] = "0123456789ABCDEF";
+
+        for (; *src != '\0' && max_dest_len >= 3; src++) {
+
+                if ((*src < '0' &&
+                     *src != '-' &&
+                     *src != '.') ||
+                    (*src > '9' &&
+                     *src < 'A') ||
+                    (*src > 'Z' &&
+                     *src < 'a' &&
+                     *src != '_') ||
+                    (*src > 'z')) {
+                        *dest++ = '%';
+                        *dest++ = hex[(*src >> 4) & 0x0f];
+                        *dest++ = hex[*src & 0x0f];
+                        max_dest_len -= 3;
+                } else {
+                        *dest++ = *src;
+                        max_dest_len--;
+                }
+        }
 
-    free(new_usegment);
+        *dest++ = '\0';
+        max_dest_len--;
+        
+        return max_dest_len;
 }
 
 /*
@@ -158,10 +203,7 @@ decode_urlpart(char *segment, size_t sizeof_segment)
  *
  * The general format of an SMB URI is explain in Christopher Hertel's CIFS
  * book, at http://ubiqx.org/cifs/Appendix-D.html.  We accept a subset of the
- * general format ("smb:" only; we do not look for "cifs:"), and expand on
- * what he calls "context", herein called "options" to avoid conflict with the
- * SMBCCTX context used throughout this library.  We add the "mb" keyword
- * which applies as follows:
+ * general format ("smb:" only; we do not look for "cifs:").
  *
  *
  * We accept:
@@ -169,37 +211,28 @@ decode_urlpart(char *segment, size_t sizeof_segment)
  *
  * Meaning of URLs:
  *
- * smb://           show all workgroups known by the first master browser found
- * smb://?mb=.any   same as smb:// (i.e. without any options)
- *
- * smb://?mb=.all   show all workgroups known by every master browser found.
- *                  Why might you want this?  In an "appliance" application
- *                  where the workgroup/domain being used on the local network
- *                  is not known ahead of time, but where one wanted to
- *                  provide network services via samba, a unique workgroup
- *                  could be used.  However, when the appliance is first
- *                  started, the local samba instance's master browser has not
- *                  synchronized with the other master browser(s) on the
- *                  network (and might not synchronize for 12 minutes) and
- *                  therefore is not aware of the workgroup/ domain names
- *                  available on the network.  This option may be used to
- *                  overcome the problem of a libsmbclient application
- *                  arbitrarily selecting the local (still ignorant) master
- *                  browser to obtain its list of workgroups/domains and
- *                  getting back a practically emmpty list.  By requesting
- *                  the list of workgroups/domains from each found master
- *                  browser on the local network, a complete list of
- *                  workgroups/domains can be built.
+ * smb://           Show all workgroups.
  *
- * smb://?mb=name   NOT YET IMPLEMENTED -- show all workgroups known by the
- *                  master browser whose name is "name"
+ *                  The method of locating the list of workgroups varies
+ *                  depending upon the setting of the context variable
+ *                  context->options.browse_max_lmb_count.  This value
+ *                  determine the maximum number of local master browsers to
+ *                  query for the list of workgroups.  In order to ensure that
+ *                  a complete list of workgroups is obtained, all master
+ *                  browsers must be queried, but if there are many
+ *                  workgroups, the time spent querying can begin to add up.
+ *                  For small networks (not many workgroups), it is suggested
+ *                  that this variable be set to 0, indicating query all local
+ *                  master browsers.  When the network has many workgroups, a
+ *                  reasonable setting for this variable might be around 3.
  *
  * smb://name/      if name<1D> or name<1B> exists, list servers in
  *                  workgroup, else, if name<20> exists, list all shares
  *                  for server ...
  *
- * If "options" are provided, this function returns the entire option list as
- * a string, for later parsing by the caller.
+ * If "options" are provided, this function returns the entire option list as a
+ * string, for later parsing by the caller.  Note that currently, no options
+ * are supported.
  */
 
 static const char *smbc_prefix = "smb:";
@@ -246,7 +279,7 @@ smbc_parse_path(SMBCCTX *context,
        p += 2;  /* Skip the double slash */
 
         /* See if any options were specified */
-        if ( (q = strrchr(p, '?')) != NULL ) {
+        if ((q = strrchr(p, '?')) != NULL ) {
                 /* There are options.  Null terminate here and point to them */
                 *q++ = '\0';
                 
@@ -333,11 +366,11 @@ smbc_parse_path(SMBCCTX *context,
        all_string_sub(path, "/", "\\", 0);
 
  decoding:
-       decode_urlpart(path, path_len);
-       decode_urlpart(server, server_len);
-       decode_urlpart(share, share_len);
-       decode_urlpart(user, user_len);
-       decode_urlpart(password, password_len);
+       (void) smbc_urldecode(path, path, path_len);
+       (void) smbc_urldecode(server, server, server_len);
+       (void) smbc_urldecode(share, share, share_len);
+       (void) smbc_urldecode(user, user, user_len);
+       (void) smbc_urldecode(password, password, password_len);
 
        return 0;
 }
@@ -352,28 +385,8 @@ static int smbc_check_options(char *server, char *share, char *path, char *optio
         /* No options at all is always ok */
         if (! *options) return 0;
 
-        /*
-         * For right now, we only support a very few options possibilities.
-         * No options are supported if server, share, or path are not empty.
-         * If all are empty, then we support the following two choices right
-         * now:
-         *
-         *   mb=.any
-         *   mb=.all
-         */
-        if ((*server || *share || *path) && *options) {
-                /* Invalid: options provided with server, share, or path */
-                DEBUG(1, ("Found unsupported options (%s) with non-empty server, share, or path\n", options));
-                return -1;
-        }
-
-        if (strcmp(options, "mb=.any") != 0 &&
-            strcmp(options, "mb=.all") != 0) {
-                DEBUG(1, ("Found unsupported options (%s)\n", options));
-                return -1;
-        }
-
-        return 0;
+        /* Currently, we don't support any options. */
+        return -1;
 }
 
 /*
@@ -452,8 +465,6 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv)
 
        context->callbacks.remove_cached_srv_fn(context, srv);
        
-       SAFE_FREE(srv);
-       
        return 0;
 }
 
@@ -471,7 +482,7 @@ SMBCSRV *find_server(SMBCCTX *context,
 
        srv = context->callbacks.get_cached_srv_fn(context, server, share, 
                                                   workgroup, username);
-       
+
        if (!auth_called && !srv && (!username[0] || !password[0])) {
                context->callbacks.auth_fn(server, share,
                                            workgroup, sizeof(fstring),
@@ -512,6 +523,7 @@ SMBCSRV *find_server(SMBCCTX *context,
                          */
                        goto check_server_cache; 
                }
+
                return srv;
        }
 
@@ -541,6 +553,8 @@ SMBCSRV *smbc_server(SMBCCTX *context,
        pstring ipenv;
        struct in_addr ip;
        int tried_reverse = 0;
+        int port_try_first;
+        int port_try_next;
   
        zero_ip(&ip);
        ZERO_STRUCT(c);
@@ -552,25 +566,56 @@ SMBCSRV *smbc_server(SMBCCTX *context,
 
         srv = find_server(context, server, share,
                           workgroup, username, password);
-        if (srv)
+
+        /*
+         * If we found a connection and we're only allowed one share per
+         * server...
+         */
+        if (srv && *share != '\0' && context->internal->options.one_share_per_server) {
+
+                /*
+                 * ... then if there's no current connection to the share,
+                 * connect to it.  find_server(), or rather the function
+                 * pointed to by context->callbacks.get_cached_srv_fn which
+                 * was called by find_server(), will have issued a tree
+                 * disconnect if the requested share is not the same as the
+                 * one that was already connected.
+                 */
+                if (srv->cli.cnum == (uint16) -1) {
+                        /* Ensure we have accurate auth info */
+                        context->callbacks.auth_fn(server, share,
+                                                   workgroup, sizeof(fstring),
+                                                   username, sizeof(fstring),
+                                                   password, sizeof(fstring));
+
+                        if (! cli_send_tconX(&srv->cli, share, "?????",
+                                             password, strlen(password)+1)) {
+                        
+                                errno = smbc_errno(context, &srv->cli);
+                                cli_shutdown(&srv->cli);
+                                context->callbacks.remove_cached_srv_fn(context, srv);
+                                srv = NULL;
+                        }
+
+                        /* Regenerate the dev value since it's based on both server and share */
+                        if (srv) {
+                                srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
+                        }
+                }
+        }
+        
+        /* If we have a connection... */
+        if (srv) {
+
+                /* ... then we're done here.  Give 'em what they came for. */
                 return srv;
+        }
 
        make_nmb_name(&calling, context->netbios_name, 0x0);
        make_nmb_name(&called , server, 0x20);
 
        DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server));
   
-#if 0 /* djl: obsolete code?  neither group nor p is used beyond here */
-       if ((p=strchr_m(server_n,'#')) && 
-           (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) {
-    
-               fstrcpy(group, server_n);
-               p = strchr_m(group,'#');
-               *p = 0;
-               
-       }
-#endif
-
        DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server));
 
  again:
@@ -593,18 +638,31 @@ SMBCSRV *smbc_server(SMBCCTX *context,
 
        c.timeout = context->timeout;
 
-        /* Force use of port 139 for first try, so browse lists can work */
-        c.port = 139;
+        /*
+         * Force use of port 139 for first try if share is $IPC, empty, or
+         * null, so browse lists can work
+         */
+        if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0)
+        {
+                port_try_first = 139;
+                port_try_next = 445;
+        }
+        else
+        {
+                port_try_first = 445;
+                port_try_next = 139;
+        }
+
+        c.port = port_try_first;
 
        if (!cli_connect(&c, server_n, &ip)) {
-                /*
-                 * Port 139 connection failed.  Try port 445 to handle
-                 * connections to newer (e.g. XP) hosts with NetBIOS disabled.
-                 */
-                c.port = 445;
+
+                /* First connection attempt failed.  Try alternate port. */
+                c.port = port_try_next;
+
                 if (!cli_connect(&c, server_n, &ip)) {
-                       cli_shutdown(&c);
-                        errno = ENETUNREACH;
+                        cli_shutdown(&c);
+                        errno = ETIMEDOUT;
                         return NULL;
                 }
        }
@@ -625,7 +683,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
 
                    if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
                      DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server));
-                     errno = ENOENT;
+                     errno = ETIMEDOUT;
                      return NULL;
                    }
 
@@ -639,7 +697,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
 
                  }
                }
-               errno = ENOENT;
+               errno = ETIMEDOUT;
                return NULL;
        }
   
@@ -647,7 +705,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
   
        if (!cli_negprot(&c)) {
                cli_shutdown(&c);
-               errno = ENOENT;
+               errno = ETIMEDOUT;
                return NULL;
        }
 
@@ -732,10 +790,11 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
        SMBCSRV *ipc_srv=NULL;
 
         /*
-         * See if we've already created this special connection.  Reference
-         * our "special" share name 'IPC$$'.
+         * See if we've already created this special connection.  Reference our
+         * "special" share name '*IPC$', which is an impossible real share name
+         * due to the leading asterisk.
          */
-        ipc_srv = find_server(context, server, "IPC$$",
+        ipc_srv = find_server(context, server, "*IPC$",
                               workgroup, username, password);
         if (!ipc_srv) {
 
@@ -801,7 +860,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
                 errno = 0;      /* let cache function set errno if it likes */
                 if (context->callbacks.add_cached_srv_fn(context, ipc_srv,
                                                          server,
-                                                         "IPC$$",
+                                                         "*IPC$",
                                                          workgroup,
                                                          username)) {
                         DEBUG(3, (" Failed to add server to cache\n"));
@@ -1621,21 +1680,15 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
 {
        struct smbc_dirent *dirent;
        int size;
-       char *u_name = NULL, *u_comment = NULL;
-       size_t u_name_len = 0, u_comment_len = 0;
-
-       if (name)
-           u_name_len = push_utf8_allocate(&u_name, name);
-       if (comment)
-           u_comment_len = push_utf8_allocate(&u_comment, comment);
+        int name_length = (name == NULL ? 0 : strlen(name));
+        int comment_len = (comment == NULL ? 0 : strlen(comment));
 
        /*
         * Allocate space for the dirent, which must be increased by the 
-        * size of the name and the comment and 1 for the null on the comment.
-        * The null on the name is already accounted for.
+        * size of the name and the comment and 1 each for the null terminator.
         */
 
-       size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1;
+       size = sizeof(struct smbc_dirent) + name_length + comment_len + 2;
     
        dirent = SMB_MALLOC(size);
 
@@ -1682,18 +1735,15 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint
        dir->dir_end->dirent = dirent;
        
        dirent->smbc_type = type;
-       dirent->namelen = u_name_len;
-       dirent->commentlen = u_comment_len;
+       dirent->namelen = name_length;
+       dirent->commentlen = comment_len;
        dirent->dirlen = size;
   
-       strncpy(dirent->name, (u_name?u_name:""), dirent->namelen + 1);
+       strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
 
        dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
-       strncpy(dirent->comment, (u_comment?u_comment:""), dirent->commentlen + 1);
+       strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
        
-       SAFE_FREE(u_comment);
-       SAFE_FREE(u_name);
-
        return 0;
 
 }
@@ -1781,7 +1831,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state)
 }
 
 static void
-dir_list_fn(file_info *finfo, const char *mask, void *state)
+dir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
 {
 
        if (add_dirent((SMBCFILE *)state, finfo->name, "", 
@@ -1807,14 +1857,14 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
        if (!context || !context->internal ||
            !context->internal->_initialized) {
                DEBUG(4, ("no valid context\n"));
-               errno = EINVAL;
+               errno = EINVAL + 8192;
                return NULL;
 
        }
 
        if (!fname) {
                DEBUG(4, ("no valid fname\n"));
-               errno = EINVAL;
+               errno = EINVAL + 8193;
                return NULL;
        }
 
@@ -1826,7 +1876,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                             password, sizeof(password),
                             options, sizeof(options))) {
                DEBUG(4, ("no valid path\n"));
-               errno = EINVAL;
+               errno = EINVAL + 8194;
                return NULL;
        }
 
@@ -1835,7 +1885,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
         /* Ensure the options are valid */
         if (smbc_check_options(server, share, path, options)) {
                 DEBUG(4, ("unacceptable options (%s)\n", options));
-                errno = EINVAL;
+                errno = EINVAL + 8195;
                 return NULL;
         }
 
@@ -1861,108 +1911,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
        dir->file     = False;
        dir->dir_list = dir->dir_next = dir->dir_end = NULL;
 
-       if (server[0] == (char)0 &&
-            (! *options || strcmp(options, "mb=.any") == 0)) {
-                struct in_addr server_ip;
-               if (share[0] != (char)0 || path[0] != (char)0) {
-
-                       errno = EINVAL;
-                       if (dir) {
-                               SAFE_FREE(dir->fname);
-                               SAFE_FREE(dir);
-                       }
-                       return NULL;
-               }
-
-               /*
-                 * We have server and share and path empty ... so list the
-                 * workgroups first try to get the LMB for our workgroup, and
-                 * if that fails, try the DMB
-                 */
-
-               pstrcpy(workgroup, lp_workgroup());
-
-               if (!find_master_ip(workgroup, &server_ip)) {
-                   struct user_auth_info u_info;
-                   struct cli_state *cli;
-
-                   DEBUG(4, ("Unable to find master browser for workgroup %s\n", 
-                             workgroup));
-
-                   /* find the name of the server ... */
-                   pstrcpy(u_info.username, user);
-                   pstrcpy(u_info.password, password);
-
-                   if (!(cli = get_ipc_connect_master_ip_bcast(workgroup, &u_info))) {
-                       DEBUG(4, ("Unable to find master browser by "
-                                 "broadcast\n"));
-                       errno = ENOENT;
-                       return NULL;
-                   }
-
-                   fstrcpy(server, cli->desthost);
-
-                   cli_shutdown(cli);
-               } else {
-                    /*
-                     * Do a name status query to find out the name of the
-                     * master browser.  We use <01><02>__MSBROWSE__<02>#01 if
-                     * *#00 fails because a domain master browser will not
-                     * respond to a wildcard query (or, at least, an NT4
-                     * server acting as the domain master browser will not).
-                     *
-                     * We might be able to use ONLY the query on MSBROWSE, but
-                     * that's not yet been tested with all Windows versions,
-                     * so until it is, leave the original wildcard query as
-                     * the first choice and fall back to MSBROWSE if the
-                     * wildcard query fails.
-                     */
-                   if (!name_status_find("*", 0, 0x20, server_ip, server) &&
-                        !name_status_find(MSBROWSE, 1, 0x1b, server_ip, server)) {
-                       errno = ENOENT;
-                       return NULL;
-                   }
-               }       
-
-               DEBUG(4, ("using workgroup %s %s\n", workgroup, server));
-
-                /*
-                 * Get a connection to IPC$ on the server if we do not already
-                 * have one
-                 */
-                
-               srv = smbc_server(context, server, "IPC$", workgroup, user, password);
-                if (!srv) {
-                    
-                    if (dir) {
-                        SAFE_FREE(dir->fname);
-                        SAFE_FREE(dir);
-                    }
-                    return NULL;
-                }
-                
-               dir->srv = srv;
-               dir->dir_type = SMBC_WORKGROUP;
-
-               /* Now, list the stuff ... */
-
-               if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn,
-                                      (void *)dir)) {
-
-                        DEBUG(1, ("Could not enumerate domains using '%s'\n", workgroup));
-                       if (dir) {
-                               SAFE_FREE(dir->fname);
-                               SAFE_FREE(dir);
-                       }
-
-                       return NULL;
-
-               }
-        } else if (server[0] == (char)0 &&
-                   (! *options || strcmp(options, "mb=.all") == 0)) {
+       if (server[0] == (char)0) {
 
                 int i;
                 int count;
+                int max_lmb_count;
                 struct ip_service *ip_list;
                 struct ip_service server_addr;
                 struct user_auth_info u_info;
@@ -1970,7 +1923,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
 
                if (share[0] != (char)0 || path[0] != (char)0) {
 
-                       errno = EINVAL;
+                       errno = EINVAL + 8196;
                        if (dir) {
                                SAFE_FREE(dir->fname);
                                SAFE_FREE(dir);
@@ -1978,6 +1931,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                        return NULL;
                }
 
+                /* Determine how many local master browsers to query */
+                max_lmb_count = (context->internal->options.browse_max_lmb_count == 0
+                                 ? INT_MAX
+                                 : context->internal->options.browse_max_lmb_count);
+
                 pstrcpy(u_info.username, user);
                 pstrcpy(u_info.password, password);
 
@@ -2001,11 +1959,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
                         count = 1;
                 }
 
-                for (i = 0; i < count; i++) {
+                for (i = 0; i < count && i < max_lmb_count; i++) {
                         DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip)));
                         
                         cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info);
-
                        /* cli == NULL is the master browser refused to talk or 
                           could not be found */
                        if ( !cli )
@@ -2060,7 +2017,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
 
                        if (path[0] != (char)0) { /* Should not have empty share with path */
 
-                               errno = EINVAL;
+                               errno = EINVAL + 8197;
                                if (dir) {
                                        SAFE_FREE(dir->fname);
                                        SAFE_FREE(dir);
@@ -2254,12 +2211,54 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir)
 
 }
 
+static void smbc_readdir_internal(SMBCCTX * context,
+                                  struct smbc_dirent *dest,
+                                  struct smbc_dirent *src,
+                                  int max_namebuf_len)
+{
+        if (context->internal->options.urlencode_readdir_entries) {
+
+                /* url-encode the name.  get back remaining buffer space */
+                max_namebuf_len =
+                        smbc_urlencode(dest->name, src->name, max_namebuf_len);
+
+                /* We now know the name length */
+                dest->namelen = strlen(dest->name);
+
+                /* Save the pointer to the beginning of the comment */
+                dest->comment = dest->name + dest->namelen + 1;
+
+                /* Copy the comment */
+                strncpy(dest->comment, src->comment, max_namebuf_len);
+
+                /* Ensure the comment is null terminated */
+                if (max_namebuf_len > src->commentlen) {
+                        dest->comment[src->commentlen] = '\0';
+                } else {
+                        dest->comment[max_namebuf_len - 1] = '\0';
+                }
+
+                /* Save other fields */
+                dest->smbc_type = src->smbc_type;
+                dest->commentlen = strlen(dest->comment);
+                dest->dirlen = ((dest->comment + dest->commentlen + 1) -
+                                (char *) dest);
+        } else {
+
+                /* No encoding.  Just copy the entry as is. */
+                memcpy(dest, src, src->dirlen);
+                dest->comment = (char *)(&dest->name + src->namelen + 1);
+        }
+        
+}
+
 /*
  * Routine to get a directory entry
  */
 
 struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
 {
+        int maxlen;
        struct smbc_dirent *dirp, *dirent;
 
        /* Check that all is ok first ... */
@@ -2292,37 +2291,40 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
        if (!dir->dir_next) {
                return NULL;
         }
-       else {
 
-               dirent = dir->dir_next->dirent;
-               if (!dirent) {
+        dirent = dir->dir_next->dirent;
+        if (!dirent) {
 
-                       errno = ENOENT;
-                       return NULL;
+                errno = ENOENT;
+                return NULL;
 
-               }
+        }
 
-               /* Hmmm, do I even need to copy it? */
+        dirp = (struct smbc_dirent *)context->internal->_dirent;
+        maxlen = (sizeof(context->internal->_dirent) -
+                  sizeof(struct smbc_dirent));
 
-               memcpy(context->internal->_dirent, dirent, dirent->dirlen); /* Copy the dirent */
-               dirp = (struct smbc_dirent *)context->internal->_dirent;
-               dirp->comment = (char *)(&dirp->name + dirent->namelen + 1);
-               dir->dir_next = dir->dir_next->next;
+        smbc_readdir_internal(context, dirp, dirent, maxlen);
 
-               return (struct smbc_dirent *)context->internal->_dirent;
-       }
+        dir->dir_next = dir->dir_next->next;
 
+        return dirp;
 }
 
 /*
  * Routine to get directory entries
  */
 
-static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count)
+static int smbc_getdents_ctx(SMBCCTX *context,
+                             SMBCFILE *dir,
+                             struct smbc_dirent *dirp,
+                             int count)
 {
-       struct smbc_dir_list *dirlist;
-       int rem = count, reqd;
+       int rem = count;
+        int reqd;
+        int maxlen;
        char *ndir = (char *)dirp;
+       struct smbc_dir_list *dirlist;
 
        /* Check that all is ok first ... */
 
@@ -2364,8 +2366,15 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
 
                }
 
-               if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen + 
-                                  dirlist->dirent->commentlen + 1))) {
+                /* Do urlencoding of next entry, if so selected */
+                dirent = (struct smbc_dirent *)context->internal->_dirent;
+                maxlen = (sizeof(context->internal->_dirent) -
+                          sizeof(struct smbc_dirent));
+                smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen);
+
+                reqd = dirent->dirlen;
+
+               if (rem < reqd) {
 
                        if (rem < count) { /* We managed to copy something */
 
@@ -2382,12 +2391,12 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent
 
                }
 
-               dirent = dirlist->dirent;
-
                memcpy(ndir, dirent, reqd); /* Copy the data in ... */
     
                ((struct smbc_dirent *)ndir)->comment = 
-                       (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1);
+                       (char *)(&((struct smbc_dirent *)ndir)->name +
+                                 dirent->namelen +
+                                 1);
 
                ndir += reqd;
 
@@ -2453,27 +2462,6 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
 
        }
 
-       /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
-
-          mode = aDIR | aRONLY;
-
-          }
-          else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
-
-          if (strcmp(path, "\\") == 0) {
-
-          mode = aDIR | aRONLY;
-
-          }
-          else {
-
-          mode = aRONLY;
-          smbc_stat_printjob(srv, path, &size, &m_time);
-          c_time = a_time = m_time;
-
-          }
-          else { */
-
        if (!cli_mkdir(&srv->cli, path)) {
 
                errno = smbc_errno(context, &srv->cli);
@@ -2491,7 +2479,7 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
 
 static int smbc_rmdir_dirempty = True;
 
-static void rmdir_list_fn(file_info *finfo, const char *mask, void *state)
+static void rmdir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
 {
 
        if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0)
@@ -3238,10 +3226,93 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx,
 }
 
 
+/* Obtain the current dos attributes */
+static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
+                                     TALLOC_CTX *ctx,
+                                     const char *filename,
+                                     SMBCSRV *srv)
+{
+        time_t m_time = 0, a_time = 0, c_time = 0;
+        size_t size = 0;
+        uint16 mode = 0;
+       SMB_INO_T inode = 0;
+        DOS_ATTR_DESC *ret;
+    
+        ret = talloc(ctx, sizeof(DOS_ATTR_DESC));
+        if (!ret) {
+                errno = ENOMEM;
+                return NULL;
+        }
+
+        /* Obtain the DOS attributes */
+        if (!smbc_getatr(context, srv, filename, &mode, &size, 
+                         &c_time, &a_time, &m_time, &inode)) {
+        
+                errno = smbc_errno(context, &srv->cli);
+                DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
+                return NULL;
+        
+        }
+                
+        ret->mode = mode;
+        ret->size = size;
+        ret->a_time = a_time;
+        ret->c_time = c_time;
+        ret->m_time = m_time;
+        ret->inode = inode;
+
+        return ret;
+}
+
+
+/* parse a ascii version of a security descriptor */
+static void dos_attr_parse(SMBCCTX *context,
+                           DOS_ATTR_DESC *dad,
+                           SMBCSRV *srv,
+                           char *str)
+{
+       const char *p = str;
+       fstring tok;
+
+       while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {
+
+               if (StrnCaseCmp(tok, "MODE:", 5) == 0) {
+                       dad->mode = strtol(tok+5, NULL, 16);
+                       continue;
+               }
+
+               if (StrnCaseCmp(tok, "SIZE:", 5) == 0) {
+                        dad->size = strtoll(tok+5, NULL, 10);
+                       continue;
+               }
+
+               if (StrnCaseCmp(tok, "A_TIME:", 7) == 0) {
+                        dad->a_time = strtoll(tok+7, NULL, 10);
+                       continue;
+               }
+
+               if (StrnCaseCmp(tok, "C_TIME:", 7) == 0) {
+                        dad->c_time = strtoll(tok+7, NULL, 10);
+                       continue;
+               }
+
+               if (StrnCaseCmp(tok, "M_TIME:", 7) == 0) {
+                        dad->m_time = strtoll(tok+7, NULL, 10);
+                       continue;
+               }
+
+               if (StrnCaseCmp(tok, "INODE:", 6) == 0) {
+                        dad->inode = strtoll(tok+6, NULL, 10);
+                       continue;
+               }
+       }
+}
+
+
 /***************************************************** 
 retrieve the acls for a file
 *******************************************************/
-static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
+static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
                     struct cli_state *ipc_cli, POLICY_HND *pol,
                     char *filename, char *name, char *buf, int bufsize)
 {
@@ -3249,166 +3320,446 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
         int n = 0;
         int n_used;
         BOOL all;
+        BOOL all_nt;
+        BOOL all_dos;
+        BOOL some_nt;
+        BOOL some_dos;
         BOOL numeric = True;
         BOOL determine_size = (bufsize == 0);
        int fnum = -1;
        SEC_DESC *sd;
        fstring sidstr;
         char *p;
+       time_t m_time = 0, a_time = 0, c_time = 0;
+       size_t size = 0;
+       uint16 mode = 0;
+       SMB_INO_T ino = 0;
+        struct cli_state *cli = &srv->cli;
 
-       fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
-
-       if (fnum == -1) {
-                DEBUG(5, ("cacl_get failed to open %s: %s\n",
-                          filename, cli_errstr(cli)));
-                errno = 0;
-               return -1;
-       }
+        all = (StrnCaseCmp(name, "system.*", 8) == 0);
+        all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0);
+        all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0);
+        some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0);
+        some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0);
+        numeric = (* (name + strlen(name) - 1) != '+');
 
-       sd = cli_query_secdesc(cli, fnum, ctx);
+        n_used = 0;
 
-       if (!sd) {
-                DEBUG(5, ("cacl_get Failed to query old descriptor\n"));
-                errno = 0;
-               return -1;
-       }
+        /*
+         * If we are (possibly) talking to an NT or new system and some NT
+         * attributes have been requested...
+         */
+        if (ipc_cli && (all || some_nt)) {
+                /* Point to the portion after "system.nt_sec_desc." */
+                name += 19;     /* if (all) this will be invalid but unused */
 
-       cli_close(cli, fnum);
+                /* ... then obtain any NT attributes which were requested */
+                fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ);
 
-        all = (*name == '*');
-        numeric = (* (name + strlen(name) - 1) != '+');
+                if (fnum == -1) {
+                        DEBUG(5, ("cacl_get failed to open %s: %s\n",
+                                  filename, cli_errstr(cli)));
+                        errno = 0;
+                        return -1;
+                }
 
-        n_used = 0;
+                sd = cli_query_secdesc(cli, fnum, ctx);
 
-        if (all) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx,
-                                            "REVISION:%d", sd->revision);
-                        if (!p) {
-                                errno = ENOMEM;
-                                return -1;
-                        }
-                        n = strlen(p);
-                } else {
-                        n = snprintf(buf, bufsize,
-                                     "REVISION:%d", sd->revision);
+                if (!sd) {
+                        DEBUG(5,
+                              ("cacl_get Failed to query old descriptor\n"));
+                        errno = 0;
+                        return -1;
                 }
-        } else if (StrCaseCmp(name, "revision") == 0) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx, "%d", sd->revision);
-                        if (!p) {
-                                errno = ENOMEM;
-                                return -1;
+
+                cli_close(cli, fnum);
+
+                if (all || all_nt) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    "REVISION:%d",
+                                                    sd->revision);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             "REVISION:%d", sd->revision);
+                        }
+                } else if (StrCaseCmp(name, "revision") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%d", sd->revision);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%d", sd->revision);
                         }
-                        n = strlen(p);
-                } else {
-                        n = snprintf(buf, bufsize, "%d", sd->revision);
                 }
-        }
         
-        if (!determine_size && n > bufsize) {
-                errno = ERANGE;
-                return -1;
-        }
-        buf += n;
-        n_used += n;
-        bufsize -= n;
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
 
-       /* Get owner and group sid */
+                /* Get owner and group sid */
 
-       if (sd->owner_sid) {
-                convert_sid_to_string(ipc_cli, pol,
-                                      sidstr, numeric, sd->owner_sid);
-       } else {
-               fstrcpy(sidstr, "");
-       }
+                if (sd->owner_sid) {
+                        convert_sid_to_string(ipc_cli, pol,
+                                              sidstr, numeric, sd->owner_sid);
+                } else {
+                        fstrcpy(sidstr, "");
+                }
 
-        if (all) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
-                        if (!p) {
-                                errno = ENOMEM;
-                                return -1;
+                if (all || all_nt) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, ",OWNER:%s", sidstr);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",OWNER:%s", sidstr);
                         }
-                        n = strlen(p);
+                } else if (StrnCaseCmp(name, "owner", 5) == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%s", sidstr);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%s", sidstr);
+                        }
+                }
+
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
+
+                if (sd->grp_sid) {
+                        convert_sid_to_string(ipc_cli, pol,
+                                              sidstr, numeric, sd->grp_sid);
                 } else {
-                        n = snprintf(buf, bufsize, ",OWNER:%s", sidstr);
+                        fstrcpy(sidstr, "");
                 }
-        } else if (StrnCaseCmp(name, "owner", 5) == 0) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx, "%s", sidstr);
-                        if (!p) {
-                                errno = ENOMEM;
+
+                if (all || all_nt) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",GROUP:%s", sidstr);
+                        }
+                } else if (StrnCaseCmp(name, "group", 5) == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%s", sidstr);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%s", sidstr);
+                        }
+                }
+
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
+
+                /* Add aces to value buffer  */
+                for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+
+                        SEC_ACE *ace = &sd->dacl->ace[i];
+                        convert_sid_to_string(ipc_cli, pol,
+                                              sidstr, numeric, &ace->trustee);
+
+                        if (all || all_nt) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, 
+                                                            ",ACL:"
+                                                            "%s:%d/%d/0x%08x", 
+                                                            sidstr,
+                                                            ace->type,
+                                                            ace->flags,
+                                                            ace->info.mask);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     ",ACL:%s:%d/%d/0x%08x", 
+                                                     sidstr,
+                                                     ace->type,
+                                                     ace->flags,
+                                                     ace->info.mask);
+                                }
+                        } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
+                                    StrCaseCmp(name + 3, sidstr) == 0) ||
+                                   (StrnCaseCmp(name, "acl+", 4) == 0 &&
+                                    StrCaseCmp(name + 4, sidstr) == 0)) {
+                                if (determine_size) {
+                                        p = talloc_asprintf(ctx, 
+                                                            "%d/%d/0x%08x", 
+                                                            ace->type,
+                                                            ace->flags,
+                                                            ace->info.mask);
+                                        if (!p) {
+                                                errno = ENOMEM;
+                                                return -1;
+                                        }
+                                        n = strlen(p);
+                                } else {
+                                        n = snprintf(buf, bufsize,
+                                                     "%d/%d/0x%08x", 
+                                                     ace->type,
+                                                     ace->flags,
+                                                     ace->info.mask);
+                                }
+                        }
+                        if (n > bufsize) {
+                                errno = ERANGE;
                                 return -1;
                         }
-                        n = strlen(p);
-                } else {
-                        n = snprintf(buf, bufsize, "%s", sidstr);
+                        buf += n;
+                        n_used += n;
+                        bufsize -= n;
                 }
-        }
 
-        if (!determine_size && n > bufsize) {
-                errno = ERANGE;
-                return -1;
+                /* Restore name pointer to its original value */
+                name -= 19;
         }
-        buf += n;
-        n_used += n;
-        bufsize -= n;
 
-       if (sd->grp_sid) {
-               convert_sid_to_string(ipc_cli, pol,
-                                      sidstr, numeric, sd->grp_sid);
-       } else {
-               fstrcpy(sidstr, "");
-       }
+        if (all || some_dos) {
+                /* Point to the portion after "system.dos_attr." */
+                name += 16;     /* if (all) this will be invalid but unused */
 
-        if (all) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx, ",GROUP:%s", sidstr);
-                        if (!p) {
-                                errno = ENOMEM;
-                                return -1;
+                /* Obtain the DOS attributes */
+                if (!smbc_getatr(context, srv, filename, &mode, &size, 
+                                 &c_time, &a_time, &m_time, &ino)) {
+                        
+                        errno = smbc_errno(context, &srv->cli);
+                        return -1;
+                        
+                }
+                
+                if (all || all_dos) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    "%sMODE:0x%x",
+                                                    (ipc_cli &&
+                                                     (all || some_nt)
+                                                     ? ","
+                                                     : ""),
+                                                    mode);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             "%sMODE:0x%x",
+                                             (ipc_cli &&
+                                              (all || some_nt)
+                                              ? ","
+                                              : ""),
+                                             mode);
+                        }
+                } else if (StrCaseCmp(name, "mode") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "0x%x", mode);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "0x%x", mode);
                         }
-                        n = strlen(p);
-                } else {
-                        n = snprintf(buf, bufsize, ",GROUP:%s", sidstr);
                 }
-        } else if (StrnCaseCmp(name, "group", 5) == 0) {
-                if (determine_size) {
-                        p = talloc_asprintf(ctx, "%s", sidstr);
-                        if (!p) {
-                                errno = ENOMEM;
-                                return -1;
+        
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
+
+                if (all || all_dos) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    ",SIZE:%llu",
+                                                    (unsigned long long) size);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",SIZE:%llu",
+                                             (unsigned long long) size);
+                        }
+                } else if (StrCaseCmp(name, "size") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    "%llu",
+                                                    (unsigned long long) size);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             "%llu",
+                                             (unsigned long long) size);
                         }
-                        n = strlen(p);
-                } else {
-                        n = snprintf(buf, bufsize, "%s", sidstr);
                 }
-        }
+        
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
 
-        if (!determine_size && n > bufsize) {
-                errno = ERANGE;
-                return -1;
-        }
-        buf += n;
-        n_used += n;
-        bufsize -= n;
+                if (all || all_dos) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    ",C_TIME:%lu", c_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",C_TIME:%lu", c_time);
+                        }
+                } else if (StrCaseCmp(name, "c_time") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%lu", c_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%lu", c_time);
+                        }
+                }
+        
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
 
-       /* Add aces to value buffer  */
-       for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+                if (all || all_dos) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    ",A_TIME:%lu", a_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",A_TIME:%lu", a_time);
+                        }
+                } else if (StrCaseCmp(name, "a_time") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%lu", a_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%lu", a_time);
+                        }
+                }
+        
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
 
-               SEC_ACE *ace = &sd->dacl->ace[i];
-               convert_sid_to_string(ipc_cli, pol,
-                                      sidstr, numeric, &ace->trustee);
+                if (all || all_dos) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx,
+                                                    ",M_TIME:%lu", m_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize,
+                                             ",M_TIME:%lu", m_time);
+                        }
+                } else if (StrCaseCmp(name, "m_time") == 0) {
+                        if (determine_size) {
+                                p = talloc_asprintf(ctx, "%lu", m_time);
+                                if (!p) {
+                                        errno = ENOMEM;
+                                        return -1;
+                                }
+                                n = strlen(p);
+                        } else {
+                                n = snprintf(buf, bufsize, "%lu", m_time);
+                        }
+                }
+        
+                if (!determine_size && n > bufsize) {
+                        errno = ERANGE;
+                        return -1;
+                }
+                buf += n;
+                n_used += n;
+                bufsize -= n;
 
-                if (all) {
+                if (all || all_dos) {
                         if (determine_size) {
-                                p = talloc_asprintf(ctx, 
-                                                    ",ACL:%s:%d/%d/0x%08x", 
-                                                    sidstr,
-                                                    ace->type,
-                                                    ace->flags,
-                                                    ace->info.mask);
+                                p = talloc_asprintf(ctx,
+                                                    ",INODE:%llu",
+                                                    (unsigned long long) ino);
                                 if (!p) {
                                         errno = ENOMEM;
                                         return -1;
@@ -3416,22 +3767,14 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
                                 n = strlen(p);
                         } else {
                                 n = snprintf(buf, bufsize,
-                                             ",ACL:%s:%d/%d/0x%08x", 
-                                             sidstr,
-                                             ace->type,
-                                             ace->flags,
-                                             ace->info.mask);
+                                             ",INODE:%llu",
+                                             (unsigned long long) ino);
                         }
-                } else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
-                            StrCaseCmp(name + 3, sidstr) == 0) ||
-                           (StrnCaseCmp(name, "acl+", 4) == 0 &&
-                            StrCaseCmp(name + 4, sidstr) == 0)) {
+                } else if (StrCaseCmp(name, "inode") == 0) {
                         if (determine_size) {
-                                p = talloc_asprintf(ctx, 
-                                                    "%d/%d/0x%08x", 
-                                                    ace->type,
-                                                    ace->flags,
-                                                    ace->info.mask);
+                                p = talloc_asprintf(ctx,
+                                                    "%llu",
+                                                    (unsigned long long) ino);
                                 if (!p) {
                                         errno = ENOMEM;
                                         return -1;
@@ -3439,23 +3782,28 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli,
                                 n = strlen(p);
                         } else {
                                 n = snprintf(buf, bufsize,
-                                             "%d/%d/0x%08x", 
-                                             ace->type, ace->flags, ace->info.mask);
+                                             "%llu",
+                                             (unsigned long long) ino);
                         }
                 }
-                if (n > bufsize) {
+        
+                if (!determine_size && n > bufsize) {
                         errno = ERANGE;
                         return -1;
                 }
                 buf += n;
                 n_used += n;
                 bufsize -= n;
-       }
+
+                /* Restore name pointer to its original value */
+                name -= 16;
+        }
 
         if (n_used == 0) {
                 errno = ENOATTR;
                 return -1;
         }
+
        return n_used;
 }
 
@@ -3492,8 +3840,7 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
                         the_acl = p + 1;
                 }
 
-                sd = sec_desc_parse(ctx, ipc_cli, pol,
-                                    numeric, (char *) the_acl);
+                sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl);
 
                 if (!sd) {
                         errno = EINVAL;
@@ -3653,12 +4000,14 @@ int smbc_setxattr_ctx(SMBCCTX *context,
                       int flags)
 {
         int ret;
+        int ret2;
         SMBCSRV *srv;
         SMBCSRV *ipc_srv;
        fstring server, share, user, password, workgroup;
        pstring path;
         TALLOC_CTX *ctx;
         POLICY_HND pol;
+        DOS_ATTR_DESC *dad;
 
        if (!context || !context->internal ||
            !context->internal->_initialized) {
@@ -3675,8 +4024,7 @@ int smbc_setxattr_ctx(SMBCCTX *context,
 
        }
   
-       DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
-                  fname, name, (int) size, (char *) value));
+       DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value));
 
        if (smbc_parse_path(context, fname,
                             server, sizeof(server),
@@ -3698,11 +4046,13 @@ int smbc_setxattr_ctx(SMBCCTX *context,
                return -1;  /* errno set by smbc_server */
        }
 
-        ipc_srv = smbc_attr_server(context, server, share,
-                                   workgroup, user, password,
-                                   &pol);
-        if (!ipc_srv) {
-                return -1;
+        if (! srv->no_nt_session) {
+                ipc_srv = smbc_attr_server(context, server, share,
+                                           workgroup, user, password,
+                                           &pol);
+                srv->no_nt_session = True;
+        } else {
+                ipc_srv = NULL;
         }
         
         ctx = talloc_init("smbc_setxattr");
@@ -3711,6 +4061,71 @@ int smbc_setxattr_ctx(SMBCCTX *context,
                 return -1;
         }
 
+        /*
+         * Are they asking to set the entire set of known attributes?
+         */
+        if (StrCaseCmp(name, "system.*") == 0 ||
+            StrCaseCmp(name, "system.*+") == 0) {
+                /* Yup. */
+                char *namevalue =
+                        talloc_asprintf(ctx, "%s:%s", name+7, (const char *) value);
+                if (! namevalue) {
+                        errno = ENOMEM;
+                        ret = -1;
+                        return -1;
+                }
+
+                if (ipc_srv) {
+                        ret = cacl_set(ctx, &srv->cli,
+                                       &ipc_srv->cli, &pol, path,
+                                       namevalue,
+                                       (*namevalue == '*'
+                                        ? SMBC_XATTR_MODE_SET
+                                        : SMBC_XATTR_MODE_ADD),
+                                       flags);
+                } else {
+                        ret = 0;
+                }
+
+                /* get a DOS Attribute Descriptor with current attributes */
+                dad = dos_attr_query(context, ctx, path, srv);
+                if (dad) {
+                        /* Overwrite old with new, using what was provided */
+                        dos_attr_parse(context, dad, srv, namevalue);
+
+                        /* Set the new DOS attributes */
+#warning "Should try Set Path Info first, but it's not yet implemented"
+#if 0                           /* not yet implemented */
+                        if (! cli_setpathinfo(&srv->cli, path,
+                                              dad->c_time,
+                                              dad->a_time,
+                                              dad->m_time,
+                                              dad->mode)) {
+                                if (!cli_setatr(&srv->cli, path,
+                                                dad->mode, dad->m_time)) {
+                                        errno = smbc_errno(context, &srv->cli);
+                                }
+                        }
+#else
+                        if (!cli_setatr(&srv->cli, path,
+                                        dad->mode, dad->m_time)) {
+                                errno = smbc_errno(context, &srv->cli);
+                        }
+#endif
+                }
+
+                /* we only fail if both NT and DOS sets failed */
+                if (ret < 0 && ! dad) {
+                        ret = -1; /* in case dad was null */
+                }
+                else {
+                        ret = 0;
+                }
+
+                talloc_destroy(ctx);
+                return ret;
+        }
+
         /*
          * Are they asking to set an access control element or to set
          * the entire access control list?
@@ -3723,8 +4138,12 @@ int smbc_setxattr_ctx(SMBCCTX *context,
 
                 /* Yup. */
                 char *namevalue =
-                        talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
-                if (! namevalue) {
+                        talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
+
+                if (! ipc_srv) {
+                        ret = -1; /* errno set by smbc_server() */
+                }
+                else if (! namevalue) {
                         errno = ENOMEM;
                         ret = -1;
                 } else {
@@ -3748,8 +4167,13 @@ int smbc_setxattr_ctx(SMBCCTX *context,
 
                 /* Yup. */
                 char *namevalue =
-                        talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
-                if (! namevalue) {
+                        talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
+
+                if (! ipc_srv) {
+                        
+                        ret = -1; /* errno set by smbc_server() */
+                }
+                else if (! namevalue) {
                         errno = ENOMEM;
                         ret = -1;
                 } else {
@@ -3769,8 +4193,13 @@ int smbc_setxattr_ctx(SMBCCTX *context,
 
                 /* Yup. */
                 char *namevalue =
-                        talloc_asprintf(ctx, "%s:%s", name+19, (char *) value);
-                if (! namevalue) {
+                        talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
+
+                if (! ipc_srv) {
+                        /* errno set by smbc_server() */
+                        ret = -1;
+                }
+                else if (! namevalue) {
                         errno = ENOMEM;
                         ret = -1;
                 } else {
@@ -3782,6 +4211,67 @@ int smbc_setxattr_ctx(SMBCCTX *context,
                 return ret;
         }
 
+        /*
+         * Are they asking to set a DOS attribute?
+         */
+        if (StrCaseCmp(name, "system.dos_attr.*") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.a_time") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.m_time") == 0) {
+
+                /* get a DOS Attribute Descriptor with current attributes */
+                dad = dos_attr_query(context, ctx, path, srv);
+                if (dad) {
+                        char *namevalue =
+                                talloc_asprintf(ctx, "%s:%s", name+16, (const char *) value);
+                        if (! namevalue) {
+                                errno = ENOMEM;
+                                ret = -1;
+                        } else {
+                                /* Overwrite old with provided new params */
+                                dos_attr_parse(context, dad, srv, namevalue);
+
+                                /* Set the new DOS attributes */
+#warning "Should try Set Path Info first, but it's not yet implemented"
+#if 0                           /* not yet implemented */
+                                ret2 = cli_setpathinfo(&srv->cli, path,
+                                                       dad->c_time,
+                                                       dad->a_time,
+                                                       dad->m_time,
+                                                       dad->mode);
+                                if (! ret2) {
+                                        ret2 = cli_setatr(&srv->cli, path,
+                                                          dad->mode,
+                                                          dad->m_time);
+                                        if (! ret2) {
+                                                errno = smbc_errno(context,
+                                                                   &srv->cli);
+                                        }
+                                }
+#else
+                                ret2 = cli_setatr(&srv->cli, path,
+                                                  dad->mode, dad->m_time);
+                                if (! ret2) {
+                                        errno = smbc_errno(context, &srv->cli);
+                                }
+#endif
+
+                                /* ret2 has True (success) / False (failure) */
+                                if (ret2) {
+                                        ret = 0;
+                                } else {
+                                        ret = -1;
+                                }
+                        }
+                } else {
+                        ret = -1;
+                }
+
+                talloc_destroy(ctx);
+                return ret;
+        }
+
         /* Unsupported attribute name */
         talloc_destroy(ctx);
         errno = EINVAL;
@@ -3802,6 +4292,7 @@ int smbc_getxattr_ctx(SMBCCTX *context,
         TALLOC_CTX *ctx;
         POLICY_HND pol;
 
+
         if (!context || !context->internal ||
             !context->internal->_initialized) {
 
@@ -3839,11 +4330,15 @@ int smbc_getxattr_ctx(SMBCCTX *context,
                 return -1;  /* errno set by smbc_server */
         }
 
-        ipc_srv = smbc_attr_server(context, server, share,
-                                   workgroup, user, password,
-                                   &pol);
-        if (!ipc_srv) {
-                return -1;
+        if (! srv->no_nt_session) {
+                ipc_srv = smbc_attr_server(context, server, share,
+                                           workgroup, user, password,
+                                           &pol);
+                if (! ipc_srv) {
+                        srv->no_nt_session = True;
+                }
+        } else {
+                ipc_srv = NULL;
         }
         
         ctx = talloc_init("smbc:getxattr");
@@ -3853,7 +4348,9 @@ int smbc_getxattr_ctx(SMBCCTX *context,
         }
 
         /* Are they requesting a supported attribute? */
-        if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
+        if (StrCaseCmp(name, "system.*") == 0 ||
+            StrCaseCmp(name, "system.*+") == 0 ||
+            StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
@@ -3861,13 +4358,19 @@ int smbc_getxattr_ctx(SMBCCTX *context,
             StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
             StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
             StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
-            StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
+            StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 ||
+            StrCaseCmp(name, "system.dos_attr.*") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.mode") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.size") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.c_time") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.a_time") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.m_time") == 0 ||
+            StrCaseCmp(name, "system.dos_attr.inode") == 0) {
 
                 /* Yup. */
-                ret = cacl_get(ctx, &srv->cli,
-                               &ipc_srv->cli, &pol, 
-                               (char *) path, (char *) name + 19,
-                               (char *) value, size);
+                ret = cacl_get(context, ctx, srv,
+                               ipc_srv == NULL ? NULL : &ipc_srv->cli, 
+                               &pol, path, name, (const char *) value, size);
                 if (ret < 0 && errno == 0) {
                         errno = smbc_errno(context, &srv->cli);
                 }
@@ -3931,20 +4434,19 @@ int smbc_removexattr_ctx(SMBCCTX *context,
                 return -1;  /* errno set by smbc_server */
         }
 
-        ipc_srv = smbc_attr_server(context, server, share,
-                                   workgroup, user, password,
-                                   &pol);
-        if (!ipc_srv) {
-                return -1;
+        if (! srv->no_nt_session) {
+                ipc_srv = smbc_attr_server(context, server, share,
+                                           workgroup, user, password,
+                                           &pol);
+                srv->no_nt_session = True;
+        } else {
+                ipc_srv = NULL;
         }
         
-        ipc_srv = smbc_attr_server(context, server, share,
-                                   workgroup, user, password,
-                                   &pol);
-        if (!ipc_srv) {
-                return -1;
+        if (! ipc_srv) {
+                return -1; /* errno set by smbc_attr_server */
         }
-        
+
         ctx = talloc_init("smbc_removexattr");
         if (!ctx) {
                 errno = ENOMEM;
@@ -3996,10 +4498,12 @@ int smbc_listxattr_ctx(SMBCCTX *context,
 {
         /*
          * This isn't quite what listxattr() is supposed to do.  This returns
-         * the complete set of attributes, always, rather than only those
+         * the complete set of attribute names, always, rather than only those
          * attribute names which actually exist for a file.  Hmmm...
          */
         const char supported[] =
+                "system.*\0"
+                "system.*+\0"
                 "system.nt_sec_desc.revision\0"
                 "system.nt_sec_desc.owner\0"
                 "system.nt_sec_desc.owner+\0"
@@ -4009,6 +4513,11 @@ int smbc_listxattr_ctx(SMBCCTX *context,
                 "system.nt_sec_desc.acl+\0"
                 "system.nt_sec_desc.*\0"
                 "system.nt_sec_desc.*+\0"
+                "system.dos_attr.*\0"
+                "system.dos_attr.mode\0"
+                "system.dos_attr.c_time\0"
+                "system.dos_attr.a_time\0"
+                "system.dos_attr.m_time\0"
                 ;
 
         if (size == 0) {
@@ -4295,6 +4804,8 @@ SMBCCTX * smbc_new_context(void)
                 return NULL;
         }
 
+       context->flags = SMBCCTX_FLAG_CTXVER;
+
         ZERO_STRUCTP(context->internal);
 
         
@@ -4302,37 +4813,41 @@ SMBCCTX * smbc_new_context(void)
         context->debug            = 0;
         context->timeout          = 20000; /* 20 seconds */
 
-        context->open             = smbc_open_ctx;
-        context->creat            = smbc_creat_ctx;
-        context->read             = smbc_read_ctx;
-        context->write            = smbc_write_ctx;
-        context->close            = smbc_close_ctx;
-        context->unlink           = smbc_unlink_ctx;
-        context->rename           = smbc_rename_ctx;
-        context->lseek            = smbc_lseek_ctx;
-        context->stat             = smbc_stat_ctx;
-        context->fstat            = smbc_fstat_ctx;
-        context->opendir          = smbc_opendir_ctx;
-        context->closedir         = smbc_closedir_ctx;
-        context->readdir          = smbc_readdir_ctx;
-        context->getdents         = smbc_getdents_ctx;
-        context->mkdir            = smbc_mkdir_ctx;
-        context->rmdir            = smbc_rmdir_ctx;
-        context->telldir          = smbc_telldir_ctx;
-        context->lseekdir         = smbc_lseekdir_ctx;
-        context->fstatdir         = smbc_fstatdir_ctx;
-        context->chmod            = smbc_chmod_ctx;
-        context->utimes           = smbc_utimes_ctx;
-        context->setxattr         = smbc_setxattr_ctx;
-        context->getxattr         = smbc_getxattr_ctx;
-        context->removexattr      = smbc_removexattr_ctx;
-        context->listxattr        = smbc_listxattr_ctx;
-        context->open_print_job   = smbc_open_print_job_ctx;
-        context->print_file       = smbc_print_file_ctx;
-        context->list_print_jobs  = smbc_list_print_jobs_ctx;
-        context->unlink_print_job = smbc_unlink_print_job_ctx;
-
-        context->callbacks.check_server_fn      = smbc_check_server;
+       context->internal->options.browse_max_lmb_count      = 3;    /* # LMBs to query */
+       context->internal->options.urlencode_readdir_entries = False;/* backward compat */
+       context->internal->options.one_share_per_server      = False;/* backward compat */
+
+        context->open                              = smbc_open_ctx;
+        context->creat                             = smbc_creat_ctx;
+        context->read                              = smbc_read_ctx;
+        context->write                             = smbc_write_ctx;
+        context->close                             = smbc_close_ctx;
+        context->unlink                            = smbc_unlink_ctx;
+        context->rename                            = smbc_rename_ctx;
+        context->lseek                             = smbc_lseek_ctx;
+        context->stat                              = smbc_stat_ctx;
+        context->fstat                             = smbc_fstat_ctx;
+        context->opendir                           = smbc_opendir_ctx;
+        context->closedir                          = smbc_closedir_ctx;
+        context->readdir                           = smbc_readdir_ctx;
+        context->getdents                          = smbc_getdents_ctx;
+        context->mkdir                             = smbc_mkdir_ctx;
+        context->rmdir                             = smbc_rmdir_ctx;
+        context->telldir                           = smbc_telldir_ctx;
+        context->lseekdir                          = smbc_lseekdir_ctx;
+        context->fstatdir                          = smbc_fstatdir_ctx;
+        context->chmod                             = smbc_chmod_ctx;
+        context->utimes                            = smbc_utimes_ctx;
+        context->setxattr                          = smbc_setxattr_ctx;
+        context->getxattr                          = smbc_getxattr_ctx;
+        context->removexattr                       = smbc_removexattr_ctx;
+        context->listxattr                         = smbc_listxattr_ctx;
+        context->open_print_job                    = smbc_open_print_job_ctx;
+        context->print_file                        = smbc_print_file_ctx;
+        context->list_print_jobs                   = smbc_list_print_jobs_ctx;
+        context->unlink_print_job                  = smbc_unlink_print_job_ctx;
+
+        context->callbacks.check_server_fn         = smbc_check_server;
         context->callbacks.remove_unused_server_fn = smbc_remove_unused_server;
 
         smbc_default_cache_functions(context);
@@ -4548,3 +5063,11 @@ SMBCCTX * smbc_init_context(SMBCCTX * context)
         
         return context;
 }
+
+
+/* Return the verion of samba, and thus libsmbclient */
+const char *
+smbc_version(void)
+{
+        return samba_version_string();
+}
index 3451b0cc1ab07592f0d866c4d99dd0ff768614e4..09c96b1286a58cb6ef173b704f4ecefe1fe2699c 100644 (file)
@@ -132,11 +132,6 @@ static BOOL brl_conflict(struct lock_struct *lck1,
                return False;
        }
 
-       if (lck1->start >= (lck2->start + lck2->size) ||
-           lck2->start >= (lck1->start + lck1->size)) {
-               return False;
-       }
-           
        return brl_overlap(lck1, lck2);
 } 
 
@@ -193,10 +188,6 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck
                        return False;
        }
 
-       if (lck1->start >= (lck2->start + lck2->size) ||
-           lck2->start >= (lck1->start + lck1->size))
-               return False;
-           
        return brl_overlap(lck1, lck2);
 } 
 
index 6ab2ed377e2f998d55acb841aa0c321170f01d43..95d4518c172b417bde908eb819a02034a1f6be36 100644 (file)
@@ -563,9 +563,9 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
         * and the underlying system can handle 64 bit signed locks.
         */
 
-    SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
-    SMB_OFF_T mask = (mask2<<1);
-    SMB_OFF_T max_positive_lock_offset = ~mask;
+       SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
+       SMB_OFF_T mask = (mask2<<1);
+       SMB_OFF_T max_positive_lock_offset = ~mask;
 
 #else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
 
@@ -575,7 +575,7 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
         * All offsets & counts must be 2^31 or less.
         */
 
-    SMB_OFF_T max_positive_lock_offset = 0x7FFFFFFF;
+       SMB_OFF_T max_positive_lock_offset = 0x7FFFFFFF;
 
 #endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
 
index b01ffcffc162393da927fd475ca443e909cee580..75319724616d4c9d5e4283e75947e72815578f83 100644 (file)
@@ -190,12 +190,15 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec,
                                          struct packet_struct *incoming_packet,
                                          struct nmb_name *question_name)
 {
-       long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) + 
-               sizeof(struct packet_struct *))/sizeof(long *) + 1];
-       struct userdata_struct *userdata = (struct userdata_struct *)ud;
+       union {
+           struct userdata_struct ud;
+           char c[sizeof(struct userdata_struct) + sizeof(struct subrec *) + 
+               sizeof(struct packet_struct *)+sizeof(long*)];
+       } ud;
+       struct userdata_struct *userdata = &ud.ud;
        unstring qname;
 
-       memset(ud, '\0', sizeof(ud));
+       memset(&ud, '\0', sizeof(ud));
  
        userdata->copy_fn = wins_proxy_userdata_copy_fn;
        userdata->free_fn = wins_proxy_userdata_free_fn;
index 4dcc018c64b8a32da2cbfabc86518199bb1fb227..554687d7b8335c884b5bc9fd00684e3c6d115b09 100644 (file)
@@ -294,7 +294,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
 
 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
                                   TALLOC_CTX *mem_ctx,
-                                  uint32 num_sids, const DOM_SID **sids,
+                                  uint32 num_sids, DOM_SID **sids,
                                   uint32 *num_aliases, DOM_SID ***aliases)
 {
        return NT_STATUS_NO_SUCH_USER;
index 42f451c50515e12a260ef93fe05e04bde9ccc38e..99d12563c6cab3602aed54317b78f9ee7ec6d4b4 100644 (file)
@@ -970,16 +970,47 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        DEBUG(3,("rpc: trusted_domains\n"));
 
        *num_domains = 0;
+       *names = NULL;
        *alt_names = NULL;
+       *dom_sids = NULL;
 
        retry = 0;
        do {
                if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd)))
                        goto done;
 
-               result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
-                                               &hnd->pol, &enum_ctx,
-                                               num_domains, names, dom_sids);
+               result = STATUS_MORE_ENTRIES;
+
+               while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
+                       uint32 start_idx, num;
+                       char **tmp_names;
+                       DOM_SID *tmp_sids;
+                       int i;
+
+                       result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
+                                                       &hnd->pol, &enum_ctx,
+                                                       &num, &tmp_names,
+                                                       &tmp_sids);
+
+                       if (!NT_STATUS_IS_OK(result) &&
+                           !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
+                               break;
+
+                       start_idx = *num_domains;
+                       *num_domains += num;
+                       *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
+                                                     char *, *num_domains);
+                       *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
+                                                        DOM_SID,
+                                                        *num_domains);
+                       if ((*names == NULL) || (*dom_sids == NULL))
+                               return NT_STATUS_NO_MEMORY;
+
+                       for (i=0; i<num; i++) {
+                               (*names)[start_idx+i] = tmp_names[i];
+                               (*dom_sids)[start_idx+i] = tmp_sids[i];
+                       }
+               }
        } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&  hnd && hnd->cli && hnd->cli->fd == -1);
 
 done:
index 80843eda829a3cec75b6da2e036bfb01d87c9ff3..d86f4b391a2a0621a2f02f55b684bfef0a205f60 100644 (file)
@@ -424,6 +424,7 @@ typedef struct
        BOOL bMap_acl_inherit;
        BOOL bAfs_Share;
        BOOL bEASupport;
+       int iallocation_roundup_size;
        param_opt_struct *param_opt;
 
        char dummy[3];          /* for alignment */
@@ -549,6 +550,7 @@ static service sDefault = {
        False,                  /* bMap_acl_inherit */
        False,                  /* bAfs_Share */
        False,                  /* bEASupport */
+       SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
        
        NULL,                   /* Parametric options */
 
@@ -893,6 +895,7 @@ static struct parm_struct parm_table[] = {
 
        {N_("Protocol Options"), P_SEP, P_SEPARATOR}, 
 
+       {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, 
        {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, 
        {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, 
        {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
@@ -953,7 +956,7 @@ static struct parm_struct parm_table[] = {
        {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED}, 
        {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED}, 
-       {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
+       {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
 
        {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED}, 
 
@@ -1236,9 +1239,9 @@ static void init_printer_values(service *pService)
                        string_set(&pService->szQueuepausecommand, "");
                        string_set(&pService->szQueueresumecommand, "");
 #else
-                       string_set(&pService->szLpqcommand, "/usr/bin/lpstat -o '%p'");
-                       string_set(&pService->szLprmcommand, "/usr/bin/cancel '%p-%j'");
-                       string_set(&pService->szPrintcommand, "/usr/bin/lp -d '%p' %s; rm %s");
+                       string_set(&pService->szLpqcommand, "/usr/bin/lpq -P'%p'");
+                       string_set(&pService->szLprmcommand, "/usr/bin/lprm -P'%p' %j");
+                       string_set(&pService->szPrintcommand, "/usr/bin/lpr -P'%p' %s; rm %s");
                        string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
                        string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
                        string_set(&pService->szQueuepausecommand, "/usr/bin/disable '%p'");
@@ -1931,6 +1934,7 @@ FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
+FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size);
 FN_LOCAL_CHAR(lp_magicchar, magic_char)
 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
index 36a575214b941efeaeb9f8f5171f6bcf17ad15b6..84d398ccd64ed1634f57e2e714e2018005fd69f5 100644 (file)
@@ -325,6 +325,24 @@ static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCO
        return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
 }
 
+static NTSTATUS context_update_login_attempts(struct pdb_context *context,
+                                               SAM_ACCOUNT *sam_acct, BOOL success)
+{
+       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+       if (!context) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return ret;
+       }
+
+       if (!sam_acct || !sam_acct->methods){
+               DEBUG(0, ("invalid sam_acct specified\n"));
+               return ret;
+       }
+
+       return sam_acct->methods->update_login_attempts(sam_acct->methods, sam_acct, success);
+}
+
 static NTSTATUS context_getgrsid(struct pdb_context *context,
                                 GROUP_MAP *map, DOM_SID sid)
 {
@@ -749,6 +767,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_add_sam_account = context_add_sam_account;
        (*context)->pdb_update_sam_account = context_update_sam_account;
        (*context)->pdb_delete_sam_account = context_delete_sam_account;
+       (*context)->pdb_update_login_attempts = context_update_login_attempts;
        (*context)->pdb_getgrsid = context_getgrsid;
        (*context)->pdb_getgrgid = context_getgrgid;
        (*context)->pdb_getgrnam = context_getgrnam;
@@ -992,6 +1011,17 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
        return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
 }
 
+NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       return pdb_context->pdb_update_login_attempts(pdb_context, sam_acct, success);
+}
+
 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1279,6 +1309,11 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
+static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success)
+{
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
 {
        return NT_STATUS_NOT_IMPLEMENTED;
@@ -1422,6 +1457,7 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
        (*methods)->add_sam_account = pdb_default_add_sam_account;
        (*methods)->update_sam_account = pdb_default_update_sam_account;
        (*methods)->delete_sam_account = pdb_default_delete_sam_account;
+       (*methods)->update_login_attempts = pdb_default_update_login_attempts;
 
        (*methods)->getgrsid = pdb_default_getgrsid;
        (*methods)->getgrgid = pdb_default_getgrgid;
index 0a0426ef2ab93af3e7f6058b114c9888ae419027..f086b3f09b22d3ffabb50790b4d4c36079f65b06 100644 (file)
 
 #include "smbldap.h"
 
-struct ldapsam_privates {
-       struct smbldap_state *smbldap_state;
-
-       /* Former statics */
-       LDAPMessage *result;
-       LDAPMessage *entry;
-       int index;
-       
-       const char *domain_name;
-       DOM_SID domain_sid;
-       
-       /* configuration items */
-       int schema_ver;
-
-       char *domain_dn;
-};
-
 /**********************************************************************
  Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
  **********************************************************************/
  
-static void private_data_free_fn(void **result) 
+void private_data_free_fn(void **result) 
 {
        ldap_msgfree(*result);
        *result = NULL;
@@ -134,7 +117,7 @@ static const char* get_userattr_key2string( int schema_ver, int key )
  Return the list of attribute names given a user schema version.
 **********************************************************************/
 
-static const char** get_userattr_list( int schema_ver )
+const char** get_userattr_list( int schema_ver )
 {
        switch ( schema_ver ) {
                case SCHEMAVER_SAMBAACCOUNT:
@@ -199,7 +182,7 @@ static const char* get_objclass_filter( int schema_ver )
  Run the search by name.
 ******************************************************************/
 
-static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, 
+int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, 
                                          const char *user,
                                          LDAPMessage ** result,
                                          const char **attr)
@@ -444,7 +427,7 @@ static time_t ldapsam_get_entry_timestamp(
  (Based on init_sam_from_buffer in pdb_tdb.c)
 *********************************************************************/
 
-static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, 
+static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state, 
                                SAM_ACCOUNT * sampass,
                                LDAPMessage * entry)
 {
@@ -470,6 +453,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
        uint32          user_rid; 
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
+       BOOL            use_samba_attrs = True;
        uint16          acct_ctrl = 0, 
                        logon_divs;
        uint16          bad_password_count = 0, 
@@ -708,27 +692,56 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
        hours_len = 21;
        memset(hours, 0xff, hours_len);
 
-       if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
-               /* leave as default */
-       } else {
-               pdb_gethexpwd(temp, smblmpwd);
-               memset((char *)temp, '\0', strlen(temp)+1);
-               if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
-                       return False;
-               ZERO_STRUCT(smblmpwd);
-       }
+       if (ldap_state->is_nds_ldap) {
+               char *user_dn;
+               size_t pwd_len;
+               uchar 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);
+               if (user_dn != NULL) {
+                       DEBUG(3, ("init_sam_from_ldap: smbldap_get_dn(%s) returned '%s'\n", username, user_dn));
+
+                       pwd_len = sizeof(clear_text_pw);
+                       if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
+                               nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
+                               if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
+                                       return False;
+                               ZERO_STRUCT(smblmpwd);
+                               if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
+                                       return False;
+                               ZERO_STRUCT(smbntpwd);
+                               use_samba_attrs = False;
+                       }
+               } else {
+                       DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
+               }
+       }
 
-       if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
-               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
-               /* leave as default */
-       } else {
-               pdb_gethexpwd(temp, smbntpwd);
-               memset((char *)temp, '\0', strlen(temp)+1);
-               if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
-                       return False;
-               ZERO_STRUCT(smbntpwd);
-       }
+       if (use_samba_attrs) {
+               if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry, 
+                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
+                       /* leave as default */
+               } else {
+                       pdb_gethexpwd(temp, smblmpwd);
+                       memset((char *)temp, '\0', strlen(temp)+1);
+                       if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
+                               return False;
+                       ZERO_STRUCT(smblmpwd);
+               }
+
+               if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
+                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
+                       /* leave as default */
+               } else {
+                       pdb_gethexpwd(temp, smbntpwd);
+                       memset((char *)temp, '\0', strlen(temp)+1);
+                       if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
+                               return False;
+                       ZERO_STRUCT(smbntpwd);
+               }
+       }
 
        account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
        if (pwHistLen > 0){
@@ -1491,15 +1504,17 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                        (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
                BerElement *ber;
                struct berval *bv;
-               char *retoid;
-               struct berval *retdata;
+               char *retoid = NULL;
+               struct berval *retdata = NULL;
                char *utf8_password;
                char *utf8_dn;
 
-               if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) {
-                       DEBUG(2, ("ldap password change requested, but LDAP "
-                                 "server does not support it -- ignoring\n"));
-                       return NT_STATUS_OK;
+               if (!ldap_state->is_nds_ldap) {
+                       if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) {
+                               DEBUG(2, ("ldap password change requested, but LDAP "
+                                         "server does not support it -- ignoring\n"));
+                               return NT_STATUS_OK;
+                       }
                }
 
                if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
@@ -1533,10 +1548,16 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
                SAFE_FREE(utf8_password);
                ber_free(ber, 1);
 
-               if ((rc = smbldap_extended_operation(ldap_state->smbldap_state, 
-                                                    LDAP_EXOP_MODIFY_PASSWD,
-                                                    bv, NULL, NULL, &retoid, 
-                                                    &retdata)) != LDAP_SUCCESS) {
+               if (!ldap_state->is_nds_ldap) {
+                       rc = smbldap_extended_operation(ldap_state->smbldap_state, 
+                                                       LDAP_EXOP_MODIFY_PASSWD,
+                                                       bv, NULL, NULL, &retoid, 
+                                                       &retdata);
+               } else {
+                       rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
+                                                       pdb_get_plaintext_passwd(newpwd));
+               }
+               if (rc != LDAP_SUCCESS) {
                        char *ld_error = NULL;
 
                        if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
@@ -1559,8 +1580,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
 #ifdef DEBUG_PASSWORD
                        DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
 #endif    
-                       ber_bvfree(retdata);
-                       ber_memfree(retoid);
+                       if (retdata)
+                               ber_bvfree(retdata);
+                       if (retoid)
+                               ber_memfree(retoid);
                }
                ber_bvfree(bv);
        }
@@ -2134,10 +2157,10 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
 {
        pstring filter;
 
-       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%d))",
                LDAP_OBJ_GROUPMAP,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
-               (unsigned long)gid);
+               gid);
 
        return ldapsam_getgroup(methods, filter, map);
 }
@@ -2490,10 +2513,10 @@ static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
 {
        pstring filter;
 
-       pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))", 
+       pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%d))", 
                LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY,
                get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
-               (unsigned long)gid);
+               gid);
 
        return ldapsam_search_one_group(ldap_state, filter, result);
 }
@@ -2543,7 +2566,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
                ldap_msgfree(result);
 
                pstrcpy( suffix, lp_ldap_idmap_suffix() );
-               pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
+               pstr_sprintf(filter, "(&(objectClass=%s)(%s=%d))",
                             LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
                             map->gid);
                
@@ -3174,7 +3197,7 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
  Initialise the 'compat' mode for pdb_ldap
  *********************************************************************/
 
-static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
        struct ldapsam_privates *ldap_state;
@@ -3213,7 +3236,7 @@ static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **
  Initialise the normal mode for pdb_ldap
  *********************************************************************/
 
-static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
 {
        NTSTATUS nt_status;
        struct ldapsam_privates *ldap_state;
@@ -3318,5 +3341,8 @@ NTSTATUS pdb_ldap_init(void)
        if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
                return nt_status;
 
+       /* Let pdb_nds register backends */
+       pdb_nds_init();
+
        return NT_STATUS_OK;
 }
index 0955ea1881f53184ba9b1027f0fad0367f25a96c..4474bf04e36a97fb10ffb521933ff0432f54cb87 100644 (file)
@@ -104,10 +104,15 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
   pdb_set_logon_count            ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
   pdb_set_unknown_6            ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ;
   
-  if ( !PQgetisnull( r, row, 18 ) ) string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ;
-  pdb_set_user_sid ( u, &sid, PDB_SET ) ;
-  if ( !PQgetisnull( r, row, 19 ) ) string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ;
-  pdb_set_group_sid( u, &sid, PDB_SET ) ;
+  if ( !PQgetisnull( r, row, 18 ) ) {
+    string_to_sid( &sid, PQgetvalue( r, row, 18 ) ) ;
+    pdb_set_user_sid ( u, &sid, PDB_SET ) ;
+  }
+
+  if ( !PQgetisnull( r, row, 19 ) ) {
+    string_to_sid( &sid, PQgetvalue( r, row, 19 ) ) ;
+    pdb_set_group_sid( u, &sid, PDB_SET ) ;
+  }
   
   if ( pdb_gethexpwd( PQgetvalue( r, row, 20 ), temp ), PDB_SET ) pdb_set_lanman_passwd( u, temp, PDB_SET ) ;
   if ( pdb_gethexpwd( PQgetvalue( r, row, 21 ), temp ), PDB_SET ) pdb_set_nt_passwd    ( u, temp, PDB_SET ) ;
@@ -146,7 +151,7 @@ static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, u
   }
   else
   {
-    DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%llu results)!\n", PQntuples(data->pwent)) ) ;
+    DEBUG( 5, ("pgsqlsam_setsampwent succeeded(%d results)!\n", PQntuples(data->pwent)) ) ;
     retval = NT_STATUS_OK ;
   }
   
index ee9ece2baf03d409d05b6334d63806d0a527e3b1..ce92a067d173ea54fee156fbf74b30b0c2ea9ccc 100644 (file)
@@ -315,12 +315,14 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                                                 CONFIG_TABLE_DEFAULT));
        }
 
-       pdb_sql_int_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_ACCTCTRL)) {
+               pdb_sql_int_field(&query,
                                                config_value_write(location, "acct ctrl column",
                                                                                   CONFIG_ACCT_CTRL_DEFAULT),
                                                pdb_get_acct_ctrl(newpwd));
+       }
 
-       if (pdb_get_init_flags(newpwd, PDB_LOGONTIME) != PDB_DEFAULT) {
+       if (IS_SAM_CHANGED(newpwd, PDB_LOGONTIME)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "logon time column",
@@ -328,7 +330,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_logon_time(newpwd));
        }
 
-       if (pdb_get_init_flags(newpwd, PDB_LOGOFFTIME) != PDB_DEFAULT) {
+       if (IS_SAM_CHANGED(newpwd, PDB_LOGOFFTIME)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "logoff time column",
@@ -336,7 +338,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_logoff_time(newpwd));
        }
 
-       if (pdb_get_init_flags(newpwd, PDB_KICKOFFTIME) != PDB_DEFAULT) {
+       if (IS_SAM_CHANGED(newpwd, PDB_KICKOFFTIME)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "kickoff time column",
@@ -344,7 +346,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_kickoff_time(newpwd));
        }
 
-       if (pdb_get_init_flags(newpwd, PDB_CANCHANGETIME) != PDB_DEFAULT) {
+       if (IS_SAM_CHANGED(newpwd, PDB_CANCHANGETIME)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "pass can change time column",
@@ -352,7 +354,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_pass_can_change_time(newpwd));
        }
 
-       if (pdb_get_init_flags(newpwd, PDB_MUSTCHANGETIME) != PDB_DEFAULT) {
+       if (IS_SAM_CHANGED(newpwd, PDB_MUSTCHANGETIME)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "pass must change time column",
@@ -360,7 +362,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_pass_must_change_time(newpwd));
        }
 
-       if (pdb_get_pass_last_set_time(newpwd)) {
+       if (IS_SAM_CHANGED(newpwd, PDB_PASSLASTSET)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "pass last set time column",
@@ -368,7 +370,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_pass_last_set_time(newpwd));
        }
 
-       if (pdb_get_hours_len(newpwd)) {
+       if (IS_SAM_CHANGED(newpwd, PDB_HOURSLEN)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "hours len column",
@@ -376,7 +378,7 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_hours_len(newpwd));
        }
 
-       if (pdb_get_logon_divs(newpwd)) {
+       if (IS_SAM_CHANGED(newpwd, PDB_LOGONDIVS)) {
                pdb_sql_int_field(&query,
                                                        config_value_write(location,
                                                                                           "logon divs column",
@@ -384,85 +386,113 @@ char *sql_account_query_update(const char *location, const SAM_ACCOUNT *newpwd,
                                                        pdb_get_logon_divs(newpwd));
        }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_USERSID)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "user sid column",
                                                                                          CONFIG_USER_SID_DEFAULT),
                                                   sid_to_string(sid_str, 
                                                                                 pdb_get_user_sid(newpwd)));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_GROUPSID)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "group sid column",
                                                                                          CONFIG_GROUP_SID_DEFAULT),
                                                   sid_to_string(sid_str,
                                                                                 pdb_get_group_sid(newpwd)));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_USERNAME)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "username column",
                                                                                          CONFIG_USERNAME_DEFAULT),
                                                   pdb_get_username(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_DOMAIN)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "domain column",
                                                                                          CONFIG_DOMAIN_DEFAULT),
                                                   pdb_get_domain(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_USERNAME)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "nt username column",
                                                                                          CONFIG_NT_USERNAME_DEFAULT),
                                                   pdb_get_nt_username(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_FULLNAME)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "fullname column",
                                                                                          CONFIG_FULLNAME_DEFAULT),
                                                   pdb_get_fullname(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_LOGONSCRIPT)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "logon script column",
                                                                                          CONFIG_LOGON_SCRIPT_DEFAULT),
                                                   pdb_get_logon_script(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_PROFILE)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "profile path column",
                                                                                          CONFIG_PROFILE_PATH_DEFAULT),
                                                   pdb_get_profile_path(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_DRIVE)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "dir drive column",
                                                                                          CONFIG_DIR_DRIVE_DEFAULT),
                                                   pdb_get_dir_drive(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_SMBHOME)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "home dir column",
                                                                                          CONFIG_HOME_DIR_DEFAULT),
                                                   pdb_get_homedir(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_WORKSTATIONS)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "workstations column",
                                                                                          CONFIG_WORKSTATIONS_DEFAULT),
                                                   pdb_get_workstations(newpwd));
+       }
 
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_UNKNOWNSTR)) {
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "unknown string column",
                                                                                          CONFIG_UNKNOWN_STR_DEFAULT),
                                                   pdb_get_workstations(newpwd));
+       }
 
-       pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd),
-                                 pdb_get_acct_ctrl(newpwd));
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_LMPASSWD)) {
+               pdb_sethexpwd(temp, pdb_get_lanman_passwd(newpwd),
+                                         pdb_get_acct_ctrl(newpwd));
+               pdb_sql_string_field(&query,
                                                   config_value_write(location,
                                                                                          "lanman pass column",
                                                                                          CONFIG_LM_PW_DEFAULT), temp);
+       }
 
-       pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd),
-                                 pdb_get_acct_ctrl(newpwd));
-       pdb_sql_string_field(&query,
+       if (IS_SAM_CHANGED(newpwd, PDB_NTPASSWD)) {
+               pdb_sethexpwd(temp, pdb_get_nt_passwd(newpwd),
+                                         pdb_get_acct_ctrl(newpwd));
+               pdb_sql_string_field(&query,
                                                   config_value_write(location, "nt pass column",
                                                                                          CONFIG_NT_PW_DEFAULT), temp);
+       }
 
        if (query.update) {
                query.part1[strlen(query.part1) - 1] = '\0';
index 2a525ef560b01694892985b83b92eef6a0b9be2b..ad911c3b05b05a506bfdeb077abd227f097777c8 100644 (file)
@@ -1820,6 +1820,9 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
        ZERO_STRUCT(driver);
 
        architecture = get_short_archi(arch);
+
+       if ( !architecture )
+               return WERR_UNKNOWN_PRINTER_DRIVER;
        
        /* Windows 4.0 (i.e. win9x) should always use a version of 0 */
        
@@ -4333,34 +4336,70 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
        int snum;
        int n_services = lp_numservices();
        NT_PRINTER_INFO_LEVEL *printer = NULL;
+       BOOL in_use = False;
 
        if ( !info_3 ) 
                return False;
 
-       DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
+       DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
        
        /* loop through the printers.tdb and check for the drivername */
        
-       for (snum=0; snum<n_services; snum++) {
+       for (snum=0; snum<n_services && !in_use; snum++) {
                if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
                        continue;
                
                if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
                        continue;
                
-               if ( !StrCaseCmp(info_3->name, printer->info_2->drivername) ) {
-                       free_a_printer( &printer, 2 );
-                       return True;
-               }
+               if ( strequal(info_3->name, printer->info_2->drivername) ) 
+                       in_use = True;
                
                free_a_printer( &printer, 2 );
        }
        
-       DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
+       DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
+       
+       if ( in_use ) {
+               NT_PRINTER_DRIVER_INFO_LEVEL d;
+               WERROR werr;
+               
+               DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", info_3->name));
+               
+               /* we can still remove the driver if there is one of 
+                  "Windows NT x86" version 2 or 3 left */
+                  
+               if ( !strequal( "Windows NT x86", info_3->environment ) ) {
+                       werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", DRIVER_ANY_VERSION );                       
+               }
+               else {
+                       switch ( info_3->cversion ) {
+                       case 2:
+                               werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 3 );
+                               break;
+                       case 3: 
+                               werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 2 );
+                               break;
+                       default:
+                               DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n", 
+                                       info_3->cversion));
+                               werr = WERR_UNKNOWN_PRINTER_DRIVER;
+                               break;
+                       }
+               }
+
+               /* now check the error code */
+                               
+               if ( W_ERROR_IS_OK(werr) ) {
+                       /* it's ok to remove the driver, we have other architctures left */
+                       in_use = False;
+                       free_a_printer_driver( d, 3 );
+               }
+       }
        
        /* report that the driver is not in use by default */
        
-       return False;
+       return in_use;
 }
 
 
index 0495b6fc1fc2e71d10f4a42699b8b3d4a8744705..e9d81953667284e6dffa65e2a98dd0b30d1fc6c9 100644 (file)
@@ -129,7 +129,7 @@ void pcap_cache_reload(void)
        }
 #endif
 
-#ifdef SYSV
+#if defined(SYSV) || defined(HPUX)
        if (strequal(pcap_name, "lpstat")) {
                pcap_reloaded = sysv_cache_reload();
                goto done;
index 3a7c9356344b3844ab35adab672841aa690f2b56..1213b917342b01ff78f328b6d52016943a1ca02e 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "includes.h"
 
-#ifdef SYSV
+#if defined(SYSV) || defined(HPUX)
 BOOL sysv_cache_reload(void)
 {
        char **lines;
index b4d0f3a44b3708d8db0f9109ec17371be308eb02..5483005e1bd9099473e9fc1b271231ef9a7b2652 100644 (file)
@@ -810,7 +810,7 @@ static void print_cache_flush(int snum)
  Check if someone already thinks they are doing the update.
 ****************************************************************************/
 
-static pid_t get_updating_pid(fstring sharename)
+static pid_t get_updating_pid(const char *sharename)
 {
        fstring keystr;
        TDB_DATA data, key;
@@ -1075,12 +1075,6 @@ static void print_queue_update_internal( const char *sharename,
        DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
                sharename, current_printif->type, lpq_command));
 
-       if ( !print_cache_expired(sharename, False) ) {
-               DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
-               release_print_db(pdb);
-               return;
-       }
-
        /*
         * Update the cache time FIRST ! Stops others even
         * attempting to get the lock and doing this
@@ -1212,20 +1206,24 @@ static void print_queue_update_internal( const char *sharename,
  smbd processes maytry to update the lpq cache concurrently).
 ****************************************************************************/
 
-static void print_queue_update_with_lock(int snum)
+static void print_queue_update_with_lock( const char *sharename, 
+                                          struct printif *current_printif,
+                                          char *lpq_command )
 {
-       fstring sharename, keystr;
-       pstring lpq_command;
+       fstring keystr;
        struct tdb_print_db *pdb;
-       struct printif *current_printif = get_printer_fns( snum );
-
-       fstrcpy(sharename, lp_const_servicename(snum));
 
        DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
        pdb = get_print_db_byname(sharename);
        if (!pdb)
                return;
 
+       if ( !print_cache_expired(sharename, False) ) {
+               DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
+               release_print_db(pdb);
+               return;
+       }
+       
        /*
         * Check to see if someone else is doing this update.
         * This is essentially a mutex on the update.
@@ -1276,12 +1274,6 @@ static void print_queue_update_with_lock(int snum)
        tdb_unlock_bystring(pdb->tdb, keystr);
 
        /* do the main work now */
-       /* have to substitute any variables here since 
-           print_queue_get_internal() will not */
-       
-       pstrcpy( lpq_command, lp_lpqcommand(snum) );
-       pstring_sub( lpq_command, "%p", PRINTERNAME(snum) );
-       standard_sub_snum( snum, lpq_command, sizeof(lpq_command) );
        
        print_queue_update_internal( sharename, current_printif, lpq_command );
        
@@ -1313,7 +1305,7 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle
        ctx.sharename = sharename;
        ctx.lpqcommand = lpqcommand;
 
-       print_queue_update_internal(ctx.sharename, 
+       print_queue_update_with_lock(ctx.sharename, 
                get_printer_fns_from_type(ctx.printing_type),
                ctx.lpqcommand );
 
@@ -1380,9 +1372,9 @@ void start_background_queue(void)
 /****************************************************************************
 update the internal database from the system print queue for a queue
 ****************************************************************************/
-static void print_queue_update(int snum)
+
+static void print_queue_update(int snum, BOOL force)
 {
-       struct print_queue_update_context ctx;
        fstring key;
        fstring sharename;
        pstring lpqcommand;
@@ -1390,48 +1382,49 @@ static void print_queue_update(int snum)
        size_t len = 0;
        size_t newlen;
        struct tdb_print_db *pdb;
+       enum printing_types type;
+       struct printif *current_printif;
 
+       fstrcpy( sharename, lp_const_servicename(snum));
+
+       pstrcpy( lpqcommand, lp_lpqcommand(snum));
+       pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
+       standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+       
        /* 
         * Make sure that the background queue process exists.  
         * Otherwise just do the update ourselves 
         */
        
-       if ( background_lpq_updater_pid == -1 ) {
-               print_queue_update_with_lock( 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 );
+
                return;
        }
 
-       fstrcpy( sharename, lp_const_servicename(snum));
-
-       ctx.printing_type = lp_printing(snum);
-
-       pstrcpy( lpqcommand, lp_lpqcommand(snum));
-       pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
-       standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
-
-       ctx.sharename = SMB_STRDUP( sharename );
-       ctx.lpqcommand = SMB_STRDUP( lpqcommand );
-
+       type = lp_printing(snum);
+       
        /* get the length */
 
        len = tdb_pack( buffer, len, "fdP",
-               ctx.sharename,
-               ctx.printing_type,
-               ctx.lpqcommand );
+               sharename,
+               type,
+               lpqcommand );
 
        buffer = SMB_XMALLOC_ARRAY( char, len );
 
        /* now pack the buffer */
        newlen = tdb_pack( buffer, len, "fdP",
-               ctx.sharename,
-               ctx.printing_type,
-               ctx.lpqcommand );
+               sharename,
+               type,
+               lpqcommand );
 
        SMB_ASSERT( newlen == len );
 
        DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
-               "type = %d, lpq command = [%s]\n",
-               ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
+               "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
 
        /* here we set a msg pending record for other smbd processes 
           to throttle the number of duplicate print_queue_update msgs
@@ -1456,8 +1449,6 @@ static void print_queue_update(int snum)
                 MSG_PRINTER_UPDATE, buffer, len, False);
        unbecome_root();
 
-       SAFE_FREE( ctx.sharename );
-       SAFE_FREE( ctx.lpqcommand );
        SAFE_FREE( buffer );
 
        return;
@@ -1920,7 +1911,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
        /* force update the database and say the delete failed if the
            job still exists */
 
-       print_queue_update(snum);
+       print_queue_update(snum, True);
        
        deleted = !print_job_exists(sharename, jobid);
        if ( !deleted )
@@ -2104,7 +2095,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
  
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum);
+               print_queue_update(snum, False);
  
        /* also fetch the queue status */
        memset(&status, 0, sizeof(status));
@@ -2419,7 +2410,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
        
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum);
+               print_queue_update(snum, False);
        
        return True;
 
@@ -2451,7 +2442,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum);
+               print_queue_update(snum, False);
  
        *pcount = 0;
        *ppqueue = NULL;
@@ -2572,7 +2563,7 @@ int print_queue_status(int snum,
        /* make sure the database is up to date */
 
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum);
+               print_queue_update(snum, False);
 
        /* return if we are done */
        if ( !ppqueue || !status )
@@ -2631,9 +2622,14 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
                *errcode = WERR_ACCESS_DENIED;
                return False;
        }
+       
 
+       become_root();
+               
        ret = (*(current_printif->queue_pause))(snum);
 
+       unbecome_root();
+               
        if (ret != 0) {
                *errcode = WERR_INVALID_PARAM;
                return False;
@@ -2662,9 +2658,13 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
                *errcode = WERR_ACCESS_DENIED;
                return False;
        }
-
+       
+       become_root();
+               
        ret = (*(current_printif->queue_resume))(snum);
 
+       unbecome_root();
+               
        if (ret != 0) {
                *errcode = WERR_INVALID_PARAM;
                return False;
@@ -2672,7 +2672,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum);
+               print_queue_update(snum, True);
 
        /* Send a printer notify message */
 
@@ -2693,10 +2693,13 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
        BOOL can_job_admin;
 
        /* Force and update so the count is accurate (i.e. not a cached count) */
-       print_queue_update(snum);
+       print_queue_update(snum, True);
        
        can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
        njobs = print_queue_status(snum, &queue, &status);
+       
+       if ( can_job_admin )
+               become_root();
 
        for (i=0;i<njobs;i++) {
                BOOL owner = is_owner(user, snum, queue[i].job);
@@ -2705,6 +2708,12 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
                        print_job_delete1(snum, queue[i].job);
                }
        }
+       
+       if ( can_job_admin )
+               unbecome_root();
+
+       /* update the cache */
+       print_queue_update( snum, True );
 
        SAFE_FREE(queue);
 
index 98c2475a65833f683656f6a8d6c784c7b247afce..45b7509d45144e343377b1edb5fb308630f440ff 100644 (file)
@@ -1110,12 +1110,12 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 /** Get a privilege value given its name */
 
-NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+NTSTATUS cli_lsa_lookup_priv_value(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                 POLICY_HND *pol, const char *name, LUID *luid)
 {
        prs_struct qbuf, rbuf;
-       LSA_Q_LOOKUPPRIVVALUE q;
-       LSA_R_LOOKUPPRIVVALUE r;
+       LSA_Q_LOOKUP_PRIV_VALUE q;
+       LSA_R_LOOKUP_PRIV_VALUE r;
        NTSTATUS result;
 
        ZERO_STRUCT(q);
@@ -1128,9 +1128,9 @@ NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Marshall data and send request */
 
-       init_lsa_q_lookupprivvalue(&q, pol, name);
+       init_lsa_q_lookup_priv_value(&q, pol, name);
 
-       if (!lsa_io_q_lookupprivvalue("", &q, &qbuf, 0) ||
+       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;
@@ -1138,7 +1138,7 @@ NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        /* Unmarshall response */
 
-       if (!lsa_io_r_lookupprivvalue("", &r, &rbuf, 0)) {
+       if (!lsa_io_r_lookup_priv_value("", &r, &rbuf, 0)) {
                result = NT_STATUS_UNSUCCESSFUL;
                goto done;
        }
index 5473168c0f8281da92a079e0f63f086be3b8cd6c..75751dbcbd63e2913a1b6a682429baa6dee03426 100644 (file)
@@ -2051,6 +2051,54 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        return result;
 }
 
+/* Remove foreign SID */
+
+NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli, 
+                                           TALLOC_CTX *mem_ctx, 
+                                           POLICY_HND *user_pol,
+                                           DOM_SID *sid)
+{
+       prs_struct qbuf, rbuf;
+       SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
+       SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+       DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
+
+       ZERO_STRUCT(q);
+       ZERO_STRUCT(r);
+
+       /* Initialise parse structures */
+
+       prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+       prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+       /* Marshall data and send request */
+
+       init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
+
+       if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
+           !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
+               goto done;
+       }
+
+       /* Unmarshall response */
+
+       if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
+               goto done;
+       }
+
+       /* Return output parameters */
+
+       result = r.status;
+
+ done:
+       prs_mem_free(&qbuf);
+       prs_mem_free(&rbuf);
+
+       return result;
+}
+
 /* Query user security object */
 
 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
index e38197ddba16eae02365a08588cc12f87704e54e..bbff258722ae6cdb93e35d52e5a95878fe63be39 100644 (file)
@@ -1981,20 +1981,38 @@ BOOL lsa_io_r_setsystemaccount(const char *desc, LSA_R_SETSYSTEMACCOUNT  *r_c, p
 }
 
 
-void init_lsa_q_lookupprivvalue(LSA_Q_LOOKUPPRIVVALUE *trn, POLICY_HND *hnd, const char *name)
+static void init_lsa_string( LSA_STRING *uni, const char *string )
 {
-       memcpy(&trn->pol, hnd, sizeof(trn->pol));
-       init_unistr2(&trn->uni2_right, name, UNI_FLAGS_NONE);
-       init_uni_hdr(&trn->hdr_right, &trn->uni2_right);
+       init_unistr2(&uni->unistring, string, UNI_FLAGS_NONE);
+       init_uni_hdr(&uni->hdr, &uni->unistring);
+}
+
+void init_lsa_q_lookup_priv_value(LSA_Q_LOOKUP_PRIV_VALUE *q_u, POLICY_HND *hnd, const char *name)
+{
+       memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
+       init_lsa_string( &q_u->privname, name );
+}
+
+BOOL smb_io_lsa_string( const char *desc, LSA_STRING *string, prs_struct *ps, int depth )
+{
+       prs_debug(ps, depth, desc, "smb_io_lsa_string");
+       depth++;
+
+       if(!smb_io_unihdr ("hdr", &string->hdr, ps, depth))
+               return False;
+       if(!smb_io_unistr2("unistring", &string->unistring, string->hdr.buffer, ps, depth))
+               return False;
+       
+       return True;
 }
 
 /*******************************************************************
- Reads or writes an LSA_Q_LOOKUPPRIVVALUE  structure.
+ Reads or writes an LSA_Q_LOOKUP_PRIV_VALUE  structure.
 ********************************************************************/
 
-BOOL lsa_io_q_lookupprivvalue(const char *desc, LSA_Q_LOOKUPPRIVVALUE  *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_q_lookup_priv_value(const char *desc, LSA_Q_LOOKUP_PRIV_VALUE  *r_c, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "lsa_io_q_lookupprivvalue");
+       prs_debug(ps, depth, desc, "lsa_io_q_lookup_priv_value");
        depth++;
 
        if(!prs_align(ps))
@@ -2002,21 +2020,19 @@ BOOL lsa_io_q_lookupprivvalue(const char *desc, LSA_Q_LOOKUPPRIVVALUE  *r_c, prs
  
        if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
                return False;
-       if(!smb_io_unihdr ("hdr_name", &r_c->hdr_right, ps, depth))
-               return False;
-       if(!smb_io_unistr2("uni2_right", &r_c->uni2_right, r_c->hdr_right.buffer, ps, depth))
+       if(!smb_io_lsa_string("privname", &r_c->privname, ps, depth))
                return False;
 
        return True;
 }
 
 /*******************************************************************
- Reads or writes an  LSA_R_LOOKUPPRIVVALUE structure.
+ Reads or writes an  LSA_R_LOOKUP_PRIV_VALUE structure.
 ********************************************************************/
 
-BOOL lsa_io_r_lookupprivvalue(const char *desc, LSA_R_LOOKUPPRIVVALUE  *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_r_lookup_priv_value(const char *desc, LSA_R_LOOKUP_PRIV_VALUE  *r_c, prs_struct *ps, int depth)
 {
-       prs_debug(ps, depth, desc, "lsa_io_r_lookupprivvalue");
+       prs_debug(ps, depth, desc, "lsa_io_r_lookup_priv_value");
        depth++;
 
        if(!prs_align(ps))
@@ -2271,7 +2287,6 @@ BOOL lsa_io_r_query_info2(const char *desc, LSA_R_QUERY_INFO2 *r_c,
        return True;
 }
 
-
 /*******************************************************************
  Inits an LSA_Q_ENUM_ACCT_RIGHTS structure.
 ********************************************************************/
index 27570ae8213cb576520da0fcf5004cc46f307f55..14d4bb9fdf7914bd7299fcf7b9698bad00f260de 100644 (file)
@@ -5148,6 +5148,12 @@ static BOOL sam_io_logon_hrs(const char *desc, LOGON_HRS * hrs,
        if(!prs_align(ps))
                return False;
 
+       if(!prs_uint32("maxlen", ps, depth, &hrs->max_len))
+               return False;
+
+       if(!prs_uint32("offset", ps, depth, &hrs->offset))
+               return False;
+
        if(!prs_uint32("len  ", ps, depth, &hrs->len))
                return False;
 
@@ -5471,7 +5477,7 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
                        LOGON_HRS * hrs,
                        uint16 bad_password_count,
                        uint16 logon_count,
-                       char newpass[516], uint32 unknown_6)
+                       char newpass[516])
 {
        usr->logon_time = *logon_time;  /* all zeros */
        usr->logoff_time = *logoff_time;        /* all zeros */
@@ -5535,9 +5541,6 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
        copy_unistr2(&usr->uni_munged_dial, mung_dial);
        init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
 
-       usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
-       usr->padding4 = 0;
-
        memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
 }
 
@@ -5562,7 +5565,7 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
                           uint32 group_rid, uint32 acb_info,
                           uint32 fields_present, uint16 logon_divs,
                           LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count,
-                          char newpass[516], uint32 unknown_6)
+                          char newpass[516])
 {
        DATA_BLOB blob = base64_decode_data_blob(mung_dial);
        
@@ -5630,9 +5633,6 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time,   /* all z
 
        data_blob_free(&blob);
        
-       usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
-       usr->padding4 = 0;
-
        memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
 }
 
@@ -5757,16 +5757,9 @@ static BOOL sam_io_user_info23(const char *desc, SAM_USER_INFO_23 * usr,
 
        /* ok, this is only guess-work (as usual) */
        if (usr->ptr_logon_hrs) {
-               if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
-                       return False;
-               if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
-                       return False;
                if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
                        return False;
-       } else if (UNMARSHALLING(ps)) {
-               usr->unknown_6 = 0;
-               usr->padding4 = 0;
-       }
+       } 
 
        return True;
 }
@@ -5876,16 +5869,9 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
 #if 0 /* JRA - unknown... */
        /* ok, this is only guess-work (as usual) */
        if (usr->ptr_logon_hrs) {
-               if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
-                       return False;
-               if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
-                       return False;
                if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
                        return False;
-       } else if (UNMARSHALLING(ps)) {
-               usr->unknown_6 = 0;
-               usr->padding4 = 0;
-       }
+       } 
 #endif
 
        return True;
@@ -5925,8 +5911,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
                           uint16 logon_divs,
                           LOGON_HRS * hrs,
                           uint16 bad_password_count,
-                          uint16 logon_count,
-                          uint32 unknown_6)
+                          uint16 logon_count)
 {
        usr->logon_time = *logon_time;
        usr->logoff_time = *logoff_time;
@@ -5987,9 +5972,6 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
        copy_unistr2(&usr->uni_munged_dial, mung_dial);
        init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
 
-       usr->unknown_6 = unknown_6;     /* 0x0000 04ec */
-       usr->padding4 = 0;
-
        memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
 }
 
@@ -6136,14 +6118,17 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
        data_blob_free(&munged_dial_blob);
 
-       usr->unknown_6 = pdb_get_unknown_6(pw);
-       usr->padding4 = 0;
-
        if (pdb_get_hours(pw)) {
+               usr->logon_hrs.max_len = 1260;
+               usr->logon_hrs.offset = 0;
                usr->logon_hrs.len = pdb_get_hours_len(pw);
                memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN);
-       } else
+       } else {
+               usr->logon_hrs.max_len = 1260;
+               usr->logon_hrs.offset = 0;
+               usr->logon_hrs.len = 0;
                memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs));
+       }
 
        return NT_STATUS_OK;
 }
@@ -6256,17 +6241,8 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr,
 
        /* ok, this is only guess-work (as usual) */
        if (usr->ptr_logon_hrs) {
-               if(!prs_align(ps))
-                       return False;
-               if(!prs_uint32("unknown_6     ", ps, depth, &usr->unknown_6))
-                       return False;
-               if(!prs_uint32("padding4      ", ps, depth, &usr->padding4))
-                       return False;
                if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
                        return False;
-       } else if (UNMARSHALLING(ps)) {
-               usr->unknown_6 = 0;
-               usr->padding4 = 0;
        }
 
        return True;
index e3c7832aacb290dd60ad096191a3c8d60e73aa03..dbd5d8c0bf6193bc9cbfff5c3de28662d2c33d46 100644 (file)
@@ -734,6 +734,39 @@ static BOOL api_lsa_enum_acct_rights(pipes_struct *p)
        return True;
 }
 
+/***************************************************************************
+ api_lsa_lookup_priv_value
+ ***************************************************************************/
+
+static BOOL api_lsa_lookup_priv_value(pipes_struct *p)
+{
+       LSA_Q_LOOKUP_PRIV_VALUE q_u;
+       LSA_R_LOOKUP_PRIV_VALUE 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(!lsa_io_q_lookup_priv_value("", &q_u, data, 0)) {
+               DEBUG(0,("api_lsa_lookup_priv_value: failed to unmarshall LSA_Q_LOOKUP_PRIV_VALUE .\n"));
+               return False;
+       }
+
+       r_u.status = _lsa_lookup_priv_value(p, &q_u, &r_u);
+
+       /* store the response in the SMB stream */
+       if(!lsa_io_r_lookup_priv_value("", &r_u, rdata, 0)) {
+               DEBUG(0,("api_lsa_lookup_priv_value: Failed to marshall LSA_R_LOOKUP_PRIV_VALUE.\n"));
+               return False;
+       }
+
+       return True;
+}
+
+#if 0  /* AD DC work in ongoing in Samba 4 */
+
 /***************************************************************************
  api_lsa_query_info2
  ***************************************************************************/
@@ -763,7 +796,7 @@ static BOOL api_lsa_query_info2(pipes_struct *p)
 
        return True;
 }
-
+#endif /* AD DC work in ongoing in Samba 4 */
 
 /***************************************************************************
  \PIPE\ntlsa commands
@@ -794,15 +827,19 @@ static struct api_struct api_lsa_cmds[] =
        { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights },
        { "LSA_ENUMACCTRIGHTS"  , LSA_ENUMACCTRIGHTS  , api_lsa_enum_acct_rights },
        { "LSA_QUERYSECOBJ"     , LSA_QUERYSECOBJ     , api_lsa_query_secobj     },
+       { "LSA_LOOKUPPRIVVALUE" , LSA_LOOKUPPRIVVALUE , api_lsa_lookup_priv_value }
+#if 0  /* AD DC work in ongoing in Samba 4 */
        /* be careful of the adding of new RPC's.  See commentrs below about
           ADS DC capabilities                                               */
        { "LSA_QUERYINFO2"      , LSA_QUERYINFO2      , api_lsa_query_info2      }
+#endif /* AD DC work in ongoing in Samba 4 */
 };
 
 static int count_fns(void)
 {
        int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
        
+#if 0  /* AD DC work is on going in Samba 4 */
        /*
         * NOTE: Certain calls can not be enabled if we aren't an ADS DC.  Make sure
         * these calls are always last and that you decrement by the amount of calls
@@ -811,6 +848,7 @@ static int count_fns(void)
        if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
                funcs -= 1;
        }
+#endif /* AD DC work in ongoing in Samba 4 */
 
        return funcs;
 }
index 225e5efd54c5881c740aeae75e5f971bc957ac3d..7ea35a91faf35845f552a9ff73fd2b1fe8872d1b 100644 (file)
@@ -8,6 +8,7 @@
  *  Copyright (C) Rafal Szczesniak                  2002,
  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
  *  Copyright (C) Simo Sorce                        2003.
+ *  Copyright (C) Gerald (Jerry) Carter             2005.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -345,6 +346,8 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s
        return NT_STATUS_OK;
 }
 
+#if 0  /* AD DC work in ongoing in Samba 4 */
+
 /***************************************************************************
  Init_dns_dom_info.
 ***************************************************************************/
@@ -384,6 +387,8 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
                init_dom_sid2(&r_l->dom_sid, dom_sid);
        }
 }
+#endif /* AD DC work in ongoing in Samba 4 */
+
 
 /***************************************************************************
  _lsa_open_policy2.
@@ -776,9 +781,6 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV
        DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", 
                enum_context, num_privs));
        
-       if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs + 1)))
-               return NT_STATUS_NO_MEMORY;
-
        if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
                return NT_STATUS_INVALID_HANDLE;
 
@@ -791,7 +793,6 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV
        if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
                return NT_STATUS_NO_MEMORY;
 
-
        for (i = 0; i < num_privs; i++) {
                if( i < enum_context) {
                        init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
@@ -1143,7 +1144,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
                
        /* check to see if the pipe_user is root or a Domain Admin since 
           account_pol.tdb was already opened as root, this is all we have */
-
+          
        get_current_user( &user, p );
        if ( user.uid != sec_initial_uid() 
                && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
@@ -1184,7 +1185,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
 
        /* check to see if the pipe_user is root or a Domain Admin since 
           account_pol.tdb was already opened as root, this is all we have */
-
+          
        get_current_user( &user, p );
        if ( user.uid != sec_initial_uid()
                && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
@@ -1261,6 +1262,8 @@ NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUER
        return r_u->status;
 }
 
+#if 0  /* AD DC work in ongoing in Samba 4 */
+
 /***************************************************************************
  ***************************************************************************/
 
@@ -1323,6 +1326,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I
 
        return r_u->status;
 }
+#endif /* AD DC work in ongoing in Samba 4 */
 
 /***************************************************************************
  ***************************************************************************/
@@ -1474,3 +1478,31 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA
 }
 
 
+NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
+{
+       struct lsa_info *info = NULL;
+       fstring name;
+       LUID_ATTR priv_luid;
+       SE_PRIV mask;
+       
+       /* find the connection policy handle. */
+       
+       if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+               return NT_STATUS_INVALID_HANDLE;
+               
+       unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
+       
+       DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name));
+
+       if ( !se_priv_from_name( name, &mask ) )
+               return NT_STATUS_NO_SUCH_PRIVILEGE;
+
+       priv_luid = get_privilege_luid( &mask );
+
+       r_u->luid.low  = priv_luid.luid.low;
+       r_u->luid.high = priv_luid.luid.high;
+               
+
+       return NT_STATUS_OK;
+}
+
index 8a10fa6d2da3812c9f575da8edcb432f3ad1b63b..139960f661316728438133698ff94fe94481a792 100644 (file)
@@ -2335,6 +2335,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
        
        /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
 
+       flush_pwnam_cache();
        nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
 
        /* this code is order such that we have no unnecessary retuns 
@@ -3805,6 +3806,7 @@ static int smb_delete_user(const char *unix_user)
                return -1;
        all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
        ret = smbrun(del_script,NULL);
+       flush_pwnam_cache();
        DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
 
        return ret;
index dd12a438caeeade3399fc372f162a551407db17e..6797730be97abb50f32e4c3ddbc75306b6d3c911 100644 (file)
@@ -268,12 +268,6 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
                if (!strequal(old, new)) {
                        pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
                }
-
-               /* This is max logon hours */
-               DEBUG(10,("INFO_21 UNKNOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
-               if (from->unknown_6 != pdb_get_unknown_6(to)) {
-                       pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
-               }
        }
 
        if (from->fields_present & ACCT_BAD_PWD_COUNT) {
@@ -296,8 +290,6 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
        }
 
        DEBUG(10,("INFO_21 PADDING_2: %02X\n",from->padding2));
-
-       DEBUG(10,("INFO_21 PADDING_4: %08X\n",from->padding4));
 }
 
 
@@ -499,11 +491,6 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
                /* Fix me: only update if it changes --metze */
                pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
 
-               /* This is max logon hours */
-               DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown_6(to),from->unknown_6));
-               if (from->unknown_6 != pdb_get_unknown_6(to)) {
-                       pdb_set_unknown_6(to, from->unknown_6, PDB_CHANGED);
-               }
        }
 
        if (from->fields_present & ACCT_BAD_PWD_COUNT) {
@@ -526,6 +513,4 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
        }
 
        DEBUG(10,("INFO_23 PADDING_2: %02X\n",from->padding2));
-
-       DEBUG(10,("INFO_23 PADDING_4: %08X\n",from->padding4));
 }
index ed7a544d72de9b7b918334aa471a195c03f4c6a0..ffeeb0af9a9da1ed6c1d7924e089f2dcf68ba6af 100644 (file)
@@ -2310,7 +2310,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
                
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC_ZERO(ctx, 4*sizeof(uint8) )) == NULL)
                        return WERR_NOMEM;
                *needed = 0x4;
@@ -2318,7 +2318,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "BeepEnabled")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4*sizeof(uint8) )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0x00);
@@ -2327,7 +2327,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "EventLog")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                /* formally was 0x1b */
@@ -2337,7 +2337,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "NetPopup")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0x00);
@@ -2346,7 +2346,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "MajorVersion")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
 
@@ -2365,7 +2365,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "MinorVersion")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0);
@@ -2381,7 +2381,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
         *  extra unicode string = e.g. "Service Pack 3"
         */
        if (!StrCaseCmp(value, "OSVersion")) {
-               *type = 0x3;
+               *type = REG_BINARY;
                *needed = 0x114;
 
                if((*data = (uint8 *)TALLOC(ctx, *needed)) == NULL)
@@ -2401,7 +2401,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
 
        if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
                const char *string="C:\\PRINTERS";
-               *type = 0x1;                    
+               *type = REG_SZ;
                *needed = 2*(strlen(string)+1);         
                if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
@@ -2417,7 +2417,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
 
        if (!StrCaseCmp(value, "Architecture")) {                       
                const char *string="Windows NT x86";
-               *type = 0x1;                    
+               *type = REG_SZ;
                *needed = 2*(strlen(string)+1); 
                if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
@@ -2430,10 +2430,18 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "DsPresent")) {
-               *type = 0x4;
+               *type = REG_DWORD;
                if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
-               SIVAL(*data, 0, 0x01);
+
+               /* only show the publish check box if we are a 
+                  memeber of a AD domain */
+
+               if ( lp_security() == SEC_ADS )
+                       SIVAL(*data, 0, 0x01);
+               else
+                       SIVAL(*data, 0, 0x00);
+
                *needed = 0x4;
                return WERR_OK;
        }
@@ -2443,7 +2451,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
                
                if (!get_mydnsfullname(hostname))
                        return WERR_BADFILE;
-               *type = 0x1;                    
+               *type = REG_SZ;
                *needed = 2*(strlen(hostname)+1);       
                if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
index 597c950a2416eece4b66e1df98370d23d078782f..f6ecd8c706dc2061036ea36732832f6aaff8b656 100644 (file)
@@ -176,6 +176,8 @@ static NTSTATUS cmd_lsa_lookup_names(struct cli_state *cli,
                       sid_type_lookup(types[i]), types[i]);
        }
 
+       cli_lsa_close(cli, mem_ctx, &pol);
+
  done:
        return result;
 }
@@ -242,6 +244,8 @@ static NTSTATUS cmd_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                       names[i] ? names[i] : "*unknown*", types[i]);
        }
 
+       cli_lsa_close(cli, mem_ctx, &pol);
+
  done:
        return result;
 }
@@ -673,7 +677,7 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct cli_state *cli,
 
 /* Get a privilege value given its name */
 
-static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli, 
+static NTSTATUS cmd_lsa_lookup_priv_value(struct cli_state *cli, 
                                        TALLOC_CTX *mem_ctx, int argc, 
                                        const char **argv) 
 {
@@ -693,7 +697,7 @@ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
        if (!NT_STATUS_IS_OK(result))
                goto done;
 
-       result = cli_lsa_lookupprivvalue(cli, mem_ctx, &pol, argv[1], &luid);
+       result = cli_lsa_lookup_priv_value(cli, mem_ctx, &pol, argv[1], &luid);
 
        if (!NT_STATUS_IS_OK(result))
                goto done;
@@ -765,7 +769,7 @@ struct cmd_set lsarpc_commands[] = {
 #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_lookupprivvalue,    NULL, PI_LSARPC, "Get a privilege value given its name", "" },
+       { "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", "" },
 
        { NULL }
index b4a8c8a75285cf217fc92e485f4b4e2322d8a7ce..5773cd34790840111e3b700cfb5d75f87552f51e 100644 (file)
@@ -71,8 +71,7 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
        else
                fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) );
 
-       pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid :
-                                                (unsigned long)id.gid));       
+       pstr_sprintf(id_str, "%d", ((id_type & ID_USERID) ? id.uid : id.gid));  
        
        smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
 
@@ -501,9 +500,9 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
                type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
 
        pstrcpy( suffix, lp_ldap_idmap_suffix() );
-       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+       pstr_sprintf(filter, "(&(objectClass=%s)(%s=%d))",
                LDAP_OBJ_IDMAP_ENTRY, type,  
-               ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid));
+               ((id_type & ID_USERID) ? id.uid : id.gid));
                
        attr_list = get_attr_list( sidmap_attr_list );
        rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, 
@@ -701,8 +700,8 @@ static NTSTATUS verify_idpool( void )
                        return NT_STATUS_UNSUCCESSFUL;
                }
                
-               fstr_sprintf( uid_str, "%lu", (unsigned long)luid );
-               fstr_sprintf( gid_str, "%lu", (unsigned long)lgid );
+               fstr_sprintf( uid_str, "%d", luid );
+               fstr_sprintf( gid_str, "%d", lgid );
 
                smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
                smbldap_set_mod( &mods, LDAP_MOD_ADD, 
index 6315c6ab2e6f9b692f28fbbb01e066c41476d13b..48e496b4b7a99ccbdac79dab69545fab475abe21 100644 (file)
@@ -146,9 +146,9 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
        fstring dc_name;
        struct in_addr dc_ip;
-       char *password = NULL;
-       char *username = NULL;
-       char *domain = NULL;
+       const char *password = NULL;
+       const char *username = NULL;
+       const char *domain = NULL;
        uint32 info_class = 5;
        char *domain_name = NULL;
        DOM_SID *domain_sid, sid;
index 4445f2516bc4eecf0c1bb76cb9c332e30b19fda9..b3244432ff559be4a6146f2aedb017522f663808 100644 (file)
@@ -260,8 +260,10 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
         * Ensure pending modtime is set after close.
         */
 
-       if(fsp->pending_modtime) {
+       if(fsp->pending_modtime && fsp->pending_modtime_owner) {
                set_filetime(conn, fsp->fsp_name, fsp->pending_modtime);
+       } else if (fsp->last_write_time) {
+               set_filetime(conn, fsp->fsp_name, fsp->last_write_time);
        }
 
        DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
index 7dde18f4306600fcb642b3d8c97d882e6815f175..d9fd382d5204729d3957cf5fce5323920fa9b73a 100644 (file)
@@ -525,10 +525,17 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
        pstring pathreal;
 
        ZERO_STRUCTP(pst);
+
        if (dptr->has_wild) {
                return dptr_normal_ReadDirName(dptr, poffset, pst);
        }
 
+       /* If poffset is -1 then we know we returned this name before and we have
+          no wildcards. We're at the end of the directory. */
+       if (*poffset == -1) {
+               return NULL;
+       }
+
        /* We know the stored wcard contains no wildcard characters. See if we can match
           with a stat call. If we can't, then set has_wild to true to
           prevent us from doing this on every call. */
@@ -540,6 +547,9 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
        }
 
        if (VALID_STAT(*pst)) {
+               /* We need to set the underlying dir_hdn offset to -1 also as
+                  this function is usually called with the output from TellDir. */
+               dptr->dir_hnd->offset = *poffset = -1;
                return dptr->wcard;
        }
 
@@ -548,11 +558,17 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
        pstrcat(pathreal,dptr->wcard);
 
        if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
+               /* We need to set the underlying dir_hdn offset to -1 also as
+                  this function is usually called with the output from TellDir. */
+               dptr->dir_hnd->offset = *poffset = -1;
                return dptr->wcard;
        } else {
                /* If we get any other error than ENOENT or ENOTDIR
                   then the file exists we just can't stat it. */
                if (errno != ENOENT && errno != ENOTDIR) {
+                       /* We need to set the underlying dir_hdn offset to -1 also as
+                          this function is usually called with the output from TellDir. */
+                       dptr->dir_hnd->offset = *poffset = -1;
                        return dptr->wcard;
                }
        }
@@ -563,6 +579,9 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
           with a stat we will fail. */
 
        if (dptr->conn->case_sensitive) {
+               /* We need to set the underlying dir_hdn offset to -1 also as
+                  this function is usually called with the output from TellDir. */
+               dptr->dir_hnd->offset = *poffset = -1;
                return NULL;
        } else {
                return dptr_normal_ReadDirName(dptr, poffset, pst);
@@ -1033,6 +1052,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
                *poffset = e->offset= dirp->offset;
                return e->name;
        }
+       dirp->offset = -1;
        return NULL;
 }
 
index a21bd69a36c634c232e9477c91e967f03618aa30..3048c27fa25ee967de23ac2efdb6a2c6168a5017 100644 (file)
@@ -142,6 +142,12 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
 
                if (fsp->pending_modtime) {
                        set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime);
+
+                       /* If we didn't get the "set modtime" call ourselves, we must
+                          store the last write time to restore on close. JRA. */
+                       if (!fsp->pending_modtime_owner) {
+                               fsp->last_write_time = time(NULL);
+                       }
                }
 
 /* Yes - this is correct - writes don't update this. JRA. */
index ecf39c2b54f0d70536c7fb5df52079b6968846f6..143c1196937585687f8d2dbc0ccc4cb48edf7ee3 100644 (file)
@@ -37,6 +37,13 @@ static files_struct *oplock_save_chain_fsp = NULL;
 
 static int files_used;
 
+/* A singleton cache to speed up searching by dev/inode. */
+static struct fsp_singleton_cache {
+       files_struct *fsp;
+       SMB_DEV_T dev;
+       SMB_INO_T inode;
+} fsp_fi_cache;
+
 /****************************************************************************
  Return a unique number identifying this fsp over the life of this pid.
 ****************************************************************************/
@@ -122,6 +129,11 @@ files_struct *file_new(connection_struct *conn)
                 i, fsp->fnum, files_used));
 
        chain_fsp = fsp;
+
+       /* A new fsp invalidates a negative fsp_fi_cache. */
+       if (fsp_fi_cache.fsp == NULL) {
+               ZERO_STRUCT(fsp_fi_cache);
+       }
        
        return fsp;
 }
@@ -299,19 +311,34 @@ files_struct *file_find_fsp(files_struct *orig_fsp)
 
 /****************************************************************************
  Find the first fsp given a device and inode.
+ We use a singleton cache here to speed up searching from getfilepathinfo
+ calls.
 ****************************************************************************/
 
 files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
 {
        files_struct *fsp;
 
+       if (fsp_fi_cache.dev == dev && fsp_fi_cache.inode == inode) {
+               /* Positive or negative cache hit. */
+               return fsp_fi_cache.fsp;
+       }
+
+       fsp_fi_cache.dev = dev;
+       fsp_fi_cache.inode = inode;
+
        for (fsp=Files;fsp;fsp=fsp->next) {
                if ( fsp->fd != -1 &&
                                fsp->dev == dev &&
-                               fsp->inode == inode )
+                               fsp->inode == inode ) {
+                       /* Setup positive cache. */
+                       fsp_fi_cache.fsp = fsp;
                        return fsp;
+               }
        }
 
+       /* Setup negative cache. */
+       fsp_fi_cache.fsp = NULL;
        return NULL;
 }
 
@@ -342,12 +369,39 @@ files_struct *file_find_print(void)
        files_struct *fsp;
 
        for (fsp=Files;fsp;fsp=fsp->next) {
-               if (fsp->print_file) return fsp;
+               if (fsp->print_file) {
+                       return fsp;
+               }
        } 
 
        return NULL;
 }
 
+/****************************************************************************
+ Set a pending modtime across all files with a given dev/ino pair.
+ Record the owner of that modtime.
+****************************************************************************/
+
+void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
+{
+       files_struct *fsp;
+
+       if (null_mtime(pmod)) {
+               return;
+       }
+
+       for (fsp = Files;fsp;fsp=fsp->next) {
+               if ( fsp->fd != -1 &&
+                               fsp->dev == tfsp->dev &&
+                               fsp->inode == tfsp->inode ) {
+                       fsp->pending_modtime = pmod;
+                       fsp->pending_modtime_owner = False;
+               }
+       }
+
+       tfsp->pending_modtime_owner = True;
+}
+
 /****************************************************************************
  Sync open files on a connection.
 ****************************************************************************/
@@ -392,6 +446,11 @@ void file_free(files_struct *fsp)
                chain_fsp = NULL;
        }
 
+       /* Closing a file can invalidate the positive cache. */
+       if (fsp == fsp_fi_cache.fsp) {
+               ZERO_STRUCT(fsp_fi_cache);
+       }
+
        SAFE_FREE(fsp);
 }
 
index 675da4c74786bd534ef476fc40a9c8d7a9e4ea0e..fbb73640901d75be2decfa48244e77bc32295d19 100644 (file)
@@ -929,7 +929,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
        allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
 #endif
        if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
-               fsp->initial_allocation_size = allocation_size;
+               fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
                if (fsp->is_directory) {
                        close_file(fsp,False);
                        END_PROFILE(SMBntcreateX);
@@ -942,7 +942,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                        return ERROR_NT(NT_STATUS_DISK_FULL);
                }
        } else {
-               fsp->initial_allocation_size = (SMB_BIG_UINT)file_len;
+               fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
        }
 
        /* 
@@ -1012,7 +1012,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
        p += 8;
        SIVAL(p,0,fmode); /* File Attributes. */
        p += 4;
-       SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
+       SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
        p += 8;
        SOFF_T(p,0,file_len);
        p += 8;
@@ -1472,7 +1472,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
 #endif
        if (allocation_size && (allocation_size > file_len)) {
-               fsp->initial_allocation_size = allocation_size;
+               fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
                if (fsp->is_directory) {
                        close_file(fsp,False);
                        END_PROFILE(SMBntcreateX);
@@ -1484,7 +1484,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                        return ERROR_NT(NT_STATUS_DISK_FULL);
                }
        } else {
-               fsp->initial_allocation_size = (SMB_BIG_UINT)file_len;
+               fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
        }
 
        /* Realloc the size of parameters and data we will return */
@@ -1529,7 +1529,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        p += 8;
        SIVAL(p,0,fmode); /* File Attributes. */
        p += 4;
-       SOFF_T(p, 0, get_allocation_size(fsp,&sbuf));
+       SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
        p += 8;
        SOFF_T(p,0,file_len);
        p += 8;
@@ -1698,7 +1698,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
        close_file(fsp1,False);
 
        /* Ensure the modtime is set correctly on the destination file. */
-       fsp2->pending_modtime = sbuf1.st_mtime;
+       fsp_set_pending_modtime(fsp2, sbuf1.st_mtime);
 
        close_ret = close_file(fsp2,False);
 
index 70632a20eb71d3c806079d93fbda46d1da0c3c19..a552dc5b610174ff8296d876128fe07b683a70d5 100644 (file)
@@ -491,9 +491,18 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
                unix_ERR_class = ERRDOS;
                unix_ERR_code = ERRbadshare;
                unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
+               return False;
+       }
 
+#if 0
+       /* Bluarc test may need this ... needs further investigation. */
+       if (deny_mode == DENY_ALL || old_deny_mode == DENY_ALL) {
+               unix_ERR_class = ERRDOS;
+               unix_ERR_code = ERRbadshare;
+               unix_ERR_ntstatus = NT_STATUS_SHARING_VIOLATION;
                return False;
        }
+#endif
 
        /*
         * If desired_access doesn't contain READ_DATA,WRITE_DATA,APPEND_DATA or EXECUTE
@@ -502,7 +511,7 @@ existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsign
 
        if ( !(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
                !(share->desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ) {
-               DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with\
+               DEBUG(5,("check_share_mode: Allowing open on file %s as desired access (0x%x) doesn't conflict with \
 existing desired access (0x%x).\n", fname, (unsigned int)desired_access, (unsigned int)share->desired_access ));
                return True;
        }
index d02edc5ea06000cb1eae0ce106eac8a080f1a628..c5f96db85c1201d85355d9ccc60fffa78a73a666 100644 (file)
@@ -3903,10 +3903,26 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname)
        if (current_user.uid == sbuf.st_uid) {
                return (sbuf.st_mode & S_IWUSR) ? True : False;
        }
+
+#ifdef S_ISVTX
+       /* sticky bit means delete only by owner or root. */
+       if (sbuf.st_mode & S_ISVTX) {
+               SMB_STRUCT_STAT sbuf_file;  
+               if(SMB_VFS_STAT(conn, fname, &sbuf_file) != 0) {
+                       return False;
+               }
+               if (current_user.uid == sbuf_file.st_uid) {
+                       return True;
+               }
+               return False;
+       }
+#endif
+
        /* Check group ownership. */
        ret = check_posix_acl_group_write(conn, dname, &sbuf);
        if (ret == 0 || ret == 1) {
                return ret ? True : False;
        }
+
        return (sbuf.st_mode & S_IWOTH) ? True : False;
 }
index 89183aed347abf3a3d148f62947849a3f8b6185d..f149b79f793bd7a5a476c9199cd6556a972f58dd 100644 (file)
@@ -2875,6 +2875,13 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
                         fsp->fd, fsp->fnum,
                         conn->num_files_open));
  
+               /*
+                * Take care of any time sent in the close.
+                */
+
+               mtime = make_unix_date3(inbuf+smb_vwv1);
+               fsp_set_pending_modtime(fsp, mtime);
+
                /*
                 * close_file() returns the unix errno if an error
                 * was detected on close - normally this is due to
@@ -2886,16 +2893,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
                        END_PROFILE(SMBclose);
                        return (UNIXERROR(ERRHRD,ERRgeneral));
                }
-
-               /*
-                * Now take care of any time sent in the close.
-                */
-
-               mtime = make_unix_date3(inbuf+smb_vwv1);
-               
-               /* try and set the date */
-               set_filetime(conn, file_name, mtime);
-
        }  
 
        /* We have a cached error */
@@ -4233,7 +4230,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        close_file(fsp1,False);
 
        /* Ensure the modtime is set correctly on the destination file. */
-       fsp2->pending_modtime = src_sbuf.st_mtime;
+       fsp_set_pending_modtime( fsp2, src_sbuf.st_mtime);
 
        /*
         * As we are opening fsp1 read-only we only expect
@@ -4917,7 +4914,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
         * Sometimes times are sent as zero - ignore them.
         */
 
-       if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
+       if (null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
                /* Ignore request */
                if( DEBUGLVL( 3 ) ) {
                        dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
@@ -4925,12 +4922,13 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
                }
                END_PROFILE(SMBsetattrE);
                return(outsize);
-       } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
-               /* set modify time = to access time if modify time was 0 */
+       } else if (!null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
+               /* set modify time = to access time if modify time was unset */
                unix_times.modtime = unix_times.actime;
        }
 
        /* Set the date on this file */
+       /* Should we set pending modtime here ? JRA */
        if(file_utime(conn, fsp->fsp_name, &unix_times)) {
                END_PROFILE(SMBsetattrE);
                return ERROR_DOS(ERRDOS,ERRnoaccess);
@@ -5170,13 +5168,14 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
        put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
        put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
+       /* Should we check pending modtime here ? JRA */
        put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
 
        if (mode & aDIR) {
                SIVAL(outbuf,smb_vwv6,0);
                SIVAL(outbuf,smb_vwv8,0);
        } else {
-               uint32 allocation_size = get_allocation_size(fsp, &sbuf);
+               uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
                SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
                SIVAL(outbuf,smb_vwv8,allocation_size);
        }
index f199fe3ade6abe5f290de018aa2a846dceacf994..684d49c56aeab39adbabe430fa442373263cc41d 100644 (file)
@@ -278,6 +278,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
 
        *user = 0;
        fstrcpy(dev, pdev);
+       ZERO_STRUCT(st);
 
        if (NT_STATUS_IS_ERR(*status = share_sanity_checks(snum, dev))) {
                return NULL;
@@ -605,24 +606,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        }
 #endif
        
-#if CHECK_PATH_ON_TCONX
        /* win2000 does not check the permissions on the directory
           during the tree connect, instead relying on permission
           check during individual operations. To match this behaviour
           I have disabled this chdir check (tridge) */
-       if (vfs_ChDir(conn,conn->connectpath) != 0) {
-               DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
-                        get_remote_machine_name(), conn->client_address,
-                        conn->connectpath,strerror(errno)));
-               change_to_root_user();
-               yield_connection(conn, lp_servicename(SNUM(conn)));
-               conn_free(conn);
-               *status = NT_STATUS_BAD_NETWORK_NAME;
-               return NULL;
-       }
-#else
        /* the alternative is just to check the directory exists */
-       if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
+       if (SMB_VFS_STAT(conn, conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
                DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
                change_to_root_user();
                yield_connection(conn, lp_servicename(SNUM(conn)));
@@ -630,7 +619,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
                *status = NT_STATUS_BAD_NETWORK_NAME;
                return NULL;
        }
-#endif
        
        string_set(&conn->origpath,conn->connectpath);
        
index d22705214e4973b26c1da15e28893395baf2b2f7..3f3d9c2f461fa33975116b9d24c6050bc6c7f336 100644 (file)
@@ -32,12 +32,29 @@ extern struct current_user current_user;
 #define get_file_size(sbuf) ((sbuf).st_size)
 #define DIR_ENTRY_SAFETY_MARGIN 4096
 
+/********************************************************************
+ Roundup a value to the nearest allocation roundup size boundary.
+ Only do this for Windows clients.
+********************************************************************/
+
+SMB_BIG_UINT smb_roundup(connection_struct *conn, SMB_BIG_UINT val)
+{
+       SMB_BIG_UINT rval = lp_allocation_roundup_size(SNUM(conn));
+
+       /* Only roundup for Windows clients. */
+       enum remote_arch_types ra_type = get_remote_arch();
+       if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
+               val = SMB_ROUNDUP(val,rval);
+       }
+       return val;
+}
+
 /********************************************************************
  Given a stat buffer return the allocated size on disk, taking into
  account sparse files.
 ********************************************************************/
 
-SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
+SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
 {
        SMB_BIG_UINT ret;
 
@@ -50,7 +67,7 @@ SMB_BIG_UINT get_allocation_size(files_struct *fsp, SMB_STRUCT_STAT *sbuf)
        if (!ret && fsp && fsp->initial_allocation_size)
                ret = fsp->initial_allocation_size;
 
-       return ret;
+       return smb_roundup(conn, ret);
 }
 
 /****************************************************************************
@@ -794,7 +811,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                                 BOOL dont_descend,char **ppdata, 
                                 char *base_data, int space_remaining, 
                                 BOOL *out_of_space, BOOL *got_exact_match,
-                                int *last_name_off)
+                                int *last_entry_off)
 {
        const char *dname;
        BOOL found = False;
@@ -811,6 +828,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        uint32 len;
        time_t mdate=0, adate=0, cdate=0;
        char *nameptr;
+       char *last_entry_ptr;
        BOOL was_8_3;
        int nt_extmode; /* Used for NT connections instead of mode */
        BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
@@ -919,7 +937,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        }
 
                        file_size = get_file_size(sbuf);
-                       allocation_size = get_allocation_size(NULL,&sbuf);
+                       allocation_size = get_allocation_size(conn,NULL,&sbuf);
                        mdate = sbuf.st_mtime;
                        adate = sbuf.st_atime;
                        cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
@@ -947,7 +965,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
        mangle_map(fname,False,True,SNUM(conn));
 
        p = pdata;
-       nameptr = p;
+       last_entry_ptr = p;
 
        nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
 
@@ -1215,7 +1233,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                        SOFF_T(p,0,get_file_size(sbuf));             /* File size 64 Bit */
                        p+= 8;
 
-                       SOFF_T(p,0,get_allocation_size(NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
+                       SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
                        p+= 8;
 
                        put_long_date(p,sbuf.st_ctime);       /* Inode change Time 64 Bit */
@@ -1277,8 +1295,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
                return False; /* Not finished - just out of space */
        }
 
-       /* Setup the last_filename pointer, as an offset from base_data */
-       *last_name_off = PTR_DIFF(nameptr,base_data);
+       /* Setup the last entry pointer, as an offset from base_data */
+       *last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
        /* Advance the data pointer to the next slot */
        *ppdata = p;
 
@@ -1310,7 +1328,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
        pstring directory;
        pstring mask;
        char *p;
-       int last_name_off=0;
+       int last_entry_off=0;
        int dptr_num = -1;
        int numentries = 0;
        int i;
@@ -1360,7 +1378,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                return ERROR_NT(ntstatus);
        }
 
-       RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
+       RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
 
        unix_convert(directory,conn,0,&bad_path,&sbuf);
        if (bad_path) {
@@ -1437,7 +1455,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                                        mask,dirtype,info_level,
                                        requires_resume_key,dont_descend,
                                        &p,pdata,space_remaining, &out_of_space, &got_exact_match,
-                                       &last_name_off);
+                                       &last_entry_off);
                }
 
                if (finished && out_of_space)
@@ -1482,7 +1500,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
        SSVAL(params,2,numentries);
        SSVAL(params,4,finished);
        SSVAL(params,6,0); /* Never an EA error */
-       SSVAL(params,8,last_name_off);
+       SSVAL(params,8,last_entry_off);
 
        send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
 
@@ -1537,7 +1555,7 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
        char *p;
        uint16 dirtype;
        int numentries = 0;
-       int i, last_name_off=0;
+       int i, last_entry_off=0;
        BOOL finished = False;
        BOOL dont_descend = False;
        BOOL out_of_space = False;
@@ -1674,7 +1692,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
                                                mask,dirtype,info_level,
                                                requires_resume_key,dont_descend,
                                                &p,pdata,space_remaining, &out_of_space, &got_exact_match,
-                                               &last_name_off);
+                                               &last_entry_off);
                }
 
                if (finished && out_of_space)
@@ -1706,7 +1724,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
        SSVAL(params,0,numentries);
        SSVAL(params,2,finished);
        SSVAL(params,4,0); /* Never an EA error */
-       SSVAL(params,6,last_name_off);
+       SSVAL(params,6,last_entry_off);
 
        send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
 
@@ -2422,7 +2440,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
 
        fullpathname = fname;
        file_size = get_file_size(sbuf);
-       allocation_size = get_allocation_size(fsp,&sbuf);
+       allocation_size = get_allocation_size(conn,fsp,&sbuf);
        if (mode & aDIR) {
                /* This is necessary, as otherwise the desktop.ini file in
                 * this folder is ignored */
@@ -2451,9 +2469,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
 
        c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
 
-       if (fsp && fsp->pending_modtime) {
-               /* the pending modtime overrides the current modtime */
-               sbuf.st_mtime = fsp->pending_modtime;
+       if (fsp) {
+               if (fsp->pending_modtime) {
+                       /* the pending modtime overrides the current modtime */
+                       sbuf.st_mtime = fsp->pending_modtime;
+               }
+       } else {
+               /* Do we have this path open ? */
+               files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
+               if (fsp1 && fsp1->pending_modtime) {
+                       /* the pending modtime overrides the current modtime */
+                       sbuf.st_mtime = fsp1->pending_modtime;
+               }
        }
 
        if (lp_dos_filetime_resolution(SNUM(conn))) {
@@ -2768,7 +2795,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
                        SOFF_T(pdata,0,get_file_size(sbuf));             /* File size 64 Bit */
                        pdata += 8;
 
-                       SOFF_T(pdata,0,get_allocation_size(fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
+                       SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
                        pdata += 8;
 
                        put_long_date(pdata,sbuf.st_ctime);       /* Creation Time 64 Bit */
@@ -3305,9 +3332,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                                tvs.modtime = write_time;
                        }
                        /* Prefer a defined time to an undefined one. */
-                       if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
-                               tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
-                                       ? changed_time : write_time);
+                       if (null_mtime(tvs.modtime)) {
+                               tvs.modtime = null_mtime(write_time) ? changed_time : write_time;
+                       }
 
                        /* attributes */
                        dosmode = IVAL(pdata,32);
@@ -3333,6 +3360,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
                        DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
                                        fname, (double)allocation_size ));
 
+                       if (allocation_size) {
+                               allocation_size = smb_roundup(conn, allocation_size);
+                       }
+
                        if(allocation_size != get_file_size(sbuf)) {
                                SMB_STRUCT_STAT new_sbuf;
  
@@ -3783,11 +3814,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
        }
 
        /* get some defaults (no modifications) if any info is zero or -1. */
-       if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
+       if (null_mtime(tvs.actime)) {
                tvs.actime = sbuf.st_atime;
+       }
 
-       if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
+       if (null_mtime(tvs.modtime)) {
                tvs.modtime = sbuf.st_mtime;
+       }
 
        DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
        DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
@@ -3819,30 +3852,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
         * Try and set the times, size and mode of this file -
         * if they are different from the current values
         */
-       if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
-               if(fsp != NULL) {
-                       /*
-                        * This was a setfileinfo on an open file.
-                        * NT does this a lot. We also need to 
-                        * set the time here, as it can be read by 
-                        * FindFirst/FindNext and with the patch for bug #2045
-                        * in smbd/fileio.c it ensures that this timestamp is
-                        * kept sticky even after a write. We save the request
-                        * away and will set it on file close and after a write. JRA.
-                        */
-
-                       if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
-                               DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
-                               fsp->pending_modtime = tvs.modtime;
-                       }
-
-                       DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
-
-                       if(file_utime(conn, fname, &tvs)!=0) {
-                               return(UNIXERROR(ERRDOS,ERRnoaccess));
-                       }
-               }
-       }
 
        /* check the mode isn't different, before changing it */
        if ((dosmode != 0) && (dosmode != dos_mode(conn, fname, &sbuf))) {
@@ -3855,6 +3864,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                }
        }
 
+       /* Now the size. */
        if (size != get_file_size(sbuf)) {
 
                int ret;
@@ -3895,6 +3905,34 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        return (UNIXERROR(ERRHRD,ERRdiskfull));
        }
 
+       /*
+        * Finally the times.
+        */
+       if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
+               if(fsp != NULL) {
+                       /*
+                        * This was a setfileinfo on an open file.
+                        * NT does this a lot. We also need to 
+                        * set the time here, as it can be read by 
+                        * FindFirst/FindNext and with the patch for bug #2045
+                        * in smbd/fileio.c it ensures that this timestamp is
+                        * kept sticky even after a write. We save the request
+                        * away and will set it on file close and after a write. JRA.
+                        */
+
+                       if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
+                               DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n", ctime(&tvs.modtime) ));
+                               fsp_set_pending_modtime(fsp, tvs.modtime);
+                       }
+
+               }
+               DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
+
+               if(file_utime(conn, fname, &tvs)!=0) {
+                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+               }
+       }
+
        SSVAL(params,0,0);
        send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
   
index ec13abc1c1ff7741576d51e7e17f0100f6336fc2..37aefc55acfb2a5bc75c888ad0c05ee4cf2c541c 100644 (file)
@@ -2666,9 +2666,10 @@ static BOOL run_oplock2(int dummy)
 
        sleep(2);
 
-       /* Ensure cli1 processes the break. */
+       /* Ensure cli1 processes the break. Empty file should always return 0
+        * bytes.  */
 
-       if (cli_read(cli1, fnum1, buf, 0, 4) != 4) {
+       if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
                printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
@@ -4138,7 +4139,7 @@ static BOOL run_openattrtest(int dummy)
        return correct;
 }
 
-static void list_fn(file_info *finfo, const char *name, void *state)
+static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
 {
        
 }
@@ -4198,7 +4199,7 @@ static BOOL run_dirtest(int dummy)
        return correct;
 }
 
-static void del_fn(file_info *finfo, const char *mask, void *state)
+static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
 {
        struct cli_state *pcli = (struct cli_state *)state;
        fstring fname;
index 26d59beda2bf2aea1982d9e2d7e457f83726b77a..e25316818a5cd62b52aae3fd25da1cd86ccc832d 100644 (file)
@@ -99,6 +99,8 @@ int net_help_group(int argc, const char **argv)
        d_printf("\nnet [<method>] group ADD <name> [-C comment] [-c container]"\
                 " [misc. options] [targets]\n\tCreate specified group\n");
        d_printf("\nnet rpc group MEMBERS <name>\n\tList Group Members\n\n");
+       d_printf("\nnet rpc group ADDMEM <group> <member>\n\tAdd Group Members\n\n");
+       d_printf("\nnet rpc group DELMEM <group> <member>\n\tDelete Group Members\n\n");
        net_common_methods_usage(argc, argv);
        net_common_flags_usage(argc, argv);
        d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
index b18d4b0ba5e680930f8c8eeca83dc8ecfeb11be9..1a5e98b34e930a5adf3749850ae62fdcaa3e88af 100644 (file)
@@ -2792,7 +2792,7 @@ typedef struct copy_clistate {
  * @param state        arg-pointer
  *
  **/
-static void copy_fn(file_info *f, const char *mask, void *state)
+static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state)
 {
        NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        struct copy_clistate *local_state = (struct copy_clistate *)state;
@@ -4377,7 +4377,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
        }
 
        /* Create trusting domain's account */
-       acb_info = ACB_DOMTRUST;
+       acb_info = ACB_NORMAL; 
        unknown = 0xe00500b0; /* No idea what this is - a permission mask?
                                 mimir: yes, most probably it is */
 
@@ -4390,20 +4390,34 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
 
        {
                SAM_USERINFO_CTR ctr;
-               SAM_USER_INFO_24 p24;
+               SAM_USER_INFO_23 p23;
+               NTTIME notime;
+               char nostr[] = "";
+               LOGON_HRS hrs;
                uchar pwbuf[516];
 
                encode_pw_buffer((char *)pwbuf, argv[1], STR_UNICODE);
 
                ZERO_STRUCT(ctr);
-               ZERO_STRUCT(p24);
-
-               init_sam_user_info24(&p24, (char *)pwbuf, 24);
-
-               ctr.switch_value = 24;
-               ctr.info.id24 = &p24;
-
-               result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
+               ZERO_STRUCT(p23);
+               ZERO_STRUCT(notime);
+               hrs.max_len = 1260;
+               hrs.offset = 0;
+               hrs.len = 21;
+               memset(hrs.hours, 0xFF, sizeof(hrs.hours));
+               acb_info = ACB_DOMTRUST;
+
+               init_sam_user_info23A(&p23, &notime, &notime, &notime,
+                                     &notime, &notime, &notime,
+                                     nostr, nostr, nostr, nostr, nostr,
+                                     nostr, nostr, nostr, nostr, nostr,
+                                     0, 0, acb_info, ACCT_FLAGS, 168, &hrs, 
+                                     0, 0, (char *)pwbuf);
+               ctr.switch_value = 23;
+               ctr.info.id23 = &p23;
+               p23.passmustchange = 0;
+
+               result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 23,
                                               &cli->user_session_key, &ctr);
 
                if (!NT_STATUS_IS_OK(result)) {
@@ -4438,6 +4452,112 @@ static int rpc_trustdom_add(int argc, const char **argv)
        }
 }
 
+/**
+ * Remove interdomain trust account from the RPC server.
+ * All parameters (except for argc and argv) are passed by run_rpc_command
+ * function.
+ *
+ * @param domain_sid The domain sid acquired from the server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on completion of the function.
+ * @param argc  Standard main() style argc
+ * @param argc  Standard main() style argv.  Initial components are already
+ *              stripped
+ *
+ * @return normal NTSTATUS return code
+ */
+
+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) {
+
+       POLICY_HND connect_pol, domain_pol, user_pol;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       char *acct_name;
+       DOM_SID trust_acct_sid;
+       uint32 *user_rids, num_rids, *name_types;
+       uint32 flags = 0x000003e8; /* Unknown */
+
+       if (argc != 1) {
+               d_printf("Usage: net rpc trustdom del <domain_name>\n");
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* 
+        * Make valid trusting domain account (ie. uppercased and with '$' appended)
+        */
+        
+       if (asprintf(&acct_name, "%s$", argv[0]) < 0) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       strupper_m(acct_name);
+
+       /* Get samr policy handle */
+       result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+                                 &connect_pol);
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+       
+       /* Get domain policy handle */
+       result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+                                     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,
+                                      &acct_name, &num_rids, &user_rids,
+                                      &name_types);
+       
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+                                   MAXIMUM_ALLOWED_ACCESS,
+                                   user_rids[0], &user_pol);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       /* append the rid to the domain sid */
+       sid_copy(&trust_acct_sid, domain_sid);
+       if (!sid_append_rid(&trust_acct_sid, user_rids[0])) {
+               goto done;
+       }
+
+       /* remove the sid */
+
+       result = cli_samr_remove_sid_foreign_domain(cli, mem_ctx, &user_pol,
+                                                   &trust_acct_sid);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       /* Delete user */
+
+       result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       if (!NT_STATUS_IS_OK(result)) {
+         DEBUG(0,("Could not set trust account password: %s\n",
+                  nt_errstr(result)));
+         goto done;
+       }
+
+ done:
+       SAFE_FREE(acct_name);
+       return result;
+}
 
 /**
  * Delete interdomain trust account for a remote domain.
@@ -4447,15 +4567,18 @@ static int rpc_trustdom_add(int argc, const char **argv)
  *
  * @return Integer status (0 means success)
  **/
+
 static int rpc_trustdom_del(int argc, const char **argv)
 {
-       d_printf("Sorry, not yet implemented.\n");
-       d_printf("Use 'smbpasswd -x -i' instead.\n");
-       return -1;
+       if (argc > 0) {
+               return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_del_internals,
+                                      argc, argv);
+       } else {
+               d_printf("Usage: net rpc trustdom del <domain>\n");
+               return -1;
+       }
 }
 
 /**
  * Establish trust relationship to a trusting domain.
  * Interdomain account must already be created on remote PDC.
index feb50b457a8a0f45ca4460bbc081fe7cd609dfe5..32cb6a4650b7499a79c635cf7283d807929de790 100644 (file)
@@ -385,7 +385,7 @@ static int net_help_rights( int argc, const char **argv )
        
        d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
        d_printf("For example\n");
-       d_printf("\n  net rpc grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivlege\n");
+       d_printf("\n  net rpc rights grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivilege\n");
        d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n");